123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576 |
- // SNFMultiDLL.cpp
- // Copyright (C) ARM Research Labs, LLC
- //
- // Provides a full SNFMulti engine with dynamic scanner allocation.
-
- #include <windows.h>
- #include <stdexcept>
- #include <cmath>
- #include "../SNFMulti/snfmulti.hpp"
-
- using namespace std;
-
- const char* SNF_DLL_VERSION = "SNFMulti DLL Version 3.0 Build: " __DATE__ " " __TIME__;
-
- const int snf_ERROR_NO_HANDLE = -1;
- const int snf_ERROR_SCAN_FAILED = -2;
- const int snf_ERROR_EXCEPTION = -3;
-
- const double snf_ReputationMehResult = 0.0; /* Don't know or don't care */
- const double snf_ReputationBadResult = 1.0; /* IP is pure evil */
- const double snf_ReputationGoodResult = -1.0; /* IP is pure good */
-
- ////////////////////////////////////////////////////////////////////////////////
- // Here we define the interface provided by this DLL.
-
- #define EXP __declspec(dllexport)
- extern "C" {
-
- BOOL WINAPI DllMain ( HINSTANCE hInst, DWORD wDataSeg, LPVOID lpvReserved ); // Main DLL setup function.
-
- EXP int setThrottle(int Threads); // Set scan thread limit.
- EXP int startupSNF(char* Path); // Start SNF with configuration.
- EXP int startupSNFAuthenticated(char* Path, char* Lic, char* Auth); // Start SNF with conf & auth.
- EXP int shutdownSNF(); // Shutdown SNF.
- EXP int testIP(unsigned long int IPToCheck); // Test the IP for a GBUdb range.
- EXP double getIPReputation(unsigned long int IPToCheck); // Get reputation figure for IP.
- EXP int scanBuffer(unsigned char* Bfr, int Length, char* Name, int Setup); // Scan msgBuffer, name, setup time.
- EXP int scanFile(char* FilePath, int Setup); // Scan msgFile, setup time.
- EXP int getScanXHeaders(int ScanHandle, char** Bfr, int* Length); // Get result & XHeaders.
- EXP int getScanXMLLog(int ScanHandle, char** Bfr, int* Length); // Get result & XML Log.
- EXP int getScanClassicLog(int ScanHandle, char** Bfr, int* Length); // Get result & Classic Log.
- EXP int getScanResult(int ScanHandle); // Get just the scan result.
- EXP int closeScan(int ScanHandle); // Close the scan result.
-
- }
-
- ////////////////////////////////////////////////////////////////////////////////
- // Here are the guts of the engine.
- //
-
- // A ScannerInstance encapsulates an snf_EngineHandler and buffers for the
- // scan results. The buffers can safely be passed back to the calling app.
-
- class ScannerInstance : public snf_EngineHandler { // Scanner Instance.
- private:
- int Ordinal; // Instance ordinal.
- int ScanResult; // Current scan result.
-
- string ScanXHeaders; // Buffered X-Headers.
- char* ScanXHeadersPtr; // Buffered X-Headers pointer.
- int ScanXHeadersLength; // Buffered X-Headers length.
-
- string ScanXMLLog; // Buffered XML Log.
- char* ScanXMLLogPtr; // Buffered XML Log pointer.
- int ScanXMLLogLength; // Buffered XML Log length.
-
- string ScanClassicLog; // Buffered Classic Log.
- char* ScanClassicLogPtr; // Buffered Classic Log pointer.
- int ScanClassicLogLength; // Buffered Classic Log length.
-
- void clearBuffers(); // Clears the buffers & result.
-
- public:
- ScannerInstance(snf_RulebaseHandler* RBH, int N); // Initialize w/ Rulebase & Ordinal
- ~ScannerInstance(); // Cleanup before going away.
- int scanBuffer(unsigned char* Bfr, int Length, char* Name, int Setup); // Scan message buffer, give handle.
- int scanFile(char* FilePath, int Setup); // Scan message file, give handle.
- int getScanXHeaders(char** Bfr, int* Length); // Return scan result & X headers.
- int getScanXMLLog(char** Bfr, int* Length); // Return scan result & XML log.
- int getScanClassicLog(char** Bfr, int* Length); // Return scan result & Classic log.
- int getScanResult(); // Return scan result.
- };
-
- const int XHeaderReserve = 4096; // Space to reserve for X headers.
- const int XMLLogReserve = 4096; // Space to reserve for XML log data.
- const int ClassicReserve = 4096; // Space to reserve for Classic log data.
-
- ScannerInstance::ScannerInstance(snf_RulebaseHandler* RBH, int N) : // Initialize.
- Ordinal(N), // Ordinal as assigned.
- ScanResult(snf_ERROR_UNKNOWN), // No good result yet.
- ScanXHeaders(0,XHeaderReserve), // Pre-allocate some space for our
- ScanXMLLog(0, XMLLogReserve), // result caching buffers (strings)
- ScanClassicLog(0, ClassicReserve) { // so we might not have to later.
- clearBuffers(); // Clear the buffers.
- open(RBH); // Open the engine handler.
- }
-
- ScannerInstance::~ScannerInstance() { // When shutting down
- close(); // close the engine handler
- clearBuffers(); // and clear the buffers.
- Ordinal = -1; // Invalidate our handle.
- }
-
- // In the C world, 0 cannot be a handle, so when we return a "handle" from
- // our scanXX() methods we must convert the scanner's ordinal into a "handle"
- // by adding 1. Later on when we get a scanner by it's handle, that function
- // reverses the conversion by subtracting 1 from the handle to get the ordinal.
-
- int ScannerInstance::
- scanBuffer(unsigned char* Bfr, int Length, char* Name, int Setup) { // Scan a message buffer.
- try { // Prepare to capture exceptions.
- clearBuffers(); // Clear the buffers first.
- ScanResult = scanMessage(Bfr, Length, Name, Setup); // Scan and capture the result.
- } // Translate exceptions into
- catch(snf_EngineHandler::FileError& e) { // result codes and capture them.
- ScanResult = snf_ERROR_MSG_FILE;
- }
- catch(snf_EngineHandler::XHDRError& e) {
- ScanResult = snf_ERROR_MSG_FILE;
- }
- catch(snf_EngineHandler::BadMatrix& e) {
- ScanResult = snf_ERROR_BAD_MATRIX;
- }
- catch(snf_EngineHandler::MaxEvals& e) {
- ScanResult = snf_ERROR_MAX_EVALS;
- }
- catch(snf_EngineHandler::AllocationError& e) {
- ScanResult = snf_ERROR_ALLOCATION;
- }
- catch(...) {
- ScanResult = snf_ERROR_UNKNOWN;
- }
- return (Ordinal + 1); // Return our handle.
- }
-
- int ScannerInstance::
- scanFile(char* FilePath, int Setup) { // Scan a message file.
- try { // Prepare to capture exceptions.
- clearBuffers(); // Clear the buffers first.
- ScanResult = scanMessageFile(FilePath, Setup); // Scan and capture the result.
- } // Translate exceptions into
- catch(snf_EngineHandler::FileError& e) { // result codes and capture them.
- ScanResult = snf_ERROR_MSG_FILE;
- }
- catch(snf_EngineHandler::XHDRError& e) {
- ScanResult = snf_ERROR_MSG_FILE;
- }
- catch(snf_EngineHandler::BadMatrix& e) {
- ScanResult = snf_ERROR_BAD_MATRIX;
- }
- catch(snf_EngineHandler::MaxEvals& e) {
- ScanResult = snf_ERROR_MAX_EVALS;
- }
- catch(snf_EngineHandler::AllocationError& e) {
- ScanResult = snf_ERROR_ALLOCATION;
- }
- catch(...) {
- ScanResult = snf_ERROR_UNKNOWN;
- }
- return (Ordinal + 1); // Return our handle.
- }
-
- void ScannerInstance::clearBuffers() { // Clear the buffers.
- ScanXHeaders.clear(); // Clear the buffer strings
- ScanXHeadersPtr = 0; // zero their pointers and
- ScanXHeadersLength = 0; // zero their lengths.
-
- ScanXMLLog.clear();
- ScanXMLLogPtr = 0;
- ScanXMLLogLength = 0;
-
- ScanClassicLog.clear();
- ScanClassicLogPtr = 0;
- ScanClassicLogLength = 0;
-
- ScanResult = snf_ERROR_UNKNOWN;
- }
-
- int ScannerInstance::getScanXHeaders(char** Bfr, int* Length) { // Return the result & X headers.
- if(0 == ScanXHeadersPtr) { // If we haven't already then
- ScanXHeaders = getXHDRs(); // capture the data.
- ScanXHeadersLength = ScanXHeaders.length();
- ScanXHeadersPtr = const_cast<char*>(ScanXHeaders.c_str());
- }
- *Bfr = ScanXHeadersPtr; // Pass the pointer and
- *Length = ScanXHeadersLength; // length back to the caller.
- return ScanResult; // Return the scan result.
- }
-
- int ScannerInstance::getScanXMLLog(char** Bfr, int* Length) { // Return the result & XML log.
- if(0 == ScanXMLLogPtr) { // If we haven't already then
- ScanXMLLog = getXMLLog(); // capture the data.
- ScanXMLLogPtr = const_cast<char*>(ScanXMLLog.c_str());
- ScanXMLLogLength = ScanXMLLog.length();
- }
- *Bfr = ScanXMLLogPtr; // Pass the pointer and
- *Length = ScanXMLLogLength; // length back to the caller.
- return ScanResult; // Return the scan result.
- }
-
- int ScannerInstance::getScanClassicLog(char** Bfr, int* Length) { // Return the result & Classic log.
- if(0 == ScanClassicLogPtr) { // If we haven't already then
- ScanClassicLog = getClassicLog(); // capture the data.
- ScanClassicLogPtr = const_cast<char*>(ScanClassicLog.c_str());
- ScanClassicLogLength = ScanClassicLog.length();
- }
- *Bfr = ScanClassicLogPtr; // Pass the pointer and
- *Length = ScanClassicLogLength; // length back to the caller.
- return ScanResult; // Return the scan result.
- }
-
- int ScannerInstance::getScanResult() { // Return the scan result only.
- return ScanResult; // Just like that.
- }
-
- // The snfScannerPool starts up and shuts down the rulebase engine and keeps
- // track of the ScannerInstances.
-
- class snfScannerPool { // Dynamically allocated scanner pool.
- private:
- codedweller::Mutex myMutex; // Protect the state of the pool.
- snf_RulebaseHandler* myRulebaseHandler; // This is our rulebase manager.
- vector<ScannerInstance*> ScannerPool; // This is a collection of scanners.
- codedweller::ProductionQueue<ScannerInstance*> AvailableScanners; // This is the available scanners queue.
- unsigned int ScanThreadLimit; // Maximum number of concurrent threads.
-
- public:
- snfScannerPool(); // This is how we are constructed.
- ~snfScannerPool(); // This is how we are destroyed.
- void Throttle(int ThreadLimit); // Set a Scan Thread Limit.
- void startup(char* ConfigurationPath); // Startup the engine w/ config.
- void startupAuthenticated(char* Path, char* Lic, char* Auth); // Startup engine w/ full auth.
- void shutdown(); // Shutdown the engine.
- int testIP(unsigned long int IPToCheck); // Test an IP against gbudb.
- double getIPReputation(unsigned long int IPToCheck); // This is how we get IP reps.
- ScannerInstance* grabScanner(); // Get a new (available) scanner.
- ScannerInstance* getScanner(int ScanHandle); // What scanner goes with this handle?
- void dropScanner(ScannerInstance* S); // When done with a scanner, drop it.
- };
-
- snfScannerPool Scanners; // Call our local pool "Scanners".
-
- snfScannerPool::snfScannerPool() : // When created, our
- myRulebaseHandler(0), // rulebase handler is 0.
- ScanThreadLimit(0) {} // There is no limit.
-
- snfScannerPool::~snfScannerPool() { // When destroyed we must
- shutdown(); // shutdown if needed.
- }
-
- void snfScannerPool::Throttle(int ThreadLimit) { // Set a scanner thread limit.
- ThreadLimit = (0 > ThreadLimit) ? 0 : ThreadLimit; // Throttle will be 0 or above.
- ScanThreadLimit = ThreadLimit;
- }
-
- void snfScannerPool::startup(char* ConfigurationPath) { // Start the engine with this config.
- codedweller::ScopeMutex StateIsInFlux(myMutex); // Protect our state data.
- if(myRulebaseHandler) return; // If we are started, do nothing.
- myRulebaseHandler = new snf_RulebaseHandler(); // Create a new rulebase handler.
- myRulebaseHandler->PlatformVersion(SNF_DLL_VERSION); // Record our version identification.
- myRulebaseHandler->open(ConfigurationPath, "", ""); // Open the rulebase with the config.
- }
-
- void snfScannerPool::startupAuthenticated(char* Path, char* Lic, char* Auth) { // Startup engine w/ full auth.
- codedweller::ScopeMutex StateIsInFlux(myMutex); // Protect our state data.
- if(myRulebaseHandler) return; // If we are started, do nothing.
- myRulebaseHandler = new snf_RulebaseHandler(); // Create a new rulebase handler.
- myRulebaseHandler->PlatformVersion(SNF_DLL_VERSION); // Record our version identification.
- myRulebaseHandler->open(Path, Lic, Auth); // Open rulebase with full auth.
- }
-
- void snfScannerPool::shutdown() { // Shutdown the engine.
- codedweller::ScopeMutex StateIsInFlux(myMutex); // Protect our state data.
- if(
- 0 == ScannerPool.size() &&
- 0 == AvailableScanners.size() &&
- 0 == myRulebaseHandler
- ) return; // If we are down don't bother.
-
- if(ScannerPool.size() != AvailableScanners.size()) throw false; // If some scanners are in use throw!
-
- for(
- vector<ScannerInstance*>::iterator iS = ScannerPool.begin(); // Destroy all of the scanner
- iS != ScannerPool.end(); // instances in the pool.
- iS++) delete (*iS);
-
- ScannerPool.clear(); // Empty the pool of pointers.
-
- while(0 < AvailableScanners.size()) AvailableScanners.take(); // Empty the available scanners.
- if(myRulebaseHandler) { // Safely destroy the rulebase handler.
- myRulebaseHandler->close(); // Close it first,
- delete myRulebaseHandler; // then delete it,
- myRulebaseHandler = 0; // then forget about it.
- }
- }
-
- int snfScannerPool::testIP(unsigned long int IPToCheck) { // This is how we test IPs.
- codedweller::ScopeMutex StayAsYouAre(myMutex); // Hold things steady while we do this.
- if(0 == myRulebaseHandler) return snf_ERROR_NO_HANDLE; // If we have no engine, punt!
- IPTestRecord Tester(IPToCheck); // Make up a test record for this IP.
- myRulebaseHandler->performIPTest(Tester); // Run it past the engine.
- return Tester.R; // IPRange is an enum, so use as an int.
- }
-
- double snfScannerPool::getIPReputation(unsigned long int IPToCheck) { // This is how we get IP reps.
- codedweller::ScopeMutex StayAsYouAre(myMutex); // Hold things steady while we do this.
- if(0 == myRulebaseHandler) return snf_ERROR_NO_HANDLE; // If we have no engine, punt!
- IPTestRecord Tester(IPToCheck); // Make up a test record for this IP.
- myRulebaseHandler->performIPTest(Tester); // Run it past the engine.
-
- // Now that we have a result from the engine let's translate the result.
-
- double Reputation = snf_ReputationMehResult; // Reputation figures are precise.
- switch(Tester.G.Flag()) { // Flags get priority in our translation.
- case Good: Reputation = snf_ReputationGoodResult; break; // A good flag means the IP is pure good.
- case Bad: Reputation = snf_ReputationBadResult; break; // A bad flag means the IP is pure evil.
- case Ignore: Reputation = snf_ReputationMehResult; break; // An ignore flag means we don't care.
- default: { // Ugly means we calculate the reputation
- Reputation = // figure from the statistics. Start by
- sqrt(fabs(Tester.G.Probability() * Tester.G.Confidence())); // combining the c & p figures then
- if(0 > Tester.G.Probability()) Reputation *= -1.0; // flip the sign if p is negative.
- }
- }
- return Reputation; // This is what we say about this IP.
- }
-
- // In order to balance off speed and safety we control access when starting
- // up, shutting down, or getting a new scanner. The grabScanner operation is
- // usually very fast.
- //
- // The the calling application behaves properly it will never attempt a scan
- // while attempting to shutdown, and will never attempt to shutdown while it
- // is performing a scan. If this conflict does occur then one of two cases
- // arise:
- //
- // The shutdown() thread grabs the mutex before the grabScanner() thread,
- // the engine is shutdown, then the grabScanner() thread finds the engine
- // is down and cannot return a scanner.
- //
- // The grabScanner() thread gets the mutex before the shutdown() thread,
- // a scanner is allocated, and the shutdown() thread discovers an imabalance
- // in the number of Available scanners and the number of scanners in the pool.
- // When it discovers that it will throw false and the C interface function will
- // return an error.
-
- ScannerInstance* snfScannerPool::grabScanner() { // Get the next available scanner.
- codedweller::ScopeMutex FreezeOurState(myMutex); // Don't change while I'm doing this.
- if(0 == myRulebaseHandler) return 0; // If we're not alive return nothing.
- if(1 > AvailableScanners.size()) { // No scanners? See about making one.
- if(
- 0 == ScanThreadLimit || // If there is no limit OR
- ScanThreadLimit > ScannerPool.size() // we have room for more scanners
- ) { // then we can make another one:
- ScannerInstance* NewScanner =
- new ScannerInstance(myRulebaseHandler, ScannerPool.size()); // Start up a new scanner and
- ScannerPool.push_back(NewScanner); // add it to the pool.
- AvailableScanners.give(NewScanner); // Make the new scanner available.
- } // If we have reached the limit on
- } // scanners we will wait for one.
-
- return AvailableScanners.take(); // Get a scanner from the pool.
- }
-
- // Since handles are one bigger than the ordinal (so 0 isn't a handle)
- // we must convert the ScanHandle we're given into a proper ordinal so
- // we can match the scanner's position in the pool. The reverse happens
- // upon scan requestes.
-
- ScannerInstance* snfScannerPool::getScanner(int ScanHandle) { // Get the scanner for this handle.
- ScannerInstance* S = 0; // We're gonna get a scanner.
- try { S = ScannerPool.at(ScanHandle - 1); } // Safely get the scanner at Ordinal.
- catch(...) { return 0; } // If something goes wrong, no scanner.
- return S; // Return the scanner we got.
- }
-
- void snfScannerPool::dropScanner(ScannerInstance* S) { // When done with a scanner, drop it.
- if( // If :
- 0 != S && // - we have a good scanner pointer and
- 0 != myRulebaseHandler // - we are not dead yet
- ) AvailableScanners.give(S); // then make the scanner available.
- }
-
-
- ////////////////////////////////////////////////////////////////////////////////
- // Interface Functions
-
- BOOL WINAPI DLLMain ( HINSTANCE hInst, DWORD wDataSeg, LPVOID lpvReserved ) {
- try {
- switch(wDataSeg) { // Handle setup & teardown msgs.
-
- case DLL_PROCESS_ATTACH: // If the DLL is being loaded
- return true; // return true. Nothing to do yet.
- break;
-
- case DLL_PROCESS_DETACH: // If the DLL is being dropped
- Scanners.shutdown(); // be sure we are shut down first.
- break;
-
- default: // For all other messages (thread stuff)
- return true; // we'll just return ok because
- break; // we don't have any of that here.
-
- }
- }
- catch(...) {}; // Do not throw exceptions.
- // We won't actually get here but we
- return false; // want to make the compiler happy :-)
- }
-
- EXP int setThrottle(int Threads) { // Set scan thread limit.
- try {
- Scanners.Throttle(Threads); // Set the throttle limit
- }
- catch(...) { return snf_ERROR_EXCEPTION; }
- return Threads; // and return the value.
- }
-
- EXP int startupSNF(char* Path) { // Start the engine.
- try { // Use a try block to translate
- Scanners.startup(Path); // exceptions into result codes.
- }
- catch(snf_RulebaseHandler::AuthenticationError &e) { // Catch and translage exceptions.
- return snf_ERROR_RULE_AUTH;
- }
- catch(snf_RulebaseHandler::AllocationError& e) {
- return snf_ERROR_ALLOCATION;
- }
- catch(snf_RulebaseHandler::FileError& e) {
- return snf_ERROR_RULE_FILE;
- }
- catch(...) {
- return snf_ERROR_EXCEPTION;
- }
- return snf_SUCCESS; // No exceptions, All happy :-)
- }
-
- EXP int startupSNFAuthenticated(char* Path, char* Lic, char* Auth) { // Start SNF with conf & auth.
- try { // Use a try block to translate
- Scanners.startupAuthenticated(Path, Lic, Auth); // exceptions into result codes.
- }
- catch(snf_RulebaseHandler::AuthenticationError &e) { // Catch and translage exceptions.
- return snf_ERROR_RULE_AUTH;
- }
- catch(snf_RulebaseHandler::AllocationError& e) {
- return snf_ERROR_ALLOCATION;
- }
- catch(snf_RulebaseHandler::FileError& e) {
- return snf_ERROR_RULE_FILE;
- }
- catch(...) {
- return snf_ERROR_EXCEPTION;
- }
- return snf_SUCCESS; // No exceptions, All happy :-)
- }
-
- EXP int shutdownSNF() { // Shut down the engine.
- try { // Use a try block to translate
- Scanners.shutdown(); // exceptions into result codes.
- }
- catch(snf_RulebaseHandler::AuthenticationError &e) { // Catch and translage exceptions.
- return snf_ERROR_RULE_AUTH;
- }
- catch(snf_RulebaseHandler::AllocationError& e) {
- return snf_ERROR_ALLOCATION;
- }
- catch(snf_RulebaseHandler::FileError& e) {
- return snf_ERROR_RULE_FILE;
- }
- catch(...) {
- return snf_ERROR_EXCEPTION;
- }
- return snf_SUCCESS; // No exceptions, All happy :-)
- }
-
- EXP int testIP(unsigned long int IPToCheck) { // Test the IP for a GBUdb range.
- int Result = snf_ERROR_EXCEPTION; // On panics return this.
- try {
- Result = Scanners.testIP(IPToCheck); // Testing an IP is easy.
- }
- catch(...) {} // Do not throw exceptions.
- return Result; // Return the result.
- }
-
- EXP double getIPReputation(unsigned long int IPToCheck) { // Get reputation figure for IP.
- double Result = snf_ReputationMehResult; // On panics return this.
- try {
- Result = Scanners.getIPReputation(IPToCheck); // Getting an IP rep is easy.
- }
- catch(...) {} // Do not throw exceptions.
- return Result; // Return the result.
- }
-
- EXP int scanBuffer(unsigned char* Bfr, int Length, char* Name, int Setup) { // Scan a message.
- ScannerInstance* myScanner = 0; // We need a scanner.
- try { myScanner = Scanners.grabScanner(); } // Safely get a scanner.
- catch(...) { return snf_ERROR_NO_HANDLE; } // If that fails, we're done.
-
- int ScannerHandle = snf_ERROR_NO_HANDLE; // We will return a handle.
- try { ScannerHandle = myScanner->scanBuffer(Bfr, Length, Name, Setup); } // Perform the scan.
- catch(...) { // If we get an unhandled
- Scanners.dropScanner(myScanner); // exception then drop the
- return snf_ERROR_SCAN_FAILED; // scanner and return the failure.
- } // If all goes well then
- return ScannerHandle; // return our scanner's handle.
- }
-
- EXP int scanFile(char* FilePath, int Setup) {
- ScannerInstance* myScanner = 0; // We need a scanner.
- try { myScanner = Scanners.grabScanner(); } // Safely get a scanner.
- catch(...) { return snf_ERROR_NO_HANDLE; } // If that fails, we're done.
-
- int ScannerHandle = snf_ERROR_NO_HANDLE; // We will return a handle.
- try { ScannerHandle = myScanner->scanFile(FilePath, Setup); } // Perform the scan.
- catch(...) { // If we get an unhandled
- Scanners.dropScanner(myScanner); // exception then drop the
- return snf_ERROR_SCAN_FAILED; // scanner and return the failure.
- } // If all goes well then
- return ScannerHandle; // return our scanner's handle.
- }
-
- EXP int getScanXHeaders(int ScanHandle, char** Bfr, int* Length) { // Return the XHeaders for a scan.
- ScannerInstance* myScanner = 0; // We need the scanner.
- try { myScanner = Scanners.getScanner(ScanHandle); } // Try to get the scanner by handle.
- catch(...) { return snf_ERROR_NO_HANDLE; } // If we can't, we're broken.
- if(0 == myScanner) return snf_ERROR_NO_HANDLE; // A zero pointer is also broken.
- int Result = snf_ERROR_EXCEPTION; // On panic return this error code.
- try {
- Result = myScanner->getScanXHeaders(Bfr, Length); // If we can, get our data.
- }
- catch(...) {} // Do not throw exceptions.
- return Result; // Return our result.
- }
-
- EXP int getScanXMLLog(int ScanHandle, char** Bfr, int* Length) { // Return the XML Log for a scan.
- ScannerInstance* myScanner = 0; // We need the scanner.
- try { myScanner = Scanners.getScanner(ScanHandle); } // Try to get the scanner by handle.
- catch(...) { return snf_ERROR_NO_HANDLE; } // If we can't, we're broken.
- if(0 == myScanner) return snf_ERROR_NO_HANDLE; // A zero pointer is also broken.
- int Result = snf_ERROR_EXCEPTION; // On panic return this error code.
- try {
- Result = myScanner->getScanXMLLog(Bfr, Length); // If we can, get our data.
- }
- catch(...) {} // Do not throw exceptions.
- return Result; // Return our result.
- }
-
- EXP int getScanClassicLog(int ScanHandle, char** Bfr, int* Length) { // Return the classic log for a scan.
- ScannerInstance* myScanner = 0; // We need the scanner.
- try { myScanner = Scanners.getScanner(ScanHandle); } // Try to get the scanner by handle.
- catch(...) { return snf_ERROR_NO_HANDLE; } // If we can't we're broken.
- if(0 == myScanner) return snf_ERROR_NO_HANDLE; // A zero pointer is also broken.
- int Result = snf_ERROR_EXCEPTION; // On panic return this error code.
- try {
- Result = myScanner->getScanClassicLog(Bfr, Length); // If we can, get our data.
- }
- catch(...) {} // Do not throw exceptions.
- return Result; // Return our result.
- }
-
- EXP int getScanResult(int ScanHandle) { // Return just the scan result.
- ScannerInstance* myScanner = 0; // We need the scanner.
- try { myScanner = Scanners.getScanner(ScanHandle); } // Try to get the scanner by handle.
- catch(...) { return snf_ERROR_NO_HANDLE; } // If we can't we're broken.
- if(0 == myScanner) return snf_ERROR_NO_HANDLE; // A zero pointer is also broken.
- return myScanner->getScanResult(); // If we can, get our data.
- }
-
- EXP int closeScan(int ScanHandle) { // Return the scanner to the pool.
- ScannerInstance* myScanner = 0; // We need the scanner.
- try { myScanner = Scanners.getScanner(ScanHandle); } // Try to get the scanner by handle.
- catch(...) { return snf_ERROR_NO_HANDLE; } // If we can't we're broken.
- if(0 == myScanner) return snf_ERROR_NO_HANDLE; // A zero pointer is also broken.
- try { Scanners.dropScanner(myScanner); } // If we can then drop the scanner.
- catch(...) { return snf_ERROR_EXCEPTION; } // Convert exceptions to a panic code.
- return snf_SUCCESS; // If all ok then return success.
- }
|