FileDocCategorySizeDatePackage
PlatformManagerImpl.javaAPI DocAzureus 3.0.3.424925Mon Jul 30 20:38:58 BST 2007org.gudy.azureus2.platform.win32

PlatformManagerImpl

public class PlatformManagerImpl extends Object implements org.gudy.azureus2.platform.PlatformManager, AEWin32AccessListener
author
parg

Fields Summary
public static final int
RT_NONE
public static final int
RT_AZ
public static final int
RT_OTHER
public static final String
DLL_NAME
public static final String
NEW_MAIN_ASSOC
public static final String
OLD_MAIN_ASS0C
private static boolean
initialising
private static boolean
init_tried
private static PlatformManagerImpl
singleton
private static AEMonitor
class_mon
private final Set
capabilitySet
private List
listeners
protected AEWin32Access
access
protected String
app_exe_name
protected File
az_exe
protected boolean
az_exe_checked
Constructors Summary
protected PlatformManagerImpl()

		access	= AEWin32Manager.getAccessor( true );
		
		access.addListener( this );
		
		app_exe_name	= SystemProperties.getApplicationName() + ".exe";
		
        initializeCapabilities();
	
Methods Summary
public voidaddListener(org.gudy.azureus2.platform.PlatformManagerListener listener)

    	listeners.add( listener );
    
protected voidapplyPatches()

		try{
			File	exe_loc = getApplicationEXELocation();
			
			String	az_exe_string = exe_loc.toString();
			
			//int	icon_index = getIconIndex();
			
			String	current = 
				access.readStringValue(
					AEWin32Access.HKEY_CLASSES_ROOT,
					NEW_MAIN_ASSOC + "\\DefaultIcon",
					"" );

			//System.out.println( "current = " + current );
			
			String	target = az_exe_string + "," + getIconIndex();
			
			//System.out.println( "target = " + target );
			
				// only patch if Azureus.exe in there
			
			if ( current.indexOf( app_exe_name ) != -1 && !current.equals(target)){
				
				access.writeStringValue( 	
						AEWin32Access.HKEY_CLASSES_ROOT,
						NEW_MAIN_ASSOC + "\\DefaultIcon",
						"",
						target );
			}
		}catch( Throwable e ){
			
			//e.printStackTrace();
		}
		
			// one off fix of permissions in app dir
		
		if ( 	hasCapability( PlatformManagerCapabilities.CopyFilePermissions ) &&
				!COConfigurationManager.getBooleanParameter( "platform.win32.permfixdone2", false )){

			try{
				
				String	str = SystemProperties.getApplicationPath();
				
				if ( str.endsWith(File.separator)){
					
					str = str.substring(0,str.length()-1);
				}
				
				fixPermissions( new File( str ), new File( str ));
				
			}catch( Throwable e ){
				
			}finally{
				
				COConfigurationManager.setParameter( "platform.win32.permfixdone2", true );
			}
		}
	
public voidcopyFilePermissions(java.lang.String from_file_name, java.lang.String to_file_name)

		try{
			access.copyFilePermissions( from_file_name, to_file_name );
			
		}catch( Throwable e ){
			
			throw( new PlatformManagerException( "Failed to copy file permissions", e ));
		}		
	
public voidcreateProcess(java.lang.String command_line, boolean inherit_handles)

		try{
			access.createProcess( command_line, inherit_handles );
			
		}catch( Throwable e ){
			
			throw( new PlatformManagerException( "Failed to create process", e ));
		}	
	
public voiddispose()
Does nothing

    
public voideventOccurred(int type)

		int	t_type;
		
		if ( type == AEWin32AccessListener.ET_SHUTDOWN ){
			
			t_type = PlatformManagerListener.ET_SHUTDOWN;
			
		}else if ( type == AEWin32AccessListener.ET_SUSPEND ){
			
			t_type = PlatformManagerListener.ET_SUSPEND;
				
		}else if ( type == AEWin32AccessListener.ET_RESUME ){
			
			t_type = PlatformManagerListener.ET_RESUME;
				
		}else{
			
			return;
		}
		
		if ( t_type != -1 ){
			
			for (int i=0;i<listeners.size();i++){
				
				try{
					((PlatformManagerListener)listeners.get(i)).eventOccurred( t_type );
					
				}catch( Throwable e ){
					
					Debug.printStackTrace(e);
				}
			}
		}
	
