Split Safety Mux/Dmux (MuD) .NET Integration Guide v1.0 v1.0 KNOWN ISSUES issue ID issue 1 Amazon cloud storage unimplemented. 2 Google cloud storage unimplemented. 3 edge cases (too-small files?) unexplored. Please inform us@splitsafety.com of other issues you encounter. 1. INSTALLATION Download SS_NET.zip and unzip. Install the DLLs - MuD.dll plus those needed to support Azure, Amazon, or Google cloud storage if you plan to use those as well as the file system - where your program can access it - in the bin subdirectory of your web app, or in the same directory as your offline executable. MuD.dll was built for .NET Framework 4; let us@splitsafety.com know if you need other versions. 2. CONFIGURATION For each user store, in config.txt in running directory or an ancestor, define .0, .1, and .2 to be a (F)ilesystem, (G)oogle, (A)mazon, or (M)icrosoft (Azure) store: #personal files backup to C: and Amazon & Google clouds: MyDocuments.0 F,C:\MuDStore\MyDocuments\0\{did} MyDocuments.1 A,,{did} #Amazon cloud MyDocuments.2 G,,{did} #Google cloud #work files backup - Azure and two thumb drives: MyFirm.0 M,DefaultEndpointsProtocol=https;AccountName=youraccountname;AccountKey=hugekey;EndpointSuffix=core.windows.net,backups,MyFirm/0/{did} MyFirm.1 F,E:\Mud\MyFirm\1\{did} #thumb drive E MyFirm.2 F,F:\Mud\MyFirm\2\{did} #thumb drive F Notes: - Key and value are first two tab-separated values in a config.txt line with one or tabs. - {did}, document ID, is a token for the relativepath passed in the API (see "API" below). 3. STANDARD API: Single Stream To / From Configured Stores using MuD; //requires MuD.dll using System.IO ; ... //DMUX a single file at relpath: string mytree = "C:\\MyFirm\\work\\" ; // tree to backup from / restore ro string relpath = "2020/TPSReport0505.docx" ; // sample file there ('/' or '\' OK) MDMWork.Dmuxer dmuxer = new MDMWork.Dmuxer( "MyFirm", relativepath ) ; if( dmuxer._err == null ) dmuxer.dmx( File.OpenRead( mytree + relpath ) ) ; // dmux passed stream into MyFirm stores 0,1,2 Console.Error.WriteLine( "Dmux into MyFirm stores 0,1,2, error=" + dmuxer._err ) ; Console.WriteLine( "Detach thumb drives or the bad guys can encrypt them too!" ) ; // and if you're paranoid, delete original so it can't be found if this computer hacked: File.Delete( mytree + relpath ) ; ... //Later that same century ... //Restore at relpath from stores 1 & 2 (thumb drives E & F): int [] aix = new int[]{ 1, 2 } ; // IDs of stores to mux MDMWork.Muxer muxer = new MDMWork.Muxer( "MyFirm", relpath, aix ) ; if( muxer._err == null ) muxer.mx( File.Create( mytree + relpath ) ) ; // restore into passed stream from MyFirm stores 1,2 Console.WriteLine( "Mux from 'MyFirm' stores 1,2 to " + File.Info( mytree + relpath ) + ", error=" + muxer._err ) ; ... //or alternatively ... //Restore stores 0 & 2 (Microsoft cloud storage and thumb drive F): aix[ 0 ] = 0 ; // IDs of stores to mux MDMWork.Muxer muxer = new MDMWork.Muxer( "MyFirm", relpath, aix ) ; if( muxer._err == null ) muxer.mx( File.Create( mytree + relpath ) ) ; // restore into passed stream from MyFirm stores 0,2 if( logger != null ){ logger.Close() ; logger = null ; } Console.WriteLine( "Mux from store 'MyFirm' stores 1,2 to " + File.Info( mytree + relpath ) + ", error=" + muxer._err ) ; ... 4. TEST API: Directly Dmux To / Mux From Unmanaged Streams using MuD; //requires MuD.dll using System.IO ; ... string path = "2020/", fil = "TPSReport0318.docx" ; Stream sors = File.OpenRead( mytree + path + fil ), dest0 = File.Create( mytree + path + fil + ".0" ), dest1 = File.Create( mytree + path + fil + ".1" ), dest2 = File.Create( mytree + path + fil + ".2" ) ; MDMWork.Dmuxer dmuxer = new MDMWork.Dmuxer( dest0, dest1, dest2 ) ; if( dmuxer._err == null ) dmuxer.dmx( sors ) ; // dmux passed stream into 3 dest streams // Later, restore from any 2 of those 3 into a recreation of original: Stream sors2 = File.OpenRead( mytree + path + fil + ".p2" ), sors0 = File.OpenRead( mytree + path + fil + ".p0" ), dest = File.Create( mytree + path + fil + ".re" ) ; MDMWork.Muxer muxer = new MDMWork.Muxer( sors2, sors0 ) ; if( muxer._err == null ) muxer.mx( dest) ; // restore into passed stream from 2 of 3 stores 5. TREE BROWSE AND MASS BACKUP/RESTORE Don't remember what you stored? A remote store can be walked; it's list() method returns an array of File-Or-Directory info: public class FordInfo{ public string Name ; public long Size ; public DateTime? LastMod ; } and for a FordInfo representing a directory (.isDir() true), it can be recursively list()ed: void walkDir( string store, int ix, string reldir, string indent ){ string error = null ; StorageConnector diroid = StorageConnector.getConnector( store, ix, reldir, out error ) ; FordInfo [] aFordInfo = diroid.list() ; foreach( FordInfo fordi in aFordInfo ){ Console.Write( "\n" + indent + fordi.Name + fordi.Date.ToString( ", yyyyMMdd HH:mm" ) ; if( fordi.Name.EndsWith( "/" ) ) walkDir( store, ix, reldir + fordi.Name, indent + " " ) ; else Console.Write( ", " + fordi.Size ) ; } } walkDir( "MyFirm", 1, "", "\n " ) ; // display files in MyFirm store 1 Recursion can also be used to backup an entire local tree, but it's much more efficient to ZIP the tree first.