context: using System;
  using System.Collections.Generic;
  using System.Text;
  using System.Data;
  using System.Net;
  using System.Collections;
  using System.Runtime.InteropServices;
  using Microsoft.Win32;
  using FOG;
  using IniReaderObj;
  using System.IO;
  using System.Diagnostics;
  
  namespace FOG 
  {
  
      public class SnapinClient : AbstractFOGService
      {
          [DllImport("user32.dll")] private static extern bool SetForegroundWindow(IntPtr hWnd);
          [DllImport("user32.dll")] private static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);
          [DllImport("user32.dll")] private static extern bool IsIconic(IntPtr hWnd);
  
          private const int SW_HIDE = 0;
          private const int SW_SHOWNORMAL = 1;
          private const int SW_SHOWMINIMIZED = 2;
          private const int SW_SHOWMAXIMIZED = 3;
          private const int SW_SHOWNOACTIVATE = 4;
          private const int SW_RESTORE = 9;
          private const int SW_SHOWDEFAULT = 10;
  
          private int intStatus, intPause;
          private String strURLPathCheckin, strURLPathDownload;
          private String strURLModuleStatus;
          private Boolean blGo;
  
          private const String MOD_NAME = "FOG::SnapinClient";
  
          public SnapinClient()
          {
              intStatus = STATUS_STOPPED;
              intPause = 400;
              blGo = false;
          }
  
          private Boolean readSettings()
          {
              if (ini != null)
              {
                  if (ini.isFileOk())
                  {
                      String preCheckIn = ini.readSetting("snapinclient", "checkinurlprefix");
                      String postCheckIn = ini.readSetting("snapinclient", "checkinurlpostfix");
  
                      String preDL = ini.readSetting("snapinclient", "downloadurlprefix");
                      String postDL = ini.readSetting("snapinclient", "downloadurlpostfix");
  
                      String ip = ini.readSetting("fog_service", "ipaddress");
  
                      if (ip == null || ip.Trim().Length == 0)
                          ip = "fogserver";
  
                      // get the module status URL 
                      String strPreMS = ini.readSetting("fog_service", "urlprefix");
                      String strPostMS = ini.readSetting("fog_service", "urlpostfix");
                      if (ip != null && strPreMS != null && strPostMS != null)
                          strURLModuleStatus = strPreMS + ip + strPostMS;
                      else
                      {
                          return false;
                      }
  
                      try
                      {
                          intPause = Int32.Parse( ini.readSetting("snapinclient", "checkintime").Trim() );
                      }
                      catch
                      { }
  
                      if (ip != null && ip.Length > 0 && preCheckIn != null && preCheckIn.Length > 0 && postCheckIn != null && postCheckIn.Length > 0 && preDL != null && preDL.Length > 0 && postDL != null && postDL.Length > 0)
                      {
  
                          strURLPathCheckin = preCheckIn + ip + postCheckIn;
                          strURLPathDownload = preDL + ip + postDL;
                          return true;
                      }
                  }
              }
              return false;
          }
  
          public override void mStart()
          {
              try
              {
                  intStatus = STATUS_RUNNING;
                  if (readSettings())
                  {
                      blGo = true;
                      startWatching();
                  }
                  else
                  {
                      log(MOD_NAME, "Failed to read ini settings.");
                  }
              }
              catch
              {
              }
          }
  
          public override string mGetDescription()
          {
              return "Snapin Client - Installs snapins on client computers.";
          }
  
          private void startWatching()
          {
              try
              {
                  log(MOD_NAME, "Starting snapin client process...");
  
                  String strCurrentHostName = getHostName();
  
                  ArrayList alMACs = getMacAddress();
  
                  try
                  {
                      Random r = new Random();
                      //int intSleep = r.Next(350, 500);	// 0.32
                      int intSleep = r.Next(30, 60);	// 0.33
                      
                      log(MOD_NAME, "Sleeping for " + intSleep + " seconds.");
                      System.Threading.Thread.Sleep(intSleep * 1000);
                  }
                  catch{}
  
                  while (blGo)
                  {
                      // process every mac address on the machine
                      // to make sure we get all intended snapins
                      Boolean blInstalled = false;
  
                      String macList = null;
                      if (alMACs != null && alMACs.Count > 0)
                      {
                          String[] strMacs = (String[])alMACs.ToArray(typeof(String));
                          macList = String.Join("|", strMacs);
                      }
  
                      if (macList != null && macList.Length > 0)
                      {
                          try
                          {
                              Boolean blConnectOK = false;
                                  String strDta = "";
                                  while (!blConnectOK)
                                  {
                                      try
                                      {
                                          log(MOD_NAME, "Attempting to connect to fog server...");
                                          WebClient wc = new WebClient();
                                          String strPath = strURLModuleStatus + "?mac=" + macList + "&moduleid=snapin";
                                          strDta = wc.DownloadString(strPath);
                                          blConnectOK = true;
                                      }
                                      catch (Exception exp)
                                      {
                                          log(MOD_NAME, "Failed to connect to fog server!");
                                          log(MOD_NAME, exp.Message);
                                          log(MOD_NAME, exp.StackTrace);
                                          log(MOD_NAME, "Sleeping for 1 minute.");
                                          try
                                          {
                                              System.Threading.Thread.Sleep(60000);
                                          }
                                          catch { }
                                      }
                                  }
  
                                  strDta = strDta.Trim();
                                  Boolean blLoop = false;
  
                                  if (strDta.StartsWith("#!ok", true, null))
                                  {
                                      log(MOD_NAME, "Module is active...");
                                      blLoop = true;
                                  }
                                  else if (strDta.StartsWith("#!db", true, null))
                                  {
                                      log(MOD_NAME, "Database error.");
                                  }
                                  else if (strDta.StartsWith("#!im", true, null))
                                  {
                                      log(MOD_NAME, "Invalid MAC address format.");
                                  }
                                  else if (strDta.StartsWith("#!ng", true, null))
                                  {
                                      log(MOD_NAME, "Module is disabled globally on the FOG Server, exiting.");
                                      return;
                                  }
                                  else if (strDta.StartsWith("#!nh", true, null))
                                  {
                                      log(MOD_NAME, "Module is disabled on this host.");
                                  }
                                  else if (strDta.StartsWith("#!um", true, null))
                                  {
                                      log(MOD_NAME, "Unknown Module ID passed to server.");
                                  }
                                  else if (strDta.StartsWith("#!er", true, null))
                                  {
                                      log(MOD_NAME, "General Error Returned: ");
                                      log(MOD_NAME, strDta);
                                  }
                                  else
                                  {
                                      log(MOD_NAME, "Unknown error, module will exit.");
                                  }
  
  
                                  if (blLoop)
                                  {
                                      WebClient web = new WebClient();
                                      String strPathCheckin = strURLPathCheckin + "?mac=" + macList;
                                      String strData = web.DownloadString(strPathCheckin);
                                      if (strData != null)
                                      {
                                          String[] arData = strData.Split('\n');
                                          String strAction = arData[0];
                                          strAction = strAction.Trim();
  
                                          if (strAction.StartsWith("#!db"))
                                          {
                                              log(MOD_NAME, "Unable to determine snapin status due to a database error.");
                                          }
                                          else if (strAction.StartsWith("#!im"))
                                          {
                                              log(MOD_NAME, "Unable to determine snapin status because the MAC address was not correctly formated.");
                                          }
                                          else if (strAction.StartsWith("#!er"))
                                          {
                                              log(MOD_NAME, "Unable to determine snapin status due to an unknown error.");
                                              log(MOD_NAME, "Maybe MAC isn't registered: " + macList);
                                          }
                                          else if (strAction.StartsWith("#!it"))
                                          {
                                              log(MOD_NAME, "Will NOT perform any snapin tasks because an image task exists for this host.");
                                          }
                                          else if (strAction.StartsWith("#!ns"))
                                          {
                                              // ok, no tasks found
                                              log(MOD_NAME, "No Tasks found for: " + macList);
                                          }
                                          else if (strAction.StartsWith("#!ok"))
                                          {
                                              // task exists load meta data, then download file.
  
                                              if (arData.Length == 9)
                                              {
  
                                                  String strTaskID = arData[1];
                                                  String strCreated = arData[2];
                                                  String strSnapinName = arData[3];
                                                  String strArgs = arData[4];
                                                  String strRestart = arData[5];
                                                  String strFileName = arData[6];
                                                  String strRunWith = arData[7];
                                                  String strRunWithArgs = arData[8];
  
                                                  if (strRunWith != null)
                                                  {
                                                      strRunWith = strRunWith.Trim();
                                                      if (strRunWith.StartsWith("SNAPINRUNWITH=")) strRunWith = strRunWith.Replace("SNAPINRUNWITH=", "");
                                                  }
  
                                                  if (strRunWithArgs != null)
                                                  {
                                                      strRunWithArgs = strRunWithArgs.Trim();
                                                      if (strRunWithArgs.StartsWith("SNAPINRUNWITHARGS=")) strRunWithArgs = strRunWithArgs.Replace("SNAPINRUNWITHARGS=", "");
                                                  }
  
                                                  if (strTaskID != null)
                                                  {
                                                      strTaskID = strTaskID.Trim();
                                                      if (strTaskID.StartsWith("JOBTASKID=")) strTaskID = strTaskID.Replace("JOBTASKID=", "");
  
                                                  }
  
  
gt:                                                 if (strCreated != null)