protected voidfixPermissions(java.io.File parent, java.io.File dir)

    	File[]	files = dir.listFiles();
    	
    	if ( files == null ){
    		
    		return;
    	}
    	
    	for (int i=0;i<files.length;i++){
    		
    		File	file = files[i];
    		   	   		
    		if ( file.isFile()){
    			
    			copyFilePermissions( parent.getAbsolutePath(), file.getAbsolutePath());
    		}
    	}
    
public intgetAdditionalFileTypeRegistrationDetails(java.lang.String name, java.lang.String type)


		String	az_exe_str;
		
		try{
			az_exe_str = getApplicationEXELocation().toString();
		
		}catch( Throwable e ){
			
			return( RT_NONE );
		}
		
		try{
			String	test1 = 
				access.readStringValue( 	
					AEWin32Access.HKEY_CLASSES_ROOT,
					name + "\\shell\\open\\command",
					"" );
			
			if ( !test1.equals( "\"" + az_exe_str + "\" \"%1\"" )){
				
				return( test1.length() ==0?RT_NONE:RT_OTHER );
			}
			
				// MRU list is just that, to remove the "always open with" we need to kill
				// the "application" entry, if it exists
			
			try{
				String	always_open_with = 
					access.readStringValue( 
						AEWin32Access.HKEY_CURRENT_USER,
						"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FileExts\\" + type,
						"Application" );
				
				//System.out.println( "mru_list = " + mru_list );

				if ( always_open_with.length() > 0 ){
				
					// AZ is default so if this entry exists it denotes another (non-AZ) app
					
					return( RT_OTHER );
				}
			}catch( Throwable e ){
				
				// e.printStackTrace();
				
				// failure means things are OK
			}
			
			/*
			try{
				String	mru_list = 
					access.readStringValue( 
						AEWin32Access.HKEY_CURRENT_USER,
						"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FileExts\\.torrent\\OpenWithList",
						"MRUList" );
				
				//System.out.println( "mru_list = " + mru_list );

				if ( mru_list.length() > 0 ){
				
					String	mru = 
						access.readStringValue( 
							AEWin32Access.HKEY_CURRENT_USER,
							"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FileExts\\.torrent\\OpenWithList",
							"" + mru_list.charAt(0) );
					
					//System.out.println( "mru = " + mru );
					
					return( mru.equalsIgnoreCase(app_exe_name));
				}
			}catch( Throwable e ){
				
				// e.printStackTrace();
				
				// failure means things are OK
			}
			*/
			
			return( RT_AZ );
			
		}catch( Throwable e ){
			
			if ( 	e.getMessage() == null || 
					e.getMessage().indexOf("RegOpenKey failed") == -1 ){
				
				Debug.printStackTrace( e );
			}

			return( RT_NONE );
		}
	
public java.lang.StringgetApplicationCommandLine()

		try{
			return( getApplicationEXELocation().toString());
			
		}catch( Throwable e ){
			
			return( null );
		}
	
protected java.io.FilegetApplicationEXELocation()

		if ( az_exe == null ){
			
			try{
			
				String az_home;
				
				// Try the app dir first, because we may not be using the one in the registry
				az_home = SystemProperties.getApplicationPath();		
				
				az_exe = new File(az_home + File.separator + app_exe_name).getAbsoluteFile();

				if (!az_exe.exists()) {
					try {
						az_home = access.getApplicationInstallDir(SystemProperties.getApplicationName());

						az_exe = new File(az_home + File.separator + app_exe_name).getAbsoluteFile();

						if (!az_exe.exists()) {

							throw (new PlatformManagerException(app_exe_name
									+ " not found in " + az_home + ", please re-install"));
						}
					} catch (Throwable e) {
					}
				}
								
				if ( !az_exe.exists()){
					
					String	msg = app_exe_name + " not found in " + az_home + " - can't check file associations. Please re-install " + SystemProperties.getApplicationName();
					
					az_exe = null;
					
					if (!az_exe_checked){
					
						Logger.log(new LogAlert(LogAlert.UNREPEATABLE, LogAlert.AT_WARNING,
								msg));
					}
					
					throw( new PlatformManagerException( msg ));
				}
			}finally{
				
				az_exe_checked	= true;
			}
		}
		
		return( az_exe );
	
