PdIISManager

<< Click to Display Table of Contents >>

Navigation:  Deployment > Deployment Targets > IIS\ISAPI > cmIISConfig – IIS configuration program >

PdIISManager

using System;

using System.Linq;

using System.Windows.Forms;

using System.Collections.Generic;

using Microsoft.Web.Administration;

 

 

namespace PdMagic.Windows

{

   public class VirtualFolder

   {

       public VirtualFolder(string aAlias, string aPhysicalFolder)

       {

           Alias = aAlias;

           PhysicalFolder = aPhysicalFolder;

       }

       public string Alias { get; set; }

       public string PhysicalFolder { get; set; }

   }

   public class MimeEntry

   {

       public MimeEntry(string aExtension, string aMIMEType)

       {

           Extension = aExtension;

           MimeType = aMIMEType;

       }

       public string Extension { get; set; }

       public string MimeType { get; set; }

   }

 

   public class PdIISManager

   {

       private ServerManager mServerManager;

 

       public PdIISManager( )

       {

           mServerManager = new ServerManager();

       }

 

       public void ReLoad()

       {

           mServerManager = new ServerManager();

       }

       public SiteCollection Sites

       {

           get { return mServerManager.Sites; }

       }

 

       public ApplicationPoolCollection ApplicationPools

       {

           get { return mServerManager.ApplicationPools; }

       }

 

       public void AddNewSite(string aName, string aFolder, List<string> aStatus)

       {

           aStatus.Add("NEW SITE");

           try

           {

               // Create and add site

               const string lProtocol = "http";

               const string lBinding = "*:80:";

               mServerManager.Sites.Add(aName, lProtocol, lBinding, aFolder);

               mServerManager.CommitChanges();

 

               aStatus.Add($"+ Name: ({aName})");

               aStatus.Add($"+ Protocol: ({lProtocol}), binding: ({lBinding})");

           }

           catch (Exception lAddNewSite)

           {

               throw new Exception("AddNewSite", lAddNewSite);

           }

       }

 

       public void DeleteSite(string aName, List<string> aStatus)

       {

           aStatus.Add("DELETE SITE");

           try

           {

               var lSite = mServerManager.Sites[aName];

               mServerManager.Sites.Remove(lSite);

               mServerManager.CommitChanges();

               aStatus.Add($"+ Name: ({aName})");

           }

           catch (Exception lDeleteSite)

           {

               throw new Exception( "DeleteSite", lDeleteSite);

           }

       }

       public void VerifyDLLAllowed(string aName, string aDLLPath, string aDescription, List<string> aStatus)

       {

           aStatus.Add("NEW ISAPI CGI RESTRICTION");

 

           const string lSection = "system.webServer/security/isapiCgiRestriction";

           var lConfig = mServerManager.GetApplicationHostConfiguration();

           var lIsapiCgiRestrictionSection = lConfig.GetSection(lSection);

           ConfigurationElementCollection lIsapiCgiRestrictionCollection = lIsapiCgiRestrictionSection.GetCollection();

           aStatus.Add( $"* Section: ({lSection})");

 

           var lExists = lIsapiCgiRestrictionCollection.Any(

               aConfigurationElement => aConfigurationElement.Attributes["path"].Value.Equals(aDLLPath));

 

           if (lExists)

           {

               aStatus.Add($"= An element already exists that points to ({aDLLPath})");

           }

           else

           {

               ConfigurationElement lAddElement = lIsapiCgiRestrictionCollection.CreateElement("add");

               lAddElement["groupId"] = aName;

               lAddElement["path"] = aDLLPath;

               lAddElement["allowed"] = true;

               lAddElement["description"] = aDescription;

               lIsapiCgiRestrictionCollection.Add(lAddElement);

               mServerManager.CommitChanges();

 

               aStatus.Add($"+ GroupId: ({lAddElement["groupId"]})");

               aStatus.Add($"+ Path=({lAddElement["path"]})");

               aStatus.Add($"+ Allowed=({lAddElement["allowed"]})");

               aStatus.Add($"+ Description=({lAddElement["description"]})");

           }

       }

 

       public void CreateISAPIHandler(string aSiteName, string aVirtualPath,string aHandlerName, string aDLLPath, List<string> aStatus)

