EldoS | Feel safer!

Software components for data protection, secure storage and transfer

Can't get OnPostReadFileCallback to work

Also by EldoS: CallbackProcess
A component to control process creation and termination in Windows and .NET applications.
#20126
Posted: 05/11/2012 13:47:00
by Andy Hickmott (Basic support level)
Joined: 03/27/2012
Posts: 9

I haven't been able to get a callback set with SetOnPostReadFileC to trigger at all. SetOnReadFileC works quite well. I'm guessing there's something I'm not setting correctly. Here's the pared-down code; when I look at the file being watched (by COPYing it to another file from CMD), readFileWrapper is called repeatedly, but postReadFileWrapper is never called.

'file' is a single fully specified filename rooted at C:\ with no wildcards, SetProcessCachedReadWriteCallbacks is TRUE, if that matters. In my test case, these are the only callbacks I'm setting up.


[The usual status and install checks...]

m_filter->SetOnPostReadFileC(&postReadFileWrapper);
m_filter->SetOnReadFileC(&readFileWrapper);

m_filter->AddFilterCallbackRule(
file.c_str(),
CallbackFilter::CbFltCallbackFlags(
CallbackFilter::PostReadCallback | CallbackFilter::ReadCallback
)
);

m_filter->AttachFilter(10000);
#20127
Posted: 05/11/2012 15:23:58
by Vladimir Cherniga (EldoS Corp.)

What do you do in readFileWrapper ?
#20128
Posted: 05/11/2012 15:39:43
by Andy Hickmott (Basic support level)
Joined: 03/27/2012
Posts: 9

At the moment, I'm just logging to std::cout. It'll get more complicated later. The routines called by readFileWrapper and postReadFileWrapper are currently identical except one logs "Read" and one logs "Post-read". I've also tried a breakpoint at the very top of each routine. The one in readFileWrapper gets hit; the one in postReadFileWrapper doesn't.
#20129
Posted: 05/11/2012 15:44:03
by Andy Hickmott (Basic support level)
Joined: 03/27/2012
Posts: 9

Oh, in case it matters, this is the version line from changes.txt in the library directory:

CallbackFilter - Version 2.3.46 - Released January 18, 2012
#20130
Posted: 05/11/2012 16:43:36
by Vladimir Cherniga (EldoS Corp.)

Make sure that your readFileWrapper callback routine doesn't raise any type of exception. Force ProcessRequest variable to be set in TRUE. We will try to reproduce the problem. Are there any special steps needed in order to get the same results ?
#20134
Posted: 05/14/2012 09:11:19
by Andy Hickmott (Basic support level)
Joined: 03/27/2012
Posts: 9

I've tried using an empty readFileWrapper, and I've tried only enabling postReadFileWrapper (i.e. no call to SetOnReadFileC, and AddFilterCallbackRule called with just CallbackFilter::PostReadCallback). It still doesn't call postReadFileWrapper.

ProcessRequest is the same as RequestAccepted in the C++ function signatures, right? Forcing *RequestAccepted to TRUE in readFileWrapper doesn't seem to make any difference.
#20143
Posted: 05/14/2012 13:43:53
by Andy Hickmott (Basic support level)
Joined: 03/27/2012
Posts: 9

If it would help, I've got a short program (~160 total, with comments) that does nothing but show the problem.
#20144
Posted: 05/14/2012 15:10:18
by Vladimir Cherniga (EldoS Corp.)

Quote
If it would help, I've got a short program (~160 total, with comments) that does nothing but show the problem.

Yes, sure. I've tried to reproduce the problem using modified encrypt sample, but it works without objections.
#20145
Posted: 05/14/2012 15:19:26
by Andy Hickmott (Basic support level)
Joined: 03/27/2012
Posts: 9

Here 'tis. I'm hoping you'll take one look at it and point out my obvious error.

Code
//
// Stand-alone program to show the problem I'm having with SetOnPostReadFileC.
// As written, prints a '.' to std::cout on the read callback, and should
// print a '!' on postread.
//
// To use, create a big file called C:\TMP\BIGFILE.DAT. I'm using one that's 6GB,
// to make sure that it can't be entirely cached. Run it. You'll need to run it
// as administrator at least once to install the filter driver. While it's
// running, open a CMD window and COPY C:\TMP\BIGFILE.DAT C:\TMP\BIGFILE.COPY .
// It should print a row of mixed '.' and '!'; in fact, it just prints '.' .
//
// I'm using Visual C++ 2008 and Windows 7 Home Premium.
//

#include "windows.h"
#include <tchar.h>
#include <iostream>
#include "CbFlt.h"


