int wmain( int argc, const wchar_t*const* argv)
{
   int err = 0;
   PfmApi* pfm = 0;
   PfmMount* mount = 0;
   PfmMountCreateParams mcp;
   PfmMarshallerServeParams msp;
   Volume volume;

   msp.dispatch = &volume;
   msp.formatterName = "tempfs";

   if (argc <= 1)
   {
      printf(
         "Sample file system application.\n"
         "syntax: tempfs <mount name>\n");
      err = -1;
   }
   else
   {
      mcp.mountSourceName = argv[1];
   }
   if (!err)
   {
      err = PfmApiFactory( &pfm);
      if (err)
      {
         printf( "ERROR: %i Unable to open PFM Api.\n",err);
      }
   }

   if (!err)
   {
      err = PfmMarshallerFactory( &volume.marshaller);
      if (err)
      {
         printf( "ERROR: %i Unable to create marshaller.\n",err);
      }
   }
   if (!err)
   {
         // Communication between the driver and file system is done
         // over a pair of simple pipes. Application is responsible
         // for creating the pipes.
      err = create_pipe( &msp.toFormatterRead, &mcp.toFormatterWrite);
      if (!err)
      {
         err = create_pipe( &mcp.fromFormatterRead, &msp.fromFormatterWrite);
      }
   }
   if (!err)
   {
         // Various mount options are available through mountFlags,
         // visibleProcessId, and ownerSid.
      err = pfm->MountCreate( &mcp, &mount);
      if (err)
      {
         printf( "ERROR: %i Unable to create mount.\n",err);
      }
   }
      // Close driver end pipe handles now. Driver has duplicated what
      // it needs. If these handles are not closed then pipes will not
      // break if driver disconnects, leaving us stuck in the
      // marshaller.
   close_fd( mcp.toFormatterWrite);
   close_fd( mcp.fromFormatterRead);

   if (!err)
   {
         // If tracemon is installed and running then diagnostic
         // messsages can be viewed in the "tempfs" channel.
      volume.marshaller->SetTrace( L"tempfs");
         // Also send diagnostic messages to stdout. This can slow
         // things down quite a bit.
      volume.marshaller->SetStatus( stdout_fd());

         // The marshaller uses alertable I/O, so process can be
         // exited via ctrl+c.
      printf( "Press CTRL+C to exit.\n");
         // The marshaller serve function will return at unmount or
         // if driver disconnects.
      volume.marshaller->ServeDispatch( &msp);
   }

   close_fd( msp.toFormatterRead);
   close_fd( msp.fromFormatterWrite);
   if (mount)
   {
      mount->Release();
   }
   if (pfm)
   {
      pfm->Release();
   }
   if (volume.marshaller)
   {
      volume.marshaller->Release();
      volume.marshaller = 0;
   }
   return err;
}
wxThread::ExitCode PFMMonitorThread::Entry()
{
	const int timeoutMSecs = 50;
	long long startChangeInstance = 0, nextChangeInstance = 0;
	PfmApi *pfmApi = PFMProxy::getInstance().getPfmApi();

	// Get the main frame window
	EncFSMPMainFrame *pMainFrame = NULL;
	wxWindow *pTopWindow = wxTheApp->GetTopWindow();
	if(pTopWindow != NULL)
	{
		pMainFrame = dynamic_cast<EncFSMPMainFrame *>(pTopWindow);
	}

	while(!TestDestroy())
	{
		int retVal = pfmMonitor_->Wait(nextChangeInstance, timeoutMSecs);
		bool sendEvents = true;
		{
			wxMutexLocker lock(mutex_);
			sendEvents = sendEvents_;
		}

		if(sendEvents)
		{
			PfmIterator *iter = NULL;
			pfmApi->MountIterate(startChangeInstance, &nextChangeInstance, &iter);

			long long curChangeInstance = 0;
			int mountId = iter->Next(&curChangeInstance);
			while(mountId > 0)
			{
				if(curChangeInstance >= startChangeInstance)
				{
					PfmMount *curMount = NULL;
					int err = pfmApi->MountIdOpen(mountId, &curMount);

					if(err == 0 && curMount != NULL)
					{
						int statusFlags = curMount->GetStatusFlags();

						std::wstring formatterName(curMount->GetFormatterName());
						std::wstring fileName(curMount->GetMountSourceName());
						wchar_t driveLetter = curMount->GetDriveLetter();
#if !defined(EFS_WIN32)
						driveLetter = L' ';
#endif
						std::wstring ownerName(curMount->GetOwnerName());
						std::wstring ownerId(curMount->GetOwnerId());
						std::wstring mountPoint(curMount->GetMountPoint());

						if(formatterName == EncFSMPStrings::formatterName_)
						{
							if((statusFlags & (pfmStatusFlagReady | pfmStatusFlagDisconnected | pfmStatusFlagClosed)) != 0)
							{
								bool isMountEvent = ((statusFlags & (pfmStatusFlagDisconnected | pfmStatusFlagClosed)) == 0);
								pMainFrame->addNewMountEvent(isMountEvent, false, fileName, driveLetter, mountPoint);
							}
						}

						curMount->Release();
					}
				}
				mountId = iter->Next(&curChangeInstance);
			}

			iter->Release();
			startChangeInstance = nextChangeInstance;
		}
	}

	return 0;
}