       {

           aStatus.Add("ADD ISAPI HANDLER");

           var lParams = $"(SiteName={aSiteName}, VirtualPath={aVirtualPath}, Handler={aHandlerName}, DllPath={aDLLPath})";

           try

           {

               Configuration lSiteConfig;

               ConfigurationSection lHandlersSection;

               ConfigurationElementCollection lHandlersCollection;

               bool lExists;

 

               //var lSiteConfig = mServerManager.GetApplicationHostConfiguration();

               try

               {

                   lSiteConfig = mServerManager.GetWebConfiguration(aSiteName, aVirtualPath);

                   aStatus.Add($"* Site / Path: ({aSiteName}{aVirtualPath})");

               }

               catch (Exception lGetWebConfiguration)

               {

                   throw new Exception("GetWebConfiguration()", lGetWebConfiguration);

               }

 

               try

               {

                   const string lSection = "system.webServer/handlers";

                   const string lPolicy = "Read, Script, Execute";

                   lHandlersSection = lSiteConfig.GetSection(lSection);

                   lHandlersSection["accessPolicy"] = lPolicy;

                   aStatus.Add($"* Set {lSection}/accessPolicy to ({lPolicy})");

               }

               catch (Exception lGetSection)

               {

                   throw new Exception("GetSection() and set accessPolicy", lGetSection);

               }

 

               try

               {

                   lHandlersCollection = lHandlersSection.GetCollection();

               }

               catch (Exception lGetCollection)

               {

                   throw new Exception("GetCollection()", lGetCollection);

               }

 

               try

               {

                   lExists = lHandlersCollection.Any(

                       aConfigurationElement => aConfigurationElement.Attributes["name"].Value.Equals(aHandlerName));

               }

               catch (Exception lCheckExists)

               {

                   throw new Exception("Check Handler Exists", lCheckExists);

               }

 

               if (lExists)

               {

                   aStatus.Add($"= Handler: ({aHandlerName}) already exists");

               }

               else

               {

                   try

                   {

                       ConfigurationElement lAddElement = lHandlersCollection.CreateElement("add");

                       lAddElement["name"] = aHandlerName;

 

                       lAddElement["path"] = "CrashMagicOnline_ISAPI.dll";

                       lAddElement["allowPathInfo"] = "true";

 

                       lAddElement["verb"] = "*";

                       lAddElement["modules"] = "IsapiModule";

                       lAddElement["scriptProcessor"] = aDLLPath;

                       lAddElement["resourceType"] = "File";

                       lAddElement["requireAccess"] = "Execute";

                       lAddElement["preCondition"] = "bitness32";

                       lHandlersCollection.Add(lAddElement);

                       mServerManager.CommitChanges();

 

                       aStatus.Add($"+ name: ({lAddElement["name"]})");

                       aStatus.Add($"+ path: ({ lAddElement["path"]})");

                       aStatus.Add($"+ allowPathInfo: ({ lAddElement["allowPathInfo"]})");

                       aStatus.Add($"+ verb: ({ lAddElement["verb"]})");

                       aStatus.Add($"+ modules: ({ lAddElement["modules"]})");

                       aStatus.Add($"+ scriptProcessor: ({ lAddElement["scriptProcessor"]})");

                       aStatus.Add($"+ resourceType: ({ lAddElement["resourceType"]})");

                       aStatus.Add($"+ requireAccess: ({ lAddElement["requireAccess"]})");

                       aStatus.Add($"+ preCondition: ({ lAddElement["preCondition"]})");

                   }

                   catch (Exception lAddHandler)

                   {

                       throw new Exception("Add Handler", lAddHandler);

                   }

               }

           }

           catch (Exception lException)

           {

              throw new Exception($"CreateISAPIHandler{lParams}", lException);  

           }

       }

 

       public void SetMaxAllowedContentLength(string aSiteName, int aLength, List<string> aStatus)

 