const CHAR EldoSTrialKey[]
      = "A long hex string that shouldn't be posted on the forums";

const CHAR ProductName[]
      = "ReadTest_Filter";

const WCHAR DriverFileName[]
      = L"C:\\Program Files\\EldoS\\CallbackFilter\\Drivers\\debug\\32bit\\cbfltfs.sys";

const WCHAR FileToWatch[]
      = L"C:\\TMP\\BIGFILE.DAT";


CallbackFilter *g_filter = NULL;
bool g_installed = false;


bool checkInstallStatus(void) {
   BOOL installed = FALSE;
   INT highVer = 0;
   INT lowVer = 0;
   SERVICE_STATUS status;
   memset(&status, 0, sizeof status);
   g_filter->GetDriverStatus(ProductName, &installed, &highVer, &lowVer, &status);

   return installed ? true : false;
}


void doInstall(void) {
   if (!checkInstallStatus()) {
      bool doExit = false;
      BOOL rebootNeeded;
      CallbackFilter::InstallDriver(DriverFileName, ProductName, &rebootNeeded);

      if (!checkInstallStatus()) {
         std::cerr << "Driver install failure" << std::endl;
         doExit = true;
      } else {
         g_installed = true;
      }

      if (rebootNeeded) {
         std::cerr << "InstallDriver says we need a reboot" << std::endl;
         doExit = true;
      }

      if (doExit)
         throw 1;
   }
}


void doUninstall(void) {
   if (g_installed) {
      BOOL rebootNeeded;
      CallbackFilter::UninstallDriver(ProductName, &rebootNeeded);

      if (rebootNeeded)
         std::cerr << std::endl << "UninstallDriver says we need a reboot" << std::cerr;
   }
}


void postReadFileWrapper(
      CallbackFilter* Sender,
      LPWSTR FileName,
      __int64 Position,
      PVOID Buffer,
      DWORD BytesToRead,
      BOOL Cached,
      PVOID* UserContext,
      LPBOOL RequestAccepted)
{
   std::cout << "!";
}


void readFileWrapper(
      CallbackFilter* Sender,
      LPWSTR FileName,
      __int64* Position,
      PVOID Buffer,
      PDWORD BytesToRead,
      BOOL Cached,
      PVOID* UserContext,
      LPBOOL RequestAccepted)
{
   std::cout << ".";

   // *RequestAccepted = TRUE;      // doesn't make a difference.
}


void doIt(void) {
   //
   // These were in my original code, but they don't seem to make a difference to
   // the problem so I left them out.
   //
   // m_filter->SetThreadPoolSize(32);
   // m_filter->SetSerializeCallbacks(FALSE);
   // m_filter->SetProcessCachedReadWriteCallbacks(TRUE);
   //

   unsigned int flags = CallbackFilter::PostReadCallback | CallbackFilter::ReadCallback;

   g_filter->SetOnPostReadFileC(&postReadFileWrapper);
   g_filter->SetOnReadFileC(&readFileWrapper);

   g_filter->AddFilterCallbackRule(FileToWatch, CallbackFilter::CbFltCallbackFlags(flags));

   g_filter->AttachFilter(10000);

   Sleep(120000);

   g_filter->DetachFilter();
}


int _tmain(int argc, _TCHAR* argv[])
{
   int rval = 0;

   g_filter = new CallbackFilter;

   try {
      std::cout << "Starting" << std::endl;

      g_filter->SetRegistrationKey(EldoSTrialKey);
   
      doInstall();

      doIt();

      std::cout << std::endl << "Stopping normally" << std::endl;

   } catch (ECBFltError &e) {
      LPCWSTR str = e.Message();   // Look at this in the debugger; std:cout doesn't support LPCWSTR.
      std::cout << std::endl << "Caught ECbFltError " << std::endl;
      rval = 1;
   } catch (...) {
      std::cerr << std::endl << "Exiting via a catch" << std::endl;
      rval = 2;
   }

   try {
      doUninstall();
      delete g_filter;

   } catch (...) {
      std::cerr << std::endl << "Teardown failed" << std::endl;
   }

   return rval;
}
#20147
Posted: 05/15/2012 02:31:12
by Vladimir Cherniga (EldoS Corp.)

I will test in a sec.
Also by EldoS: Rethync
The cross-platform framework that simplifies synchronizing data between mobile and desktop applications and servers and cloud storages

Reply

Statistics

Topic viewed 5177 times

Number of guests: 1, registered members: 0, in total hidden: 0




|

Back to top

As of July 15, 2016 EldoS Corporation will operate as a division of /n software inc. For more information, please read the announcement.

Got it!