public java.lang.StringgetAzComputerID()
Gets an ID to identify this computer to azureus. Used when the computer has muliple user accounts and we need a way to not duplicate efforts (An example would be to skip downloading something another user on the computer has already downloaded)

The default for the ID is the AZID of the first user profile.

return
ID

		boolean needWrite = false;
		String cid = null;
		try {
			cid = access.readStringValue(AEWin32Access.HKEY_LOCAL_MACHINE,
					"SOFTWARE\\Azureus", "CID");
		} catch (Exception e) {
		}

		if (cid == null || cid.length() == 0) {
			needWrite = true;
			try {
				File commonPath = new File(access.getCommonAppData(),
						SystemProperties.APPLICATION_NAME);
				if (commonPath.isDirectory()) {
					File fCID = new File(commonPath, "azCID.txt");
					if (fCID.exists()) {
						cid = FileUtil.readFileAsString(fCID, 255, "utf8");
					}
				}
			} catch (Exception e) {
			}
		}

		if (cid == null || cid.length() == 0) {
			needWrite = true;
			cid = COConfigurationManager.getStringParameter("ID");
		}

		if (cid == null || cid.length() == 0) {
			needWrite = true;
			cid = RandomUtils.generateRandomAlphanumerics(20);
		}

		if (needWrite) {
			setAzComputerID(cid);
		}
		return cid;
	
protected intgetIconIndex()

		/*
		File	exe_loc = getAureusEXELocation();
		
		long	size = exe_loc.length();
		
		boolean	old_exe = size < 250000;
		
		return( old_exe?0:1);
		*/
		
		// weird, seems like it should be 0 for old and new
		
		return( 0 );
	
public java.io.FilegetLocation(long location_id)

	    if ( location_id == LOC_USER_DATA ){
	    	
	    	return(new File(getUserDataDirectory()));
	    	
	    }else if ( location_id == LOC_MUSIC ){
	    	
	    	try{
	    		
		    	return(new File(access.getUserMusicDir()));
		    	
	    	}catch( Throwable e ){
	    		
				throw( new PlatformManagerException( "Failed to read registry details", e ));
	    	}
	    } else if (location_id == LOC_DOCUMENTS) {
	    	try{
	    		
		    	return(new File(access.getUserDocumentsDir()));
		    	
	    	}catch( Throwable e ){
	    		
				throw( new PlatformManagerException( "Failed to read registry details", e ));
	    	}
	    } else if (location_id == LOC_VIDEO) {
	    	try{
	    		
		    	return(new File(access.getUserVideoDir()));
		    	
	    	}catch( Throwable e ){
	    		
				throw( new PlatformManagerException( "Failed to read registry details", e ));
	    	}
	    }else{
	    	
	    	return( null );
	    }
	
public intgetPlatformType()

		return( PT_WINDOWS );
	
public static org.gudy.azureus2.platform.win32.PlatformManagerImplgetSingleton()

	
	  
	
	
		 	
	
		try{
			class_mon.enter();
		
			if ( singleton != null ){
				
				return( singleton );
			}
			
			try{	
				if ( initialising ){
					
					System.err.println( "PlatformManager: recursive entry during initialisation" );
				}
				
				initialising	= true;
				
				if ( !init_tried ){
					
					init_tried	= true;
					
					try{
						singleton	= new PlatformManagerImpl();
						
							// gotta separate this so that a recursive call due to config access during
							// patching finds the singleton 
						
						singleton.applyPatches();
						
					}catch( PlatformManagerException e ){
						
						throw( e );
						
					}catch( Throwable e ){
												
						if ( e instanceof PlatformManagerException ){
							
							throw((PlatformManagerException)e);
						}
						
						throw( new PlatformManagerException( "Win32Platform: failed to initialise", e ));
					}
				}
			}finally{
				
				initialising	= false;
			}
			
			return( singleton );
			
		}finally{
			
			class_mon.exit();
		}
	