       {

           aStatus.Add("SET MAX ALLOWED CONTENT LENGTH");

           const string lSectionPath = "system.webServer/security/requestFiltering";

           var lStatus = new List<string>();

 

           // Unlock section:

           var lConf = mServerManager.GetApplicationHostConfiguration();

           var lSection = lConf.RootSectionGroup.SectionGroups["system.webServer"].SectionGroups["security"].Sections["requestFiltering"];

           lSection.OverrideModeDefault = "Allow";

           mServerManager.CommitChanges();

           aStatus.Add($"* Section: ({lSectionPath}) Set OverrideModeDefault to (Allow).");

 

           // Set value:

           var lConfig = mServerManager.GetWebConfiguration(aSiteName);

           var lRequestFilteringSection = lConfig.GetSection(lSectionPath);

           var lRequestLimitsElement = lRequestFilteringSection.GetChildElement("requestLimits");

           var lOldLength = Convert.ToInt64(lRequestLimitsElement.GetAttributeValue("maxAllowedContentLength"));

           if (lOldLength == aLength)

           {

               aStatus.Add($"= requestLimits/maxAllowedContentLength already set to ({lOldLength})");

           }

           else

           {

               lRequestLimitsElement.SetAttributeValue("maxAllowedContentLength", aLength);

               mServerManager.CommitChanges();

 

               aStatus.Add($"+ Set requestLimits/maxAllowedContentLength to ({lRequestLimitsElement.GetAttributeValue("maxAllowedContentLength")})");

           }

       }

 

       public void SetServerRuntimeValues(string aSiteName, uint aUploadReadAheadSize, uint aMaxRequestEntityAllowed, List<string> aStatus)

       {

           aStatus.Add("SET SERVER RUNTIME PARAMETERS");

           const string lSectionPath = "system.webServer/serverRuntime";

           // Unlock section:

           var lConf = mServerManager.GetApplicationHostConfiguration();

           var lSection = lConf.RootSectionGroup.SectionGroups["system.webServer"].Sections["serverRuntime"];

           lSection.OverrideModeDefault = "Allow";

           mServerManager.CommitChanges();

 

           aStatus.Add($"* Section ({lSectionPath}) Set OverrideModeDefault to (Allow).");

 

           // Set value:

           var lConfig = mServerManager.GetWebConfiguration(aSiteName);

           var lServerRuntimeSection = lConfig.GetSection(lSectionPath);

 

           var lOldReadAheadSize = Convert.ToInt64(lServerRuntimeSection.GetAttributeValue("uploadReadAheadSize"));

           if (lOldReadAheadSize == aUploadReadAheadSize)

           {

               aStatus.Add($"= uploadReadAheadSize already set to ({lOldReadAheadSize})");

           }

           else

           {

               lServerRuntimeSection.SetAttributeValue("uploadReadAheadSize", aUploadReadAheadSize);

               aStatus.Add($"+ Set uploadReadAheadSize: ({lServerRuntimeSection.GetAttributeValue("uploadReadAheadSize")})");

           }

 

           var lOldMaxRequestEntity = Convert.ToInt64(lServerRuntimeSection.GetAttributeValue("maxRequestEntityAllowed"));

           if (lOldMaxRequestEntity == aMaxRequestEntityAllowed) {

               aStatus.Add($"= uploadReadAheadSize already set to ({lOldMaxRequestEntity})");

           }

           else

           {

               lServerRuntimeSection.SetAttributeValue("maxRequestEntityAllowed", aMaxRequestEntityAllowed);

               mServerManager.CommitChanges();

 

               aStatus.Add($"+ Set maxRequestEntityAllowed: ({lServerRuntimeSection.GetAttributeValue("maxRequestEntityAllowed")})");

           }

       }

 

       public void VerifyDefaultDocument(string aSiteName, string aVirtualPath, string aFileName, List<string> aStatus)

       {

           aStatus.Add("SET DEFAULT DOCUMENT");

 

           const string lSectionPath = "system.webServer/defaultDocument";

           var lConfig = mServerManager.GetWebConfiguration(aSiteName, aVirtualPath);

           var lDefaultDocumentSection = lConfig.GetSection(lSectionPath);

           lDefaultDocumentSection["enabled"] = true;

 

           aStatus.Add($"* Section: ({lSectionPath}) Set enabled = true");

           aStatus.Add($"* Site / Path: ({aSiteName}{aVirtualPath})");

 

           var lExists = false;

           var lFilesCollection = lDefaultDocumentSection.GetCollection("files");

           foreach (var lDefaultPage in lFilesCollection)

           {

               if (aFileName.ToLower() == ((string)lDefaultPage["value"]).ToLower())

                   lExists = true;

           }

 

           if (lExists)

           {

               aStatus.Add($"= ({aFileName}) already exists as default");

           }

           else

           {

               ConfigurationElement lAddElement = lFilesCollection.CreateElement("add");

               lAddElement["value"] = aFileName;

               lFilesCollection.AddAt(0, lAddElement);

               mServerManager.CommitChanges();

 

               aStatus.Add($"+ Inserted ({aFileName}) as the first default document");

           }

       }

 

