/// <summary> /// Initializes a new instance of the <see cref="StatusDialog" /> class. /// </summary> /// <param name="api">The instantiated IQueryAPI object.</param> public StatusDialog( IQueryAPI api ) { // Initialize. _api = api; _cts = new CancellationTokenSource(); _progressMax = 30; // Setup dialog/progress bar. Caption = Strings.StatusDialogTitle; InstructionText = Strings.StatusDialogHeading; ProgressBarRange = new int[2] { 0, _progressMax }; ProgressBarValue = 1; ProgressBarState = TaskDialogProgressBarState.Normal; // Hook events. Closing += new EventHandler<CancelEventArgs>( StatusDialog_Canceled ); Opened += new EventHandler( StatusDialog_Opened ); HyperlinkClick += new EventHandler<HyperlinkEventArgs>( StatusDialog_Hyperlink ); }
/// <summary> /// Initializes a new instance of the <see cref="StatusDialog" /> class. /// </summary> /// <param name="api">The instantiated IQueryAPI object.</param> public StatusDialog(IQueryAPI api) { // Initialize. _api = api; _cts = new CancellationTokenSource(); _progressMax = 30; // Setup dialog/progress bar. Caption = Strings.StatusDialogTitle; InstructionText = Strings.StatusDialogHeading; ProgressBarRange = new int[2] { 0, _progressMax }; ProgressBarValue = 1; ProgressBarState = TaskDialogProgressBarState.Normal; // Hook events. Closing += new EventHandler <CancelEventArgs>(StatusDialog_Canceled); Opened += new EventHandler(StatusDialog_Opened); HyperlinkClick += new EventHandler <HyperlinkEventArgs>(StatusDialog_Hyperlink); }
/// <summary> /// Implementation of OnStart. Executes when a Start command is sent to the service by the Service Control /// Manager (SCM) or when the operating system starts. Specifies actions to take when the service starts. /// </summary> /// <param name="args">Data passed by the start command.</param> /// <exception cref="QueryAPIException" /> protected override void OnStart(string[] args) { // Read data from registry. RegistryKey regKey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\UnofficialDDNS"); IDictionary <string, string> regPack = new Dictionary <string, string>(); try { if ((int)regKey.GetValue("Debug", 0) == 1) { LogSingleton.I.EnableDebug = true; } regPack.Add("interval", ((int)regKey.GetValue("Interval", "")).ToString()); regPack.Add("registrar", (string)regKey.GetValue("Registrar", "")); regPack.Add("userName", (string)regKey.GetValue("Username", "")); regPack.Add("apiToken", (string)regKey.GetValue("ApiToken", "")); regPack.Add("domain", (string)regKey.GetValue("Domain", "")); } catch (NullReferenceException) { // Key doesn't exist. ExitCode = 1012; throw; } catch (InvalidCastException) { // Integer values aren't integers, or string values aren't strings. ExitCode = 1010; throw; } // Validate data from registry. try { if (regPack["registrar"].Length == 0) { throw new QueryAPIException(103); } if (regPack["userName"].Length == 0) { throw new QueryAPIException(100); } if (regPack["apiToken"].Length == 0) { throw new QueryAPIException(101); } if (regPack["domain"].Length == 0) { throw new QueryAPIException(102); } using (IQueryAPI api = QueryAPIIndex.I.Factory(regPack["registrar"])) { // Just testing for Error104. } } catch (QueryAPIException err) { string text = String.Format("Error {0}: {1}", err.Code.ToString(), err.RMessage); if (err.Details != null) { text += "\n\n" + err.Details; } if (err.Url != null) { text += "\n\n" + err.Url; } LogSingleton.I.Error(err.Code, text); ExitCode = 1011; throw; } // Start main thread. LogSingleton.I.Debug("Initializing polling thread."); _cts = new CancellationTokenSource(); _pollingThread = new Thread((ThreadStart) delegate { PollingThreadWorker(regPack); }); _pollingThread.Start(); LogSingleton.I.Debug("Polling thread started."); }
/// <summary> /// Called from a thread delegate. Does the actual work by querying the registrar's API through UDDNSQuery.dll /// and then sleeps according to the interval set in the registry. /// </summary> /// <param name="regPack">The reg pack.</param> private async void PollingThreadWorker(IDictionary <string, string> regPack) { while (!_cts.IsCancellationRequested) { int sleep = Convert.ToInt32(regPack["interval"]) * 60 * 1000; // [minutes] * seconds * milliseconds LogSingleton.I.Debug(String.Format("Sleep set to {0} milliseconds.", sleep)); try { LogSingleton.I.Debug("Initializing QueryAPI object."); using (_api = QueryAPIIndex.I.Factory(regPack["registrar"])) { // Pass credentials to class instance. LogSingleton.I.Debug("Setting registrar credentials to object instance."); _api.Credentials(regPack["userName"], regPack["apiToken"].Replace("ENCRYPTED:", ""), regPack["domain"] ); // Read only. LogSingleton.I.Debug("Executing GetCurrentIPAsync()"); await _api.GetCurrentIPAsync(_cts.Token); LogSingleton.I.Debug("Executing AuthenticateAsync()"); await _api.AuthenticateAsync(_cts.Token); LogSingleton.I.Debug("Executing ValidateDomainAsync()"); await _api.ValidateDomainAsync(_cts.Token); LogSingleton.I.Debug("Executing GetRecordsAsync()"); await _api.GetRecordsAsync(_cts.Token); // Check if DNS is outdated. LogSingleton.I.Debug("Recorded IP(s): " + string.Join(",", _api.RecordedIP.Values)); if (_api.RecordedIP.Count != 1 || _api.RecordedIP.Values.First() != _api.CurrentIP) { LogSingleton.I.Info( 999, String.Format("Updating {0} with the current IP address of {1}.", regPack["domain"], _api.CurrentIP) ); LogSingleton.I.Debug("Executing UpdateRecordAsync()"); await _api.UpdateRecordAsync(_cts.Token); } LogSingleton.I.Debug("Executing LogoutAsync()"); await _api.LogoutAsync(_cts.Token); } _api = null; } catch (QueryAPIException err) { string text = String.Format("Error {0}: {1}", err.Code.ToString(), err.RMessage); if (err.Details != null) { text += "\n\n" + err.Details; } if (err.Url != null) { text += "\n\n" + err.Url; } LogSingleton.I.Error(err.Code, text); sleep /= 4; LogSingleton.I.Debug(String.Format("Sleep set to {0} milliseconds.", sleep)); } catch (OperationCanceledException) { LogSingleton.I.Debug("Caught OperationCanceledException"); return; } // Give OnStop a chance to Abort thread before logging the below statement. try { await Task.Delay(1000, _cts.Token); } catch (OperationCanceledException) { return; } LogSingleton.I.Debug(String.Format("Sleeping {0} milliseconds.", sleep)); try { await Task.Delay(sleep, _cts.Token); } catch (OperationCanceledException) { return; } } }
public static ActionResult ValidateCredentials(Session session) { // Encrypt token. if (session["REGISTRAR_TOKEN"].Length > 0 && !session["REGISTRAR_TOKEN"].StartsWith("ENCRYPTED:")) { session["REGISTRAR_TOKEN"] = "ENCRYPTED:" + Convert.ToBase64String(ProtectedData.Protect( Encoding.ASCII.GetBytes(session["REGISTRAR_TOKEN"]), null, DataProtectionScope.LocalMachine )); } // Validate dialog fields. try { if (session["REGISTRAR_REGISTRAR"].Length == 0) { throw new QueryAPIException(103); } using (IQueryAPI api = QueryAPIIndex.I.Factory(session["REGISTRAR_REGISTRAR"])) { // Testing for Error98 in the above using statement. api.Credentials(session["REGISTRAR_USER"], session["REGISTRAR_TOKEN"].Replace("ENCRYPTED:", ""), session["REGISTRAR_DOMAIN"] ); if (api.UserLength == 0) { throw new QueryAPIException(100); } if (api.TokenLength == 0) { throw new QueryAPIException(101); } if (api.DomainLength == 0) { throw new QueryAPIException(102); } } } catch (QueryAPIException err) { using (TaskDialog dialog = new TaskDialog()) { // Launch the dialog and get result. Thread thread = new Thread((ThreadStart) delegate { dialog.ShowError(Strings.ErrorDialogTitle, err.RMessage + "\n"); }); thread.SetApartmentState(ApartmentState.STA); thread.Start(); thread.Join(); session["_RegistrarValidated"] = "0"; return(ActionResult.NotExecuted); } } // Validate with status dialog. using (IQueryAPI api = QueryAPIIndex.I.Factory(session["REGISTRAR_REGISTRAR"])) using (StatusDialog dialog = new StatusDialog(api)) { // Pass credentials to class instance. api.Credentials(session["REGISTRAR_USER"], session["REGISTRAR_TOKEN"].Replace("ENCRYPTED:", ""), session["REGISTRAR_DOMAIN"] ); // Launch the dialog and get result. Thread thread = new Thread((ThreadStart) delegate { dialog.Show(); }); thread.SetApartmentState(ApartmentState.STA); thread.Start(); thread.Join(); if (dialog.Result == TaskDialog.TaskDialogResult.Ok) { session["_RegistrarValidated"] = "1"; return(ActionResult.Success); } else { session["_RegistrarValidated"] = "0"; return(ActionResult.NotExecuted); } } }
/// <summary> /// Called from a thread delegate. Does the actual work by querying the registrar's API through UDDNSQuery.dll /// and then sleeps according to the interval set in the registry. /// </summary> /// <param name="regPack">The reg pack.</param> private async void PollingThreadWorker( IDictionary<string, string> regPack ) { while ( !_cts.IsCancellationRequested ) { int sleep = Convert.ToInt32( regPack["interval"] ) * 60 * 1000; // [minutes] * seconds * milliseconds LogSingleton.I.Debug( String.Format( "Sleep set to {0} milliseconds.", sleep ) ); try { LogSingleton.I.Debug( "Initializing QueryAPI object." ); using ( _api = QueryAPIIndex.I.Factory( regPack["registrar"] ) ) { // Pass credentials to class instance. LogSingleton.I.Debug( "Setting registrar credentials to object instance." ); _api.Credentials( regPack["userName"], regPack["apiToken"].Replace( "ENCRYPTED:", "" ), regPack["domain"] ); // Read only. LogSingleton.I.Debug( "Executing GetCurrentIPAsync()" ); await _api.GetCurrentIPAsync( _cts.Token ); LogSingleton.I.Debug( "Executing AuthenticateAsync()" ); await _api.AuthenticateAsync( _cts.Token ); LogSingleton.I.Debug( "Executing ValidateDomainAsync()" ); await _api.ValidateDomainAsync( _cts.Token ); LogSingleton.I.Debug( "Executing GetRecordsAsync()" ); await _api.GetRecordsAsync( _cts.Token ); // Check if DNS is outdated. LogSingleton.I.Debug( "Recorded IP(s): " + string.Join( ",", _api.RecordedIP.Values ) ); if ( _api.RecordedIP.Count != 1 || _api.RecordedIP.Values.First() != _api.CurrentIP ) { LogSingleton.I.Info( 999, String.Format( "Updating {0} with the current IP address of {1}.", regPack["domain"], _api.CurrentIP ) ); LogSingleton.I.Debug( "Executing UpdateRecordAsync()" ); await _api.UpdateRecordAsync( _cts.Token ); } LogSingleton.I.Debug( "Executing LogoutAsync()" ); await _api.LogoutAsync( _cts.Token ); } _api = null; } catch ( QueryAPIException err ) { string text = String.Format( "Error {0}: {1}", err.Code.ToString(), err.RMessage ); if ( err.Details != null ) text += "\n\n" + err.Details; if ( err.Url != null ) text += "\n\n" + err.Url; LogSingleton.I.Error( err.Code, text ); sleep /= 4; LogSingleton.I.Debug( String.Format( "Sleep set to {0} milliseconds.", sleep ) ); } catch ( OperationCanceledException ) { LogSingleton.I.Debug( "Caught OperationCanceledException" ); return; } // Give OnStop a chance to Abort thread before logging the below statement. try { await Task.Delay( 1000, _cts.Token ); } catch ( OperationCanceledException ) { return; } LogSingleton.I.Debug( String.Format( "Sleeping {0} milliseconds.", sleep ) ); try { await Task.Delay( sleep, _cts.Token ); } catch ( OperationCanceledException ) { return; } } }