public java.lang.StringgetUserDataDirectory()

		try{
			return access.getUserAppData() + SystemProperties.SEP
					+ SystemProperties.APPLICATION_NAME + SystemProperties.SEP;
			
		}catch( Throwable e ){
			
			throw( new PlatformManagerException( "Failed to read registry details", e ));
		}		
	
public java.lang.StringgetVersion()

		return( access.getVersion());
	
public booleanhasCapability(org.gudy.azureus2.platform.PlatformManagerCapabilities capability)
{@inheritDoc}

        return capabilitySet.contains(capability);
    
private voidinitializeCapabilities()

    	if ( access.isEnabled()){
    		
	        capabilitySet.add(PlatformManagerCapabilities.CreateCommandLineProcess);
	        capabilitySet.add(PlatformManagerCapabilities.GetUserDataDirectory);
	        capabilitySet.add(PlatformManagerCapabilities.RecoverableFileDelete);
	        capabilitySet.add(PlatformManagerCapabilities.RegisterFileAssociations);
	        capabilitySet.add(PlatformManagerCapabilities.ShowFileInBrowser);
	        capabilitySet.add(PlatformManagerCapabilities.GetVersion);
	        capabilitySet.add(PlatformManagerCapabilities.SetTCPTOSEnabled);
	        capabilitySet.add(PlatformManagerCapabilities.ComputerIDAvailability);
	        
	        
	        if ( Constants.compareVersions( access.getVersion(), "1.11" ) >= 0 &&
	        		!Constants.isWindows9598ME ){
	        	
	            capabilitySet.add(PlatformManagerCapabilities.CopyFilePermissions);
	            
	        }
	        
	        if ( Constants.compareVersions( access.getVersion(), "1.12" ) >= 0 ){
	        	
	            capabilitySet.add(PlatformManagerCapabilities.TestNativeAvailability);
	        }
	        
	        if ( Constants.compareVersions( access.getVersion(), "1.2" ) >= 0 ){
	        	
	            capabilitySet.add(PlatformManagerCapabilities.TraceRouteAvailability);
	            capabilitySet.add(PlatformManagerCapabilities.PingAvailability);
	        }

    	}else{
    		
    			// disabled -> only available capability is that to get the version
    			// therefore allowing upgrade
    		
	        capabilitySet.add(PlatformManagerCapabilities.GetVersion);
    	}
    
public booleanisAdditionalFileTypeRegistered(java.lang.String name, java.lang.String type)

		return( getAdditionalFileTypeRegistrationDetails( name, type ) == RT_AZ );
	
public booleanisApplicationRegistered()

			// all this stuff needs the exe location so bail out early if unavailable
		
		getApplicationEXELocation();
		
		try{
				// always trigger magnet reg here if not owned so old users get it...
			
			if ( getAdditionalFileTypeRegistrationDetails( "Magnet", ".magnet" ) == RT_NONE ){
		
				registerMagnet();
			}
		}catch( Throwable e ){
			
			Debug.printStackTrace(e);
		}
		
		if ( isAdditionalFileTypeRegistered( OLD_MAIN_ASS0C, ".torrent" )){
			
			unregisterAdditionalFileType( OLD_MAIN_ASS0C, ".torrent" );
			
			registerAdditionalFileType( NEW_MAIN_ASSOC, "Azureus Download", ".torrent", "application/x-bittorrent" );
		}
		
		boolean	reg = isAdditionalFileTypeRegistered( NEW_MAIN_ASSOC, ".torrent" );
		
			// one off auto registration on new install
		
		if ( !reg && !COConfigurationManager.getBooleanParameter( "platform.win32.autoregdone", false )){
			
			registerAdditionalFileType( NEW_MAIN_ASSOC, "Azureus Download", ".torrent", "application/x-bittorrent" );

			COConfigurationManager.setParameter( "platform.win32.autoregdone", true );
			
			reg	= true;
		}
		
		return( reg );
	