       public bool MimeTypeRegistered(string aSiteName, string aVirtualPath, string aExtension, string aMimeType)

       {

           bool lExists = false;

 

           if (aVirtualPath != "/")

               lExists = MimeTypeRegistered(aSiteName, "/", aExtension, aMimeType);

 

           if (!lExists)

           {

               var lVDirConfig = mServerManager.GetWebConfiguration(aSiteName, aVirtualPath);

               var lStaticContentSection = lVDirConfig.GetSection("system.webServer/staticContent");

               var lMimeMap = lStaticContentSection.GetCollection();

 

               var lMt =

                   lMimeMap.FirstOrDefault(

                       aMapEntry => (string) aMapEntry.Attributes["fileExtension"].Value == aExtension);

               lExists = lMt != null;

 

           }

 

           return lExists;

       }

 

       public void VerifyMimeType(string aSiteName, string aVirtualPath, string aExtension, string aMimeType, List<string> aStatus)

       {

           const string lSectionPath = "system.webServer/staticContent";

           if (MimeTypeRegistered(aSiteName, aVirtualPath, aExtension, aMimeType))

           {

               aStatus.Add($"= Mime entry already exists for ({aExtension})");

           }

           else

           {

               var lVDirConfig = mServerManager.GetWebConfiguration(aSiteName, aVirtualPath);

               var lStaticContentSection = lVDirConfig.GetSection(lSectionPath);

               var lMimeMap = lStaticContentSection.GetCollection();

 

               var lMimeMapElement = lMimeMap.CreateElement("mimeMap");

               lMimeMapElement["fileExtension"] = aExtension;

               lMimeMapElement["mimeType"] = aMimeType;

               lMimeMap.Add(lMimeMapElement);

               mServerManager.CommitChanges();

 

               aStatus.Add($"+ Added mime type: ({aMimeType}) for ({aExtension})");

           }

       }

 

       public void VerifyMimeTypes(string aSiteName, string aApplicationPath, List<MimeEntry> aMimeEntries, List<string> aStatus)

       {

           const string lSectionPath = "system.webServer/staticContent";

           aStatus.Add("SET MIME TYPES");

           aStatus.Add($"* Section: ({lSectionPath})");

           aStatus.Add($"* Site / Path: ({aSiteName}{aApplicationPath})");

 

           foreach (MimeEntry lEntry in aMimeEntries)

           {

               VerifyMimeType(aSiteName, aApplicationPath, lEntry.Extension, lEntry.MimeType, aStatus);

           }

       }

 

   private static ConfigurationElement FindElement(ConfigurationElementCollection aCollection, string aElementTagName, params string[] aKeyValues)

       {

           foreach (ConfigurationElement lElement in aCollection)

           {

               if (String.Equals(lElement.ElementTagName, aElementTagName, StringComparison.OrdinalIgnoreCase))

               {

                   bool lMatches = true;

                   for (int i = 0; i < aKeyValues.Length; i += 2)

                   {

                       object o = lElement.GetAttributeValue(aKeyValues[i]);

                       string lValue = null;

                       if (o != null)

                       {

                           lValue = o.ToString();

                       }

                       if (!String.Equals(lValue, aKeyValues[i + 1], StringComparison.OrdinalIgnoreCase))

                       {

                           lMatches = false;

                           break;

                       }

                   }

                   if (lMatches)

                   {

                       return lElement;

                   }

               }

           }

           return null;

       }

 

       public void SetApplicationUser(string aSite, string aApplication, string aUserName, string aPassword, List<string> aStatus)

