private static byte[] GetCabDecodedAttachment(string DocTypeName, string DocTypeVer) { return(CacheMan.Cache(() => { Dictionary <string, string> DocKeys; const int SP1Header_Size = 20; const int FIXED_HEADER = 16; string attachmentName; byte[] reaponseFile = null; string DocSrc; object o = ServiceController.LuceneController.Get( out DocSrc, out DocKeys, "DOCREV", new Dictionary <string, string> { { "TargetDocTypeVer", DocTypeVer }, { "TargetDocTypeName", DocTypeName } }); if (o == null) { o = ServiceController.LuceneController.Get( out DocSrc, out DocKeys, "DOCREV", new Dictionary <string, string> { { "DocTypeVer", DocTypeVer }, { "DocTypeName", DocTypeName } }); } byte[] decodedAttachment = null; if (o != null) { IDocRev_Gen2 _IDocRev = (IDocRev_Gen2)o; using (MemoryStream ms = new MemoryStream(_IDocRev.TargetDocTypeFiles)) using (BinaryReader theReader = new BinaryReader(ms)) { //Position the reader to get the file size. byte[] headerData = new byte[FIXED_HEADER]; headerData = theReader.ReadBytes(headerData.Length); int fileSize = (int)theReader.ReadUInt32(); int attachmentNameLength = (int)theReader.ReadUInt32() * 2; byte[] fileNameBytes = theReader.ReadBytes(attachmentNameLength); //InfoPath uses UTF8 encoding. Encoding enc = Encoding.Unicode; //attachmentName = enc.GetString(fileNameBytes, 0, attachmentNameLength - 2); decodedAttachment = theReader.ReadBytes(fileSize); } } return decodedAttachment; }, false, "GetCabDecodedAttachment", DocTypeName, DocTypeVer)); }
/// <summary> /// Expects the directory to contain an infopath manifest.xsf & template.xml files. The contents are then persisted & /// indexed by DocTypeName & DocTypeRev (aka solutionVersion) for OpenStream & OpenText operations. As of this writing, /// this application must have write access to the parent folder of the given directory for cab compression operations. /// </summary> /// <param name="importFolderPath"></param> /// <param name="workingFolderPath">default is parent of importFolderPath</param> public static List <ImporterLightDoc> ImportContentFolder(string sourceFolderPath, string workingFolderPath = null) { List <ImporterLightDoc> List_ImporterLightDoc = new List <ImporterLightDoc>(); DirectoryInfo _DirectoryInfo = new DirectoryInfo(sourceFolderPath); if (workingFolderPath == null) { workingFolderPath = RequestPaths.GetPhysicalApplicationPath("import"); } //// ensure the import folder actually exists //Task.Factory.StartNew(() =>{ new DirectoryInfo(workingFolderPath) .mkdir() .Attributes = FileAttributes.NotContentIndexed | FileAttributes.Hidden; //}); string DocMD5, DocTypeVer; string DocTypeName = ScanContentFolder(_DirectoryInfo, out DocTypeVer, out DocMD5); if (!ServiceController.LuceneController.List(new List <string> { "DOCREV" }, null, null, DocMD5).Any()) { try { IList <string> relativeFilePathsInDirectoryTree = GetRelativeFilePathsInDirectoryTree(_DirectoryInfo.FullName, true); IDictionary <string, string> files = CreateStringDictionary(relativeFilePathsInDirectoryTree, relativeFilePathsInDirectoryTree); //the folder's contents compressed string cabFilePath = string.Format(@"{0}\{1}_{2}.cab", workingFolderPath, DocTypeName, FileSystem.CleanFileName(DocTypeVer)); Dictionary <string, string> DocIdKeys = new Dictionary <string, string> { { "TargetDocTypeName", DocTypeName }, { "TargetDocTypeVer", DocTypeVer } }; //TODO:Unit Test this! Generating in memory cab files has not been tested at all!!! using (CompressionEngine _CompressionEngine = new CabEngine { CompressionLevel = CompressionLevel.Max }) using (ArchiveMemoryStreamContext _ArchiveMemoryStreamContext = new ArchiveMemoryStreamContext(cabFilePath, sourceFolderPath, files) { EnableOffsetOpen = true }) using (MemoryStream _TargetDocTypeFilesMemoryStream = new MemoryStream()) { _CompressionEngine.Pack(_ArchiveMemoryStreamContext, files.Keys); string fileName = Path.GetFileName(cabFilePath); uint fileNameLength = (uint)fileName.Length + 1; byte[] fileNameBytes = Encoding.Unicode.GetBytes(fileName); using (MemoryStream CabFileMemoryStream = _ArchiveMemoryStreamContext.DictionaryStringMemoryStream.Values.First()) { CabFileMemoryStream.Position = 0; using (BinaryReader _BinaryReader = new BinaryReader(CabFileMemoryStream)) using (BinaryWriter _BinaryWriter = new BinaryWriter(_TargetDocTypeFilesMemoryStream)) { // Write the InfoPath attachment signature. _BinaryWriter.Write(new byte[] { 0xC7, 0x49, 0x46, 0x41 }); // Write the default header information. _BinaryWriter.Write((uint)0x14); // size _BinaryWriter.Write((uint)0x01); // version _BinaryWriter.Write((uint)0x00); // reserved // Write the file size. _BinaryWriter.Write((uint)_BinaryReader.BaseStream.Length); // Write the size of the file name. _BinaryWriter.Write(fileNameLength); // Write the file name (Unicode encoded). _BinaryWriter.Write(fileNameBytes); // Write the file name terminator. This is two nulls in Unicode. _BinaryWriter.Write(new byte[] { 0, 0 }); // Iterate through the file reading data and writing it to the outbuffer. byte[] data = new byte[64 * 1024]; int bytesRead = 1; while (bytesRead > 0) { bytesRead = _BinaryReader.Read(data, 0, data.Length); _BinaryWriter.Write(data, 0, bytesRead); } } // these contents will be stored in yet another document as an attached cab file IDocRev_Gen2 DocRevBaseDoc = (IDocRev_Gen2)DocInterpreter.Instance.Create("DOCREV"); DocRevBaseDoc.DocChecksum = int.MinValue; DocRevBaseDoc.DocIdKeys = DocIdKeys; DocRevBaseDoc.DocStatus = true; DocRevBaseDoc.DocTitle = String.Format("{0} {1}", DocTypeName, DocTypeVer); DocRevBaseDoc.DocTypeName = "DOCREV"; DocRevBaseDoc.TargetDocTypeFiles = _TargetDocTypeFilesMemoryStream.ToArray(); DocRevBaseDoc.TargetDocTypeName = DocTypeName; DocRevBaseDoc.TargetDocTypeVer = DocTypeVer; /* * BANDAID: DOCREV * (search for this though out the code for more on DOCREV snafus in general), * earlier implementations of DOCREV did not have a TargetDocMD5 property, the IDocRev must be compatible with all versions of this object */ foreach (PropertyInfo p in DocRevBaseDoc.GetType().GetProperties().Where(p => p.Name == "TargetDocMD5")) { p.SetValue(DocRevBaseDoc, DocMD5, null); } List_ImporterLightDoc.Add( new ImporterLightDoc { LightDoc = ServiceController.Instance.Import(DocRevBaseDoc.GetDocData()) }); } } } catch (ThreadAbortException) { } }