// Copyright (c) 2012, Outercurve Foundation. // All rights reserved. // // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: // // - Redistributions of source code must retain the above copyright notice, this // list of conditions and the following disclaimer. // // - Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. // // - Neither the name of the Outercurve Foundation nor the names of its // contributors may be used to endorse or promote products derived from this // software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR // ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON // ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. using System; using System.Collections.Generic; using System.IO; using WebsitePanel.Providers.SharePoint; using WebsitePanel.Providers.Utils; using WebsitePanel.Server.Utils; using Microsoft.Win32; namespace WebsitePanel.Providers.HostedSolution { /// /// Provides hosted SharePoint server functionality implementation. /// public class HostedSharePointServer : HostingServiceProviderBase, IHostedSharePointServer { private delegate TReturn SharePointAction(HostedSharePointServerImpl impl); protected string Wss3RegistryKey; protected string Wss3Registry32Key; protected string LanguagePacksPath; public HostedSharePointServer() { this.Wss3RegistryKey = @"SOFTWARE\Microsoft\Shared Tools\Web Server Extensions\12.0"; this.Wss3Registry32Key = @"SOFTWARE\Wow6432Node\Microsoft\Shared Tools\Web Server Extensions\12.0"; this.LanguagePacksPath = @"%commonprogramfiles%\microsoft shared\Web Server Extensions\12\HCCab\"; } /// /// Gets root web application uri. /// public Uri RootWebApplicationUri { get { return new Uri(ProviderSettings["RootWebApplicationUri"]); } } public string BackupTemporaryFolder { get { return ProviderSettings["BackupTemporaryFolder"]; } } /// /// Gets list of supported languages by this installation of SharePoint. /// /// List of supported languages public int[] GetSupportedLanguages() { HostedSharePointServerImpl impl = new HostedSharePointServerImpl(); return impl.GetSupportedLanguages(LanguagePacksPath); } /// /// Gets list of SharePoint collections within root web application. /// /// List of SharePoint collections within root web application. public SharePointSiteCollection[] GetSiteCollections() { return ExecuteSharePointAction(delegate(HostedSharePointServerImpl impl) { return impl.GetSiteCollections(RootWebApplicationUri); }); } /// /// Gets SharePoint collection within root web application with given name. /// /// Url that uniquely identifies site collection to be loaded. /// SharePoint collection within root web application with given name. public SharePointSiteCollection GetSiteCollection(string url) { return ExecuteSharePointAction(delegate(HostedSharePointServerImpl impl) { return impl.GetSiteCollection(RootWebApplicationUri, url); }); } /// /// Creates site collection within predefined root web application. /// /// Information about site coolection to be created. public void CreateSiteCollection(SharePointSiteCollection siteCollection) { ExecuteSharePointAction(delegate(HostedSharePointServerImpl impl) { impl.CreateSiteCollection(RootWebApplicationUri, siteCollection); return null; }); } /// /// Deletes site collection under given url. /// /// Url that uniquely identifies site collection to be deleted. public void DeleteSiteCollection(SharePointSiteCollection siteCollection) { ExecuteSharePointAction(delegate(HostedSharePointServerImpl impl) { impl.DeleteSiteCollection(RootWebApplicationUri, siteCollection); return null; }); } /// /// Backups site collection under give url. /// /// Url that uniquely identifies site collection to be deleted. /// Resulting backup file name. /// A value which shows whether created backup must be archived. /// Created backup full path. public string BackupSiteCollection(string url, string filename, bool zip) { return ExecuteSharePointAction(delegate(HostedSharePointServerImpl impl) { return impl.BackupSiteCollection(RootWebApplicationUri, url, filename, zip, BackupTemporaryFolder); }); } /// /// Restores site collection under given url from backup. /// /// Site collection to be restored. /// Backup file name to restore from. public void RestoreSiteCollection(SharePointSiteCollection siteCollection, string filename) { ExecuteSharePointAction(delegate(HostedSharePointServerImpl impl) { impl.RestoreSiteCollection(RootWebApplicationUri, siteCollection, filename); return null; }); } /// /// Gets binary data chunk of specified size from specified offset. /// /// Path to file to get bunary data chunk from. /// Offset from which to start data reading. /// Binary data chunk length. /// Binary data chunk read from file. public virtual byte[] GetTempFileBinaryChunk(string path, int offset, int length) { byte[] buffer = FileUtils.GetFileBinaryChunk(path, offset, length); // Delete temp file if (buffer.Length < length) { FileUtils.DeleteFile(path); } return buffer; } /// /// Appends supplied binary data chunk to file. /// /// Non existent file name to append to. /// Full path to existent file to append to. /// Binary data chunk to append to. /// Path to file that was appended with chunk. public virtual string AppendTempFileBinaryChunk(string fileName, string path, byte[] chunk) { if (path == null) { path = Path.Combine(Path.GetTempPath(), fileName); if (FileUtils.FileExists(path)) { FileUtils.DeleteFile(path); } } FileUtils.AppendFileBinaryContent(path, chunk); return path; } public override bool IsInstalled() { return IsSharePointInstalled(); } /// /// Deletes service items that represent SharePoint site collection. /// /// Items to be deleted. public override void DeleteServiceItems(ServiceProviderItem[] items) { foreach (ServiceProviderItem item in items) { if (item is SharePointSiteCollection) { try { DeleteSiteCollection((SharePointSiteCollection)item); } catch (Exception ex) { Log.WriteError(String.Format("Error deleting '{0}' {1}", item.Name, item.GetType().Name), ex); } } } } /// /// Calculates diskspace used by supplied service items. /// /// Service items to get diskspace usage for. /// Calculated disk space usage statistics. public override ServiceProviderItemDiskSpace[] GetServiceItemsDiskSpace(ServiceProviderItem[] items) { List itemsDiskspace = new List(); // update items with diskspace foreach (ServiceProviderItem item in items) { if (item is SharePointSiteCollection) { try { Log.WriteStart(String.Format("Calculating '{0}' site logs size", item.Name)); SharePointSiteCollection site = GetSiteCollection(item.Name); ServiceProviderItemDiskSpace diskspace = new ServiceProviderItemDiskSpace(); diskspace.ItemId = item.Id; diskspace.DiskSpace = site.Diskspace; itemsDiskspace.Add(diskspace); Log.WriteEnd(String.Format("Calculating '{0}' site logs size", item.Name)); } catch (Exception ex) { Log.WriteError(ex); } } } return itemsDiskspace.ToArray(); } /// /// Checks whether Wss 3.0 is installed. /// /// true - if it is installed; false - otherwise. private bool IsSharePointInstalled() { RegistryKey spKey = Registry.LocalMachine.OpenSubKey(Wss3RegistryKey); RegistryKey spKey32 = Registry.LocalMachine.OpenSubKey(Wss3Registry32Key); if (spKey == null && spKey32 == null) { return false; } string spVal = (string)spKey.GetValue("SharePoint"); return (String.Compare(spVal, "installed", true) == 0); } /// /// Executes supplied action within separate application domain. /// /// Action to be executed. /// Any object that results from action execution or null if nothing is supposed to be returned. /// Is thrown in case supplied action is null. private static TReturn ExecuteSharePointAction(SharePointAction action) { if (action == null) { throw new ArgumentNullException("action"); } AppDomain domain = null; try { // Create instance of server implementation in a separate application domain for // security and isolation purposes. Type type = typeof(HostedSharePointServerImpl); AppDomainSetup info = new AppDomainSetup(); info.ApplicationBase = Path.GetDirectoryName(AppDomain.CurrentDomain.BaseDirectory); info.PrivateBinPath = "bin; bin/debug"; domain = AppDomain.CreateDomain("WSS30", null, info); HostedSharePointServerImpl impl = (HostedSharePointServerImpl) domain.CreateInstanceAndUnwrap(type.Assembly.FullName, type.FullName); // Execute requested action within created application domain. return action(impl); } finally { if (domain != null) { AppDomain.Unload(domain); } } } public void UpdateQuotas(string url, long maxStorage, long warningStorage) { ExecuteSharePointAction(delegate(HostedSharePointServerImpl impl) { impl.UpdateQuotas(RootWebApplicationUri, url, maxStorage, warningStorage); return null; }); } public SharePointSiteDiskSpace[] CalculateSiteCollectionsDiskSpace(string[] urls) { SharePointSiteDiskSpace[] sd = null; sd = ExecuteSharePointAction(delegate(HostedSharePointServerImpl impl) { return impl.CalculateSiteCollectionDiskSpace(RootWebApplicationUri, urls); }); return sd; } public long GetSiteCollectionSize(string url) { long ret; ret = ExecuteSharePointAction(delegate(HostedSharePointServerImpl impl) { return impl.GetSiteCollectionSize(RootWebApplicationUri, url); }); return ret; } public virtual void SetPeoplePickerOu(string site, string ou) { } } }