       {

           aStatus.Add("SET APPLICATION USER");

           try

           {

               const string lSectionPath = "system.applicationHost/sites";

               var lConfig = mServerManager.GetApplicationHostConfiguration();

               var lSitesSection = lConfig.GetSection(lSectionPath);

               var lSitesCollection = lSitesSection.GetCollection();

               var lSiteElement = FindElement(lSitesCollection, "site", "name", aSite);

               var lApplicationCollection = lSiteElement.GetCollection();

 

               ConfigurationElement lApplicationElement = FindElement(lApplicationCollection, "application", "path", aApplication);

               ConfigurationElementCollection lVirtualDirCollection = lApplicationElement.GetCollection();

               ConfigurationElement lVirtualDirElement = FindElement(lVirtualDirCollection, "virtualDirectory", "path", @"/");

               aStatus.Add($"* Application: ({aApplication})");

               aStatus.Add($"* Site: ({aSite})");

 

               if (lVirtualDirElement.Attributes["userName"].Value.Equals(aUserName))

               {

                   aStatus.Add($"= UserName: ({lVirtualDirElement.Attributes["userName"].Value}) already set");

               }

               else

               {

                   lVirtualDirElement.Attributes["userName"].Value = aUserName;

                   lVirtualDirElement.Attributes["password"].Value = aPassword;

                   aStatus.Add($"+ Set userName: ({lVirtualDirElement.Attributes["userName"].Value})");

                   aStatus.Add($"+ Set password: (***)");

               }

           }

           catch (Exception lSetApplicationUser)

           {

               throw new Exception("SetApplicationUser", lSetApplicationUser);

           }

       }

 

       public void AddNewApplication(string aSite, string aApplication, string aPath, List<string> aStatus)

       {

           aStatus.Add("ADD APPLICATION");

           try

           {

               mServerManager.Sites[aSite].Applications.Add(aApplication, aPath);

               mServerManager.CommitChanges();

               aStatus.Add($"+ Site / Path: ({ aSite}{aPath})");

               aStatus.Add($"+ Application: ({aApplication})");

           }

           catch (Exception lAddNewApplication)

           {

               throw new Exception("Add New Application", lAddNewApplication);

           }

       }

 

 

       private void VerifyVirtualDirectory(string aSite, string aApplication, string aVirtualName, string aPhysicalDir, List<string> aStatus )

       {

           try

           {

               var lExists = false;

               var lApplication = mServerManager.Sites[aSite].Applications[aApplication];

               foreach (var lDirectory in lApplication.VirtualDirectories)

               {

                   if (lDirectory.PhysicalPath.ToLower() == aPhysicalDir.ToLower())

                       lExists = true;

               }

 

               if (lExists)

               {

                   aStatus.Add($"= Virtual directory ({aVirtualName}) already exists");

               }

               else

               {

                   lApplication.VirtualDirectories.Add(aVirtualName, aPhysicalDir);

                   mServerManager.CommitChanges();

 

                   aStatus.Add($"+ Added virtual directory ({aVirtualName}={aPhysicalDir})");

               }

           }

           catch (Exception lAddNewVirtualDirectory)

           {

               throw new Exception("Add New Virtual Directory ", lAddNewVirtualDirectory);

           }

       }

 

       public void VerifyVirtualFolders( string aSiteName, string aApplicationPath, List<VirtualFolder> aFolders, List<string> aStatus)

       {

           aStatus.Add($"ADD VIRTUAL FOLDERS");

           aStatus.Add($"* Site / Path: ({aSiteName}{aApplicationPath})");

           foreach (VirtualFolder lVirtualFolder in aFolders)

           {

               VerifyVirtualDirectory( aSiteName, aApplicationPath, $"/{lVirtualFolder.Alias}",

                   lVirtualFolder.PhysicalFolder, aStatus);

           }

       }

       public void SetUpApplicationPool(string aApplicationPoolName, string aUserName, string aPassword, List<string> aStatus)

       {

           aStatus.Add("PREPARE APPLICATION POOL");

           try

           {

               aStatus.Add($"* Pool name: ({aApplicationPoolName})");

 

               var lAppPool = mServerManager.ApplicationPools[aApplicationPoolName];

               lAppPool.ManagedRuntimeVersion = "v4.0";

               aStatus.Add($"+ Set ManagedRuntimeVersion: ({lAppPool.ManagedRuntimeVersion})");

 

               lAppPool.ManagedPipelineMode = ManagedPipelineMode.Integrated;

               aStatus.Add($"+ Set ManagedPipelineMode: ({lAppPool.ManagedPipelineMode})");

 

               lAppPool.Enable32BitAppOnWin64 = true;

               aStatus.Add($"+ Set Enable32BitAppOnWin64: ({lAppPool.Enable32BitAppOnWin64})");

 

               lAppPool.AutoStart = true;

               aStatus.Add($"+ Set AutoStart: ({lAppPool.AutoStart})");

 

               lAppPool.ProcessModel.IdleTimeout = new TimeSpan(0, 360, 0);

               aStatus.Add($"+ Set ProcessModel.IdleTimeout: ({lAppPool.ProcessModel.IdleTimeout})");

 

               lAppPool.Recycling.DisallowOverlappingRotation = true;

               aStatus.Add($"+ Set Recycling.DisallowoverlappingRotation: ({lAppPool.Recycling.DisallowOverlappingRotation})");

 

               lAppPool.Recycling.PeriodicRestart.Time = new TimeSpan(0, 0, 0);

               aStatus.Add($"+ Set Recycling.PeriodicRestart.Time: ({new TimeSpan(0, 0, 0)})");

 

               lAppPool.Recycling.PeriodicRestart.Schedule.Clear();

               lAppPool.Recycling.PeriodicRestart.Schedule.Add(new TimeSpan(3,0,0));

               aStatus.Add($"+ Set Recycling.PeriodicRestart.Schedule: ({new TimeSpan(3,0,0)})");

               

               if (aUserName != string.Empty)

               {

                   lAppPool.ProcessModel.UserName = Environment.MachineName + "\\" + aUserName;

                   lAppPool.ProcessModel.IdentityType = ProcessModelIdentityType.SpecificUser;

                   lAppPool.ProcessModel.Password = aPassword;

                   aStatus.Add($"+ Set ProcessModelUserName: ({lAppPool.ProcessModel.UserName}) Password: (***)");

                   aStatus.Add($"+ Set IdentityType: (SpecificUser)");

               }

               else

               {

                   aStatus.Add("* No User Name sent");

               }

               mServerManager.CommitChanges();

           }

 

           catch (Exception lSetUpApplicationPool)

           {

               throw new Exception("Set Up ApplicationPool", lSetUpApplicationPool);

           }

       }

 

       public void AddNewApplicationPool(string aApplicationPoolName, List<string> aStatus)

       {

           aStatus.Add("ADD APPLICATION POOL");

           try

           {

               mServerManager.ApplicationPools.Add(aApplicationPoolName);

               mServerManager.CommitChanges();

               aStatus.Add($"+ Pool name: ({aApplicationPoolName})");

 

           }

           catch (Exception lAddNewApplicationPool)

           {

               throw new Exception("Add New ApplicationPool", lAddNewApplicationPool);

           }

       }

 

       public void DeleteApplicationPool(string aApplicationPoolName, List<string> aStatus)

       {

           aStatus.Add("DELETE APPLICATION POOL");

           try

           {

               ApplicationPool lAppPool = mServerManager.ApplicationPools[aApplicationPoolName];

               if (lAppPool == null)

               {

                   throw new Exception("DeleteApplicationPool - Application pool not found");

               }

 

               ApplicationPoolCollection lAppColl = mServerManager.ApplicationPools;

               lAppColl.Remove(lAppPool);

               mServerManager.CommitChanges();

               aStatus.Add($"+ Pool name: ({aApplicationPoolName})");

           }

           catch (Exception lDeleteApplication)

           {

               throw new Exception("Delete Application", lDeleteApplication);

           }

       }

 

       public void AttachSiteToApplicationPool(string aSite, string aApplicationPath, string aApplicationPool, List<string> aStatus)

       {

           aStatus.Add("ADD SITE TO APPLICATION POOL");

           try

           {

               mServerManager.Sites[aSite].Applications[aApplicationPath].ApplicationPoolName = aApplicationPool;

               ApplicationPool lAppPool = mServerManager.ApplicationPools[aApplicationPool];

               aStatus.Add($"+ Site: ({mServerManager.Sites[aSite].Name}) added to pool: ({lAppPool.Name})");

 

               mServerManager.CommitChanges();

           }

           catch (Exception lAttachSiteToAppPool)

           {

               throw new Exception("Attach Site To Application Pool", lAttachSiteToAppPool);

           }

       }

 

   }

}