public static voidmain(java.lang.String[] args)

		try {
			PlatformManagerImpl impl = new PlatformManagerImpl();
			System.out.println(impl.getAzComputerID());
		} catch (PlatformManagerException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	
public voidperformRecoverableFileDelete(java.lang.String file_name)

		try{
			access.moveToRecycleBin( file_name );
			
		}catch( Throwable e ){
			
			throw( new PlatformManagerException( "Failed to move file", e ));
		}
	
public voidping(java.net.InetAddress interface_address, java.net.InetAddress target, org.gudy.azureus2.platform.PlatformManagerPingCallback callback)

		if ( !hasCapability( PlatformManagerCapabilities.PingAvailability )){
			
			throw new PlatformManagerException("Unsupported capability called on platform manager");
		}
		
		try{
			access.ping( interface_address, target, callback );
			
		}catch( Throwable e ){
			
			throw( new PlatformManagerException( "Failed to trace route", e ));
		}	
	
public voidregisterAdditionalFileType(java.lang.String name, java.lang.String description, java.lang.String type, java.lang.String content_type)

		registerAdditionalFileType( name, description, type, content_type, false );
	
public voidregisterAdditionalFileType(java.lang.String name, java.lang.String description, java.lang.String type, java.lang.String content_type, boolean url_protocol)

		// 	WriteRegStr HKCR ".torrent" "" "Azureus"
		// 	WriteRegStr HKCR "Azureus" "" "Azureus Torrent"
		// 	WriteRegStr HKCR "Azureus\shell" "" "open"
		// 	WriteRegStr HKCR "Azureus\DefaultIcon" "" $INSTDIR\Azureus.exe,1
		// 	WriteRegStr HKCR "Azureus\shell\open\command" "" '"$INSTDIR\Azureus.exe" "%1"'
		// 	WriteRegStr HKCR "Azureus\Content Type" "" "application/x-bittorrent"
		

		try{
			String	az_exe_string	= getApplicationEXELocation().toString();
			
			unregisterAdditionalFileType( name, type );

			access.writeStringValue( 	
					AEWin32Access.HKEY_CLASSES_ROOT,
					type,
					"",
					name );
		
			access.writeStringValue( 	
					AEWin32Access.HKEY_CLASSES_ROOT,
					name,
					"",
					description );
			
			access.writeStringValue( 	
					AEWin32Access.HKEY_CLASSES_ROOT,
					name + "\\shell",
					"",
					"open" );
			
			access.writeStringValue( 	
					AEWin32Access.HKEY_CLASSES_ROOT,
					name + "\\DefaultIcon",
					"",
					az_exe_string + "," + getIconIndex());
			
			access.writeStringValue( 	
					AEWin32Access.HKEY_CLASSES_ROOT,
					name + "\\shell\\open\\command",
					"",
					"\"" + az_exe_string + "\" \"%1\"" );
					
			access.writeStringValue( 	
					AEWin32Access.HKEY_CLASSES_ROOT,
					name + "\\Content Type" ,
					"",
					content_type );
			
			if ( url_protocol ){
				
				access.writeStringValue( 	
						AEWin32Access.HKEY_CLASSES_ROOT,
						name,
						"URL Protocol",
						"" );
			}
			
		}catch( PlatformManagerException e ){
			
			throw(e );
			
		}catch( Throwable e ){
			
			throw( new PlatformManagerException( "Failed to write registry details", e ));
		}
	
public voidregisterApplication()

		registerMagnet();
		
		registerAdditionalFileType( NEW_MAIN_ASSOC, "Azureus Download", ".torrent", "application/x-bittorrent" );
	
protected voidregisterMagnet()

		try{
			registerAdditionalFileType( 
				"Magnet", 
				"Magnet URI", 
				".magnet", 
				"application/x-magnet",
				true );
			
		}catch( Throwable e ){
			
			Debug.printStackTrace(e);
		}
	
public voidremoveListener(org.gudy.azureus2.platform.PlatformManagerListener listener)

    	listeners.remove( listener );
    
private voidsetAzComputerID(java.lang.String cid)

param
cid

		try {
			access.writeStringValue(AEWin32Access.HKEY_LOCAL_MACHINE,
					"SOFTWARE\\Azureus", "CID", cid);
		} catch (Exception e) {
			Debug.out("Could not write CID: " + e.getMessage());
		}

		try {
			String sCommonAppData = access.getCommonAppData();
			if (sCommonAppData != null && sCommonAppData.length() > 0) {
				File commonPath = new File(sCommonAppData);
				if (commonPath.isDirectory()) {
					commonPath = new File(commonPath, SystemProperties.APPLICATION_NAME);
					FileUtil.mkdirs(commonPath);

					File fCID = new File(commonPath, "azCID.txt");
					FileUtil.writeBytesAsFile(fCID.getAbsolutePath(),
							cid.getBytes("utf8"));
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	
public voidsetTCPTOSEnabled(boolean enabled)

		try{
			access.writeWordValue( 	
					AEWin32Access.HKEY_LOCAL_MACHINE,
					"System\\CurrentControlSet\\Services\\Tcpip\\Parameters",
					"DisableUserTOSSetting",
					enabled?0:1);
			
		}catch( Throwable e ){
			
			throw( new PlatformManagerException( "Failed to write registry details", e ));
		}		
	
public intshellExecute(java.lang.String operation, java.lang.String file, java.lang.String parameters, java.lang.String directory, int SW_const)

		try {
			return access.shellExecute(operation, file, parameters, directory, SW_const);
		} catch (Throwable e) {
			throw( new PlatformManagerException( "Failed to shellExecute", e ));
		}
	
public voidshowFile(java.lang.String file_name)
{@inheritDoc}

        try
        {
        	File file = new File(file_name);
        	Runtime.getRuntime().exec(
        			new String[] { "explorer.exe",
        					file.isDirectory() ? "/e," : "/e,/select,",
        							"\"" + file_name + "\"" });
        }
        catch (IOException e)
        {
            throw new PlatformManagerException("Failed to show file " + file_name, e);
        }
    
public booleantestNativeAvailability(java.lang.String name)

		if ( !hasCapability( PlatformManagerCapabilities.TestNativeAvailability )){
			
			throw new PlatformManagerException("Unsupported capability called on platform manager");
		}
		
		try{
			return( access.testNativeAvailability( name ));
			
		}catch( Throwable e ){
			
			throw( new PlatformManagerException( "Failed to test availability", e ));
		}
	
public voidtraceRoute(java.net.InetAddress interface_address, java.net.InetAddress target, org.gudy.azureus2.platform.PlatformManagerPingCallback callback)

		if ( !hasCapability( PlatformManagerCapabilities.TraceRouteAvailability )){
			
			throw new PlatformManagerException("Unsupported capability called on platform manager");
		}
		
		try{
			access.traceRoute( interface_address, target, callback );
			
		}catch( Throwable e ){
			
			throw( new PlatformManagerException( "Failed to trace route", e ));
		}	
	
public voidunregisterAdditionalFileType(java.lang.String name, java.lang.String type)

		try{
			try{
		
				access.deleteValue( 	
					AEWin32Access.HKEY_CURRENT_USER,
					"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FileExts\\" + type,
					"Application" );
				
			}catch( Throwable e ){
				
				// e.printStackTrace();
			}
			
			try{
				access.deleteKey( 	
					AEWin32Access.HKEY_CLASSES_ROOT,
					type );
				
			}catch( Throwable e ){
				
				// Debug.printStackTrace( e );
			}
			
			try{
				access.deleteKey( 	
					AEWin32Access.HKEY_CLASSES_ROOT,
					name,
					true );
				
			}catch( Throwable e ){
				
				// Debug.printStackTrace( e );
			}
			
		}catch( Throwable e ){
			
			throw( new PlatformManagerException( "Failed to delete registry details", e ));
		}