Skip to content

Instantly share code, notes, and snippets.

@TheWorstProgrammerEver
Created February 6, 2017 22:09
Show Gist options
  • Select an option

  • Save TheWorstProgrammerEver/45879f96b4870a19a0a57a87d18ed9c8 to your computer and use it in GitHub Desktop.

Select an option

Save TheWorstProgrammerEver/45879f96b4870a19a0a57a87d18ed9c8 to your computer and use it in GitHub Desktop.
Symantec Protection Engine - scan stream in chunks
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