Created
February 6, 2017 22:09
-
-
Save TheWorstProgrammerEver/45879f96b4870a19a0a57a87d18ed9c8 to your computer and use it in GitHub Desktop.
Symantec Protection Engine - scan stream in chunks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using System; | |
| using System.Collections.Generic; | |
| using System.IO; | |
| using System.Linq; | |
| using System.Text; | |
| //------------------------------------------------------- | |
| // You'll need this thing from Symantec! | |
| //------------------------------------------------------- | |
| using com.symantec.scanengine.api; | |
| namespace SymantecProtectionEngine | |
| { | |
| public class Scanner | |
| { | |
| private readonly ScanRequestManager _requestManager; | |
| public Scanner(string host, int port) | |
| { | |
| _requestManager = new ScanRequestManager(); | |
| var scanEngines = new[] | |
| { | |
| new ScanEngineInfo(host, port) | |
| }.ToList(); | |
| _requestManager.PrepareForScan(scanEngines, | |
| 30000, // This becomes a timeout on the socket doing reads / writes. | |
| 5 // This is used in their weird scheduling/load-balancing algorithm. Looks like the number of seconds to wait until reusing a connection. | |
| ); | |
| } | |
| public ScanResult Scan(string fileName, Stream stream) | |
| { | |
| var scanRequest = _requestManager.CreateStreamScanRequest(Policy.SCAN); | |
| scanRequest.Start(fileName, fileName); | |
| // Symantec's demo code chunked up the files. I guess it makes sense if the files are... big. | |
| const int arbitraryChunkThreshold = 512; | |
| var chunkSize = (int)Math.Min(arbitraryChunkThreshold, stream.Length); | |
| if (!Chunk(stream, chunkSize).All(scanRequest.Send)) | |
| { | |
| throw new Exception("Something bad happened and I don't know how to find out what it was."); | |
| } | |
| // I think you can get Symantec to [try to] repair the file, so you'll probably get | |
| // that back in the result stream if you use a Policy.*REPAIR. | |
| // I'm just passing a new memory stream 'cause I don't care about it. | |
| return scanRequest.Finish(new MemoryStream()); | |
| } | |
| private static IEnumerable<byte[]> Chunk(Stream stream, int chunkSize) | |
| { | |
| using (var binaryReader = new BinaryReader(stream, Encoding.UTF8, true)) | |
| { | |
| var remaining = stream.Length; | |
| while (remaining > 0) | |
| { | |
| var buffer = new byte[Math.Min(remaining, chunkSize)]; | |
| var numberOfBytesRead = binaryReader.Read(buffer, 0, buffer.Length); | |
| remaining -= numberOfBytesRead; | |
| yield return buffer; | |
| } | |
| } | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment