Beispiel #1
0
int NeedUpdate()
{
	ERROR_OUTPUT(__func__);

		if (!FileExists(UPDATEXML))
		{
			ERROR_OUTPUT("UPDATE_XML");
			return UPDATE_XML;
		}
		else
		{
			if (!CheckInstall())
			{
				ERROR_OUTPUT("UPDATE_FILES");
				return UPDATE_FILES;
			}
			
			if (FileExists(UPDATEFILE) && CheckUpdate(UPDATEFILE))
			{
				ERROR_OUTPUT("UPDATE_MCF");
				return UPDATE_MCF;
			}
		}

	return UPDATE_NONE;
}
int NeedUpdateNonGpl()
{
	std::wstring path = UTIL::OS::getAppDataPath(UPDATEFILE_W);

	if (!FileExists(UPDATEXML_W))
	{
		return UPDATE_XML;
	}
	else
	{
		if (FileExists(path.c_str()) && CheckUpdate(path.c_str()))
			return UPDATE_MCF;

		if (!CheckInstall())
			return UPDATE_FILES;
	}

	if (CheckCert())
		return UPDATE_CERT;

	return UPDATE_NONE;
}
int NeedUpdateNonGpl()
{
	UpdateLogHandle ulh;

	std::wstring path = UTIL::OS::getAppDataPath(UPDATEFILE_W);

	if (!FileExists(UPDATEXML_W))
	{
		Log("NeedUpdate: Missing Xml");
		return UPDATE_XML;
	}
	else
	{
		if (FileExists(path.c_str()) && CheckUpdate(path.c_str()))
		{
			Log("NeedUpdate: Missing Mcf");
			return UPDATE_MCF;
		}

		if (!CheckInstall())
		{
			Log("NeedUpdate: Bad Files");
			return UPDATE_FILES;
		}
	}

#ifdef WITH_CODESIGN
	if (CheckCert())
	{
		Log("NeedUpdate: Bad Cert");
		return UPDATE_CERT;
	}
#endif

	return UPDATE_NONE;
}
int PrepOscillations( DexApparatus *apparatus, const char *params ) {

	int status = 0;
	char *target_filename = 0;
	char *mtb, *dsc;
	
	int	direction = ParseForDirection( apparatus, params );
	int eyes = ParseForEyeState( params );
	DexSubjectPosture posture = ParseForPosture( params );
	DexTargetBarConfiguration bar_position;

	if ( direction == VERTICAL ) bar_position = TargetBarRight;
	else bar_position = TargetBarLeft;

	// Prompt the subject to put the target bar in the correct position.
	if ( bar_position == TargetBarRight ) {
		status = apparatus->fWaitSubjectReady( ( posture == PostureSeated ? "TappingFolded.bmp" : "TappingFolded.bmp" ), 
			PlaceTargetBarRightFolded, OkToContinue );
	}
	else {
		status = apparatus->fWaitSubjectReady( ( posture == PostureSeated ? "BarLeft.bmp" : "BarLeft.bmp" ), 
			"Place the target bar in the left position.%s", OkToContinue );
	}
	if ( status == ABORT_EXIT ) exit( status );


	// Verify that the apparatus is in the correct configuration, and if not, 
	//  give instructions to the subject about what to do.
	status = CheckInstall( apparatus, posture, bar_position );
	if ( status != NORMAL_EXIT ) return( status );

	// Instruct the subject on the task to be done.
	
	// Show them the targets that will be used.
	apparatus->TargetsOff();
	if ( direction == VERTICAL ) {
		apparatus->VerticalTargetOn( oscillationTargets[UPPER] );
		apparatus->VerticalTargetOn( oscillationTargets[LOWER] );
	}
	else {
		apparatus->HorizontalTargetOn( oscillationTargets[UPPER] );
		apparatus->HorizontalTargetOn( oscillationTargets[LOWER] );
	}

	// Describe how to do the task, according to the desired conditions.
	AddDirective( apparatus, InstructPickUpManipulandum, "InHand.bmp" );
	if ( direction == VERTICAL ) {
		mtb = "MvToBlkV.bmp";
		dsc = "OscillateV.bmp";
	}
	else {
		mtb = "MvToBlkH.bmp";
		dsc = "OscillateH.bmp";
	}

	if ( eyes == OPEN )	{
		AddDirective( apparatus, "You will hold the manipulandum upright and to the right of the blinking Target LED.", mtb );
		AddDirective( apparatus, "You will then oscillate between the lit targets, one full cycle per beep.", dsc );
		// Need to change pictures to remove beeps.
		AddDirective( apparatus, "When the beeps will stop, you should continue the oscillations.", dsc );
	}
		// If we delete oscillation in discrete, then we don't need this condition here below any more.
	else {
		AddDirective( apparatus, "You will hold the manipulandum upright and to the right of the blinking Target LED.", mtb );
		AddDirective( apparatus, "You will then CLOSE your eyes and oscillate between the targets, one full cycle per beep.", dsc );
		AddDirective( apparatus, "When the beeps stop, you should continue the oscillations, keeping your eyes CLOSED.", dsc );
	}

	ShowDirectives( apparatus );

	return( NORMAL_EXIT );
}
int RunOscillations( DexApparatus *apparatus, const char *params ) {
	
	int status = 0;
	
	// These are static so that if the params string does not specify a value,
	//  whatever was used the previous call will be used again.
	static int	direction = VERTICAL;
	static int	eyes = OPEN;
	static double frequency = 1.0;

	static DexMass mass = MassMedium;
	static DexTargetBarConfiguration bar_position = TargetBarRight;
	static DexSubjectPosture posture = PostureSeated;
	static Quaternion desired_orientation = {0.0, 0.0, 0.0, 1.0};

	char *target_filename = 0;
	char *delay_filename = 0;

	fprintf( stderr, "     RunOscillations: %s\n", params );

	// How quickly should it oscillate?
	frequency = ParseForFrequency( apparatus, params );
	oscillationPeriod = 1.0 / frequency;
	oscillationDuration = ParseForDuration( apparatus, params );

	// Seated or supine?
	posture = ParseForPosture( params );

	// Which mass should be used for this set of trials?
	mass = ParseForMass( params );

	// Eyes open or closed?
	eyes = ParseForEyeState( params );

	// Horizontal or vertical movements?
	direction = ParseForDirection( apparatus, params );
	if ( direction == VERTICAL ) {
		bar_position = TargetBarRight;
		apparatus->CopyVector( oscillationDirection, apparatus->jVector );
	}
	else {
		bar_position = TargetBarLeft;
		apparatus->CopyVector( oscillationDirection, apparatus->kVector );
	}

	double cop_tolerance = copTolerance;
	if ( ParseForNoCheck( params) ) cop_tolerance = 1000.0;

	// Construct the results filename tag.
	char tag[32];
	if ( ParseForTag( params ) ) strcpy( tag, ParseForTag( params ) );
	else {
		strcpy( tag, "Grip" );
		strcat( tag, "O" ); // O for Oscillations.
		if ( posture == PostureSeated ) strcat( tag, "U" ); // U is for upright (seated).
		else strcat( tag, "S" ); // S is for supine.
		if ( direction == VERTICAL ) strcat( tag, "V" );
		else strcat( tag, "H" );
		if ( mass == MassSmall ) strcat( tag, "4" );
		else if ( mass == MassMedium ) strcat( tag, "6" );
		else if ( mass == MassLarge ) strcat( tag, "8" );
		else strcat( tag, "u" ); // for 'unspecified'
	}

	// What are the limits of each oscillatory movement?
	if ( target_filename = ParseForRangeFile( params ) ) LoadTargetRange( oscillationTargets, target_filename );

	// If told to do so in the command line, give the subject explicit instructions to prepare the task.
	// If this is the first block, we should do this. If not, it can be skipped.
	if ( ParseForPrep( params ) ) status = PrepOscillations( apparatus, params );
	// Verify that the apparatus is in the correct configuration, and if not, 
	//  give instructions to the subject about what to do.
	else status = CheckInstall( apparatus, posture, bar_position );
	if ( status != NORMAL_EXIT ) return( status );


	// Verify that the subject is ready, in case they did something unexpected.
	if ( posture == PostureSeated ) {
		status = apparatus->fWaitSubjectReady( "BeltsSeated.bmp", MsgQueryReadySeated, OkToContinue );
	}
	else if ( posture == PostureSupine ) {
		status = apparatus->fWaitSubjectReady( "BeltsSupine.bmp", MsgQueryReadySupine, OkToContinue );
	}
	if ( status == ABORT_EXIT ) exit( status );

	// Indicate to the subject that we are ready to start and wait for their go signal.
	status = apparatus->WaitSubjectReady( "HandsOffCradle.bmp", MsgReadyToStart );
	if ( status == ABORT_EXIT ) exit( status );

	status = apparatus->SelfTest();
	if ( status != NORMAL_EXIT ) return( status );

	// Start acquisition and acquire a baseline.
	// Presumably the manipulandum is not in the hand. 
	// It should have been left either in a cradle or the retainer at the end of the last action.
	apparatus->SignalEvent( "Initiating set of oscillation movements." );
	apparatus->StartFilming( tag, defaultCameraFrameRate );
	apparatus->StartAcquisition( tag, maxTrialDuration );
	apparatus->ShowStatus( MsgAcquiringBaseline, "wait.bmp" );
	apparatus->Wait( baselineDuration );

	// Instruct subject to take the specified mass.
	//  and wait for confimation that he or she is ready.
	status = apparatus->SelectAndCheckMass( mass );
	if ( status == ABORT_EXIT ) exit( status );

	// Check that the grip is properly centered.
	apparatus->ShowStatus( MsgCheckGripCentered, "working.bmp" );
	status = apparatus->WaitCenteredGrip( cop_tolerance, copForceThreshold, copWaitTime, MsgGripNotCentered, "alert.bmp" );
	if ( status == ABORT_EXIT ) exit( status );

	// Now wait until the subject gets to the target before moving on.
	apparatus->ShowStatus( MsgMoveToBlinkingTarget, "working.bmp" );
	apparatus->TargetsOff();
	if ( direction == VERTICAL ) status = apparatus->WaitUntilAtVerticalTarget( oscillationTargets[MIDDLE] , desired_orientation, defaultPositionTolerance, defaultOrientationTolerance, waitHoldPeriod, waitTimeLimit, MsgTooLongToReachTarget, "MvToBlkVA.bmp"  );
	else status = apparatus->WaitUntilAtHorizontalTarget( oscillationTargets[MIDDLE], desired_orientation, defaultPositionTolerance, defaultOrientationTolerance, waitHoldPeriod, waitTimeLimit, MsgTooLongToReachTarget, "MvToBlkHA.bmp"  ); 
	if ( status == IDABORT ) exit( ABORT_EXIT );
	
	// Double check that the subject has the specified mass.
	// If the correct mass is already on the manipulandum and out of the cradle, 
	//  this will move right on to the next step.
	status = apparatus->SelectAndCheckMass( mass );
	if ( status == ABORT_EXIT ) exit( status );

	// Collect one second of data while holding at the starting position.
	apparatus->Wait( baselineDuration );
	
	// Indicate what to do next.
	apparatus->ShowStatus( "Start oscillating movements.\nOne cycle per beep.", "working.bmp" );

	// Show the limits of the oscillation movement by lighting 2 targets.
	apparatus->TargetsOff();
	if ( direction == VERTICAL ) {
		apparatus->VerticalTargetOn( oscillationTargets[LOWER] );
		apparatus->VerticalTargetOn( oscillationTargets[UPPER] );
	}
	else {
		apparatus->HorizontalTargetOn( oscillationTargets[LOWER] );
		apparatus->HorizontalTargetOn( oscillationTargets[UPPER] );
	}

	
	
#ifndef SILENT_ONLY
	// Mark the starting point in the recording where post hoc tests should be applied.
	// In this version we analyze the entire movement, with and without beeps.
	apparatus->MarkEvent( BEGIN_ANALYSIS );
#endif

	// Output a sound pattern to establish the oscillation frequency.
	// This will play for the first part of each trial trial.
	double time;
	for ( time = 0.0; time < oscillationEntrainDuration; time += oscillationPeriod ) {
		int tone = 3.9; //floor( 3.9 * ( sin( time * 2.0 * PI ) + 1.0 ) );
		apparatus->SetSoundState( tone, 1 );
		apparatus->Wait( oscillationPeriod / 2.0 - 0.01 );
		apparatus->SetSoundState( tone, 0 );
        apparatus->Wait( oscillationPeriod / 2.0 - 0.01 );
	}
	apparatus->MarkEvent( END_ENTRAIN );
	apparatus->SetSoundState( 4, 0 );

#ifdef BEEPS_ONLY
	// Mark the ending point in the recording where post hoc tests should be applied.
	// Here we do the analysis only on the part of the recorded movement that occurs 
	//  when the beeps were occuring.
	apparatus->MarkEvent( END_ANALYSIS );
#endif

#ifdef SILENT_ONLY
	// Mark the starting point in the recording where post hoc tests should be applied.
	// We do the analysis only on the part of the recorded movement that occurs after
	//  the beeps stops in order to detect if the subject mistakenly stopped as well.
	apparatus->MarkEvent( BEGIN_ANALYSIS );
#endif

	// Now finish out the trial
	apparatus->ShowStatus( "Continue oscillating movements.\nMaintain the same rhythm.", "working.bmp" );
	apparatus->Wait( oscillationDuration - oscillationEntrainDuration );
	  
#ifndef BEEPS_ONLY
	// Mark the ending point in the recording where post hoc tests should be applied.
	// This is the end if we choose either the entire movement or the silent part only.
	apparatus->MarkEvent( END_ANALYSIS );
#endif

	// Collect one final bit of data.
	apparatus->Wait( baselineDuration );

	// We're done.
	apparatus->TargetsOff();

	// Indicate to the subject that they are done and that they can set down the maniplulandum.
	SignalEndOfRecording( apparatus );
	status = apparatus->WaitSubjectReady( "PlaceMass.bmp", MsgTrialOver );
	if ( status == ABORT_EXIT ) exit( status );
	
	// Take a couple of seconds of extra data with the manipulandum in the cradle so we get another zero measurement.
	apparatus->ShowStatus( MsgAcquiringBaseline, "wait.bmp" );
	apparatus->Wait( baselineDuration );

	// Stop acquiring.
	apparatus->ShowStatus( "Saving data ...", "wait.bmp" );
	apparatus->SignalEvent( "Acquisition completed." );
	apparatus->StopFilming();
	apparatus->StopAcquisition( "Error during saving." );

	if ( !ParseForNoCheck( params ) ) {

		// Check the quality of the data.
		// Note that for the oscillations protocol we perform the post-hoc test only on the
		//  part of the recorded movement after the beep stops (see above). This is to 
		//  detect whether the subject mistakenly stops moving when the beeps stop.
		//  This should be taken into account when defining the test criteria below.

		// Was the manipulandum obscured?
		apparatus->ShowStatus( "Checking visibility ...", "wait.bmp" );
		status = apparatus->CheckVisibility( cumulativeDropoutTimeLimit, continuousDropoutTimeLimit, "Manipulandum occluded too often. Press <Retry> to repeat (once or twice) or call COL-CC.", "alert.bmp" );
		if ( status == ABORT_EXIT || status == RETRY_EXIT ) return( status );

		// Check that we got a reasonable amount of movement.
		apparatus->ShowStatus( "Checking for movement ...", "wait.bmp" );
		status = apparatus->CheckMovementAmplitude( oscillationMinMovementExtent, oscillationMaxMovementExtent, oscillationDirection, "Movement amplitude out of range. Press <Retry> to repeat (once or twice) or call COL-CC.", "alert.bmp" );
		if ( status == ABORT_EXIT || status == RETRY_EXIT ) return( status );

		// Check that we got a reasonable number of oscillations.
		// Here I have set it to +/- 20% of the ideal number.
		apparatus->ShowStatus( "Checking number of Oscillations ...", "wait.bmp" );

		// By default we compute a percentage of the number of oscillations over the entire movement.
		oscillationMinCycles = 0.6 * ( oscillationDuration ) * frequency;
		oscillationMaxCycles = 1.5 * ( oscillationDuration ) * frequency;	
#ifdef SILENT_ONLY
		// Adjust the calculation if we are checking only in the silent part.
		oscillationMinCycles = 0.6 * ( oscillationDuration - oscillationEntrainDuration ) * frequency;
		oscillationMaxCycles = 1.5 * ( oscillationDuration - oscillationEntrainDuration ) * frequency;
#endif
#ifdef BEEPS_ONLY
		// Adjust the calculation if we are checking only in the part with beeps.
		oscillationMinCycles = 0.6 * ( oscillationEntrainDuration ) * frequency;
		oscillationMaxCycles = 1.5 * ( oscillationEntrainDuration ) * frequency;
#endif
		// Here is what was used in the first official flight release.
		// The range was too large to catch a subject that did a half cycle per beep.
		// Widened range on oscillations so as not to constrain the subject.
		// oscillationMinCycles = 3;
		// oscillationMaxCycles = 50;
		status = apparatus->CheckMovementCycles( oscillationMinCycles, oscillationMaxCycles, oscillationDirection, oscillationCycleHysteresis, "Number of oscillations out of range. Press <Retry> to repeat (once or twice) or call COL-CC.", "alert.bmp" );
		if ( status == ABORT_EXIT || status == RETRY_EXIT ) return( status );

		apparatus->ShowStatus(  "Analysis completed.", "ok.bmp" );
	}

	return( NORMAL_EXIT );
	
}
Beispiel #6
0
bool BootLoader::preLaunchCheck(UTIL::MISC::CMDArgs &args)
{
#ifdef DESURA_OFFICIAL_BUILD
	CheckForBadUninstaller();
#endif

	if (args.hasArg("urllink"))
	{
		std::string a(m_lpCmdLine);

		size_t pos = a.find("-urllink");
		a.replace(pos, 8, "");

		BootLoaderUtil::Restart(a.c_str(), false);
		return false;
	}

#ifdef DESURA_OFFICIAL_BUILD
	if (args.hasArg("testinstall"))
	{
		m_bRetCode = true;
		m_iRetCode = InstallFilesForTest();
		return false;
	}

	if (args.hasArg("testdownload"))
	{
		m_bRetCode = true;
		m_iRetCode = DownloadFilesForTest();
		return false;
	}
#endif

	if (args.hasArg("dumplevel"))
	{
		SetDumpLevel(args.getInt("dumplevel"));
		g_bLockDump = true;
	}

	if (args.hasArg("autostart"))
	{
		//need to wait for service to start
		Sleep(15 * 1000);
		BootLoaderUtil::RestartAsNormal("-wait");
		return false;
	}

#ifdef DESURA_OFFICIAL_BUILD
#ifdef DEBUG
	if (args.hasArg("debugupdater"))
	{
		INT_PTR nResponse = DisplayUpdateWindow(-1);
		return false;
	}

	if (args.hasArg("debuginstall"))
	{
		McfUpdate();
		return false;
	}

	if (args.hasArg("debugdownload"))
	{
		FullUpdate();
		return false;
	}

	if (args.hasArg("debugcheck"))
	{
		CheckInstall();
		return false;
	}
#endif
#endif

	if (args.hasArg("testcrash"))
	{
		BootLoader *ai = nullptr;
		//ai->gcAssertValid();
	}

	unsigned int osid = BootLoaderUtil::GetOSId();

	if (osid == WINDOWS_PRE2000)
	{
		::MessageBox(nullptr, PRODUCT_NAME " needs Windows XP or better to run.", PRODUCT_NAME " Error: Old Windows", MB_OK);
		return false;
	}
	else if (osid == WINDOWS_XP || osid == WINDOWS_XP64)
	{
		m_bHasAdminRights = true;
	}

	if (args.hasArg("admin"))
	{
		m_bHasAdminRights = true;
	}

	//if the wait command is parsed in then we need to wait for all other instances of desura to exit.
	if (args.hasArg("wait"))
	{
		BootLoaderUtil::WaitForOtherInstance(m_hInstance);
	}
	else
	{
		if (BootLoaderUtil::CheckForOtherInstances(m_hInstance))
		{
			sendArgs();
			return false;
		}
		else
		{
			//if windows uninstall software launches desura it will disable its window till it quits.
			//Work around for existing clients
			std::string a(m_lpCmdLine);
			size_t pos = a.find("desura://uninstall/");

			if (pos != std::string::npos)
			{
				a.replace(pos + 9, 9, "remove");
				BootLoaderUtil::RestartAsNormal(a.c_str());
				return false;
			}
		}
	}

#ifdef DESURA_OFFICIAL_BUILD
	if (args.hasArg("forceupdate"))
	{
		if (!m_bHasAdminRights)
		{
			restartAsAdmin(UPDATE_FORCED);
			return false;
		}
		else
		{
			FullUpdate();
			BootLoaderUtil::RestartAsNormal("-wait");
			return false;
		}
	}
#endif


#ifdef _DEBUG
	SetRegValues();
	InstallService();
#else
	int nu = NeedUpdate();

	if (nu != UPDATE_NONE)
	{
		if (nu == UPDATE_MCF)
		{
			Log("Updating from MCF.\n");
			McfUpdate();
			BootLoaderUtil::RestartAsNormal("-wait");
			return false;
		}
		else if (nu == UPDATE_SERVICE_PATH)
		{
			Log("Service update path [%s].\n", g_UpdateReasons[nu]);

			if (ServiceUpdate(true))
				nu = UPDATE_NONE;
		}
	}

	if (nu != UPDATE_NONE)
	{
		if (!m_bHasAdminRights)
		{
			restartAsAdmin(nu);
			return false;
		}
		else if (nu == UPDATE_SERVICE_LOCATION || nu == UPDATE_SERVICE_HASH)
		{
			Log("Service update location [%s].\n", g_UpdateReasons[nu]);
			ServiceUpdate(false);
		}
		else if (nu == UPDATE_SERVICE_DISABLED)
		{
			if (FixServiceDisabled())
				BootLoaderUtil::RestartAsNormal("-wait");

			return false;
		}
		else
		{
			Log("Full update [%s].\n", g_UpdateReasons[nu]);
			FullUpdate();
			BootLoaderUtil::RestartAsNormal("-wait");
			return false;
		}
	}

	if (m_bHasAdminRights && !(osid == WINDOWS_XP || osid == WINDOWS_XP64))
	{
		BootLoaderUtil::RestartAsNormal("-wait");
		return false;
	}
#endif

	return true;
}
Beispiel #7
0
BOOL BootLoader::InitInstance()
{
	BootLoaderUtil::CMDArgs args(m_lpCmdLine);
	
	if (args.hasArg("waitfordebugger"))
		BootLoaderUtil::WaitForDebugger();

	BootLoaderUtil::SetCurrentDir();
	CWinApp::InitInstance();

#ifdef DESURA_NONGPL_BUILD
	CheckForBadUninstaller();
#endif

	if (args.hasArg("urllink"))
	{
		std::string a(m_lpCmdLine);

		size_t pos = a.find("-urllink");
		a.replace(pos, 8, "");

		BootLoaderUtil::Restart(a.c_str(), false);
		return FALSE;
	}

#ifdef DESURA_NONGPL_BUILD
	if (args.hasArg("testinstall"))
	{
		m_bRetCode = true;
		m_iRetCode = InstallFilesForTest();
		return FALSE;
	}

	if (args.hasArg("testdownload"))
	{
		m_bRetCode = true;
		m_iRetCode = DownloadFilesForTest();
		return FALSE;
	}
#endif
	
	if (args.hasArg("dumplevel"))
	{
		SetDumpLevel(args.getInt("dumplevel"));
		g_bLockDump = true;
	}

	if (args.hasArg("autostart"))
	{
		//need to wait for service to start
		Sleep(15*1000);
		BootLoaderUtil::RestartAsNormal("-wait");
		return FALSE;
	}

#ifdef DESURA_NONGPL_BUILD
#ifdef DEBUG
	if (args.hasArg("debugupdater"))
	{
		INT_PTR nResponse = DisplayUpdateWindow(-1);
		return FALSE;
	}

	if (args.hasArg("debuginstall"))
	{
		McfUpdate();
		return FALSE;
	}

	if (args.hasArg("debugdownload"))
	{
		FullUpdate();
		return FALSE;
	}

	if (args.hasArg("debugcheck"))
	{
		CheckInstall();
		return FALSE;
	}
#endif
#endif

	if (args.hasArg("testcrash"))
	{
		BootLoader *ai = NULL;
		ai->AssertValid();
	}

	unsigned int osid = BootLoaderUtil::GetOSId();

	if (osid == WINDOWS_PRE2000)
	{
		::MessageBox(NULL, "Desura needs Windows xp or better to run.", "Desura Error: Old Windows", MB_OK);
		return FALSE;
	}
	else if (osid == WINDOWS_XP || osid == WINDOWS_XP64)
	{
		hasAdminRights = true;
	}

	if (args.hasArg("admin"))
	{
		hasAdminRights = true;
	}

	//if the wait command is parsed in then we need to wait for all other instances of desura to exit.
	if (args.hasArg("wait"))
	{
		BootLoaderUtil::WaitForOtherInstance(m_hInstance);
	}
	else
	{
		if (BootLoaderUtil::CheckForOtherInstances(m_hInstance))
		{
			sendArgs();
			return FALSE;
		}
		else
		{
			//if windows uninstall software launches desura it will disable its window till it quits.
			//Work around for existing clients
			std::string a(m_lpCmdLine);
			size_t pos = a.find("desura://uninstall/");

			if (pos != std::string::npos)
			{
				a.replace(pos+9, 9, "remove");
				BootLoaderUtil::RestartAsNormal(a.c_str());
				return FALSE;
			}
		}
	}

#ifdef DESURA_NONGPL_BUILD
	if (args.hasArg("forceupdate"))
	{
		if (!hasAdminRights)
		{
			restartAsAdmin(UPDATE_FORCED);
			return FALSE;
		}
		else
		{
			FullUpdate();
			BootLoaderUtil::RestartAsNormal("-wait");
			return FALSE;
		}
	}
#endif
	

#ifdef _DEBUG
	SetRegValues();
	InstallService();
#else
	int nu = NeedUpdate();

	if (nu != UPDATE_NONE)
	{
		if (nu == UPDATE_MCF)
		{
			Log("Updating from MCF.\n");
			McfUpdate();
			BootLoaderUtil::RestartAsNormal("-wait");
			return FALSE;
		}
		else if (nu == UPDATE_SERVICE_PATH)
		{
			Log("Service update path [%s].\n", g_UpdateReasons[nu]);

			if (ServiceUpdate(true))
				nu = UPDATE_NONE;
		}
	}

	if (nu != UPDATE_NONE)
	{
		if (!hasAdminRights)
		{
			restartAsAdmin(nu);
			return FALSE;
		}
		else if (nu == UPDATE_SERVICE_LOCATION || nu == UPDATE_SERVICE_HASH)
		{
			Log("Service update location [%s].\n", g_UpdateReasons[nu]);
			ServiceUpdate(false);
		}
		else if (nu == UPDATE_SERVICE_DISABLED)
		{
			if (FixServiceDisabled())
				BootLoaderUtil::RestartAsNormal("-wait");

			return FALSE;
		}
		else
		{
			Log("Full update [%s].\n", g_UpdateReasons[nu]);
			FullUpdate();
			BootLoaderUtil::RestartAsNormal("-wait");
			return FALSE;
		}
	}

	if (hasAdminRights && !(osid == WINDOWS_XP || osid == WINDOWS_XP64))
	{
		BootLoaderUtil::RestartAsNormal("-wait");
		return FALSE;
	}
#endif

	loadUICore();

	if (!m_pUICore)
		return FALSE;

	bool res = m_pUICore->initWxWidgets(m_hInstance, m_nCmdShow, args.getArgc(), const_cast<char**>(args.getArgv()));

	if (res)
		m_pMainWnd = new BootLoaderUtil::CDummyWindow(m_pUICore->getHWND());

	return res?TRUE:FALSE;
}