コード例 #1
0
//---------------------------------------------------------------------------
bool NIF_Files::CreateUIElements()
{
    NiSample::CreateUIElements();

    // The Log is a text output used by all NiSample derived classes

    AddLogEntry("Press ESC or Start + Select to quit");

    return true;
}
コード例 #2
0
void NCLDebug::Log(const std::string text, ...)
{
	va_list args;
	va_start(args, text);

	char buf[1024];
	int needed = vsnprintf_s(buf, 1023, _TRUNCATE, text.c_str(), args);
	va_end(args);

	int length = (needed < 0) ? 1024 : needed;
	AddLogEntry(Vector3(0.4f, 1.0f, 0.6f), std::string(buf, (size_t)length));
}
コード例 #3
0
ファイル: control.cpp プロジェクト: xurubin/yapb
void BotControl::Think (void)
{
   // this function calls think () function for all available at call moment bots, and
   // try to catch internal error if such shit occurs

   float thinkFps = yb_thinkfps.GetFloat ();

   // check ranges
   if (thinkFps <= 0.0f || thinkFps > 40.0f)
   {
      thinkFps = 22.0f;

      AddLogEntry (true, LOG_ERROR, "Value of yb_thinkfps should be greater than zero and lower than 40.");
      yb_thinkfps.SetFloat (thinkFps);
   }
   thinkFps = (1.0f / thinkFps) * 0.88f;

   for (int i = 0; i < engine->GetMaxClients (); i++)
   {
      if (m_bots[i] != null)
      {
         if (m_bots[i]->m_thinkTimer <= engine->GetTime ())
         {
            // use these try-catch blocks to prevent server crashes when error occurs
#if !defined (NDEBUG) && !defined (_DEBUG)
            try
            {
               m_bots[i]->Think ();
            }
            catch (...)
            {
               // error occurred. kick off all bots and then print a warning message
               RemoveAll ();

               ServerPrintNoTag ("**** INTERNAL BOT ERROR! PLEASE SHUTDOWN AND RESTART YOUR SERVER! ****");
            }
#else
            m_bots[i]->Think ();
#endif
            m_bots[i]->m_thinkTimer = engine->GetTime () + thinkFps;
         }
      }
   }
}
コード例 #4
0
void NCLDebug::LogE(const char* filename, int linenumber, const std::string text, ...)
{
	//Error Format:
	//<text>
	//		-> <line number> : <file name> 

	va_list args;
	va_start(args, text);

	char buf[1024];
	int needed = vsnprintf_s(buf, 1023, _TRUNCATE, text.c_str(), args);
	va_end(args);

	int length = (needed < 0) ? 1024 : needed;

	Log(Vector3(1.0f, 0.25f, 0.25f), "[ERROR] %s:%d", filename, linenumber);
	AddLogEntry(Vector3(1.0f, 0.5f, 0.5f), "\t \x01 \"" + std::string(buf, (size_t)length) + "\"");
	
	std::cout << endl;
}
コード例 #5
0
ファイル: control.cpp プロジェクト: xurubin/yapb
Bot::Bot (edict_t *bot, int skill, int personality, int team, int member)
{
   // this function does core operation of creating bot, it's called by CreateBot (),
   // when bot setup completed, (this is a bot class constructor)

   char rejectReason[128];
   int clientIndex = ENTINDEX (bot);

   memset (this, 0, sizeof (Bot));

   pev = VARS (bot);

   if (bot->pvPrivateData != null)
      FREE_PRIVATE (bot);

   bot->pvPrivateData = null;
   bot->v.frags = 0;

   // create the player entity by calling MOD's player function
   BotControl::CallGameEntity (&bot->v);

   // set all info buffer keys for this bot
   char *buffer = GET_INFOKEYBUFFER (bot);

   SET_CLIENT_KEYVALUE (clientIndex, buffer, "model", "");
   SET_CLIENT_KEYVALUE (clientIndex, buffer, "rate", "3500.000000");
   SET_CLIENT_KEYVALUE (clientIndex, buffer, "cl_updaterate", "20");
   SET_CLIENT_KEYVALUE (clientIndex, buffer, "cl_lw", "1");
   SET_CLIENT_KEYVALUE (clientIndex, buffer, "cl_lc", "1");
   SET_CLIENT_KEYVALUE (clientIndex, buffer, "tracker", "0");
   SET_CLIENT_KEYVALUE (clientIndex, buffer, "cl_dlmax", "128");
   SET_CLIENT_KEYVALUE (clientIndex, buffer, "friends", "0");
   SET_CLIENT_KEYVALUE (clientIndex, buffer, "dm", "0");
   SET_CLIENT_KEYVALUE (clientIndex, buffer, "_ah", "0");

   if (yb_tagbots.GetBool ())
      SET_CLIENT_KEYVALUE (clientIndex, buffer, "*bot", "1");

   SET_CLIENT_KEYVALUE (clientIndex, buffer, "_vgui_menus", "0");

   memset (rejectReason, 0, sizeof (rejectReason)); // reset the reject reason template string
   MDLL_ClientConnect (bot, "fakeclient", FormatBuffer ("192.168.1.%d", ENTINDEX (bot) + 100), rejectReason);

   if (!IsNullString (rejectReason))
   {
      AddLogEntry (true, LOG_WARNING, "Server refused '%s' connection (%s)", STRING (bot->v.netname), rejectReason);
      ServerCommand ("kick \"%s\"", STRING (bot->v.netname)); // kick the bot player if the server refused it

      bot->v.flags |= FL_KILLME;
   }

   if (IsDedicatedServer () && engine->GetDeveloperLevel () > 0)
   {
      if (engine->GetDeveloperLevel () == 2)
      {
          ServerPrint ("Server requiring authentication");
          ServerPrint ("Client '%s' connected", STRING (bot->v.netname));
          ServerPrint ("Adr: 127.0.0.%d:27005", ENTINDEX (bot) + 100);
      }

      ServerPrint ("Verifying and uploading resources...");
      ServerPrint ("Custom resources total 0 bytes");
      ServerPrint ("  Decals:  0 bytes");
      ServerPrint ("----------------------");
      ServerPrint ("Resources to request: 0 bytes");
   }

   MDLL_ClientPutInServer (bot);

   bot->v.flags = 0;
   bot->v.flags |= FL_FAKECLIENT | FL_CLIENT; // set this player as fakeclient

   // initialize all the variables for this bot...
   m_notStarted = true;  // hasn't joined game yet

   m_startAction = CMENU_IDLE;
   m_moneyAmount = 0;
   m_logotypeIndex = engine->RandomInt (0, 5);


   // initialize msec value
   m_msecNum = m_msecDel = 0.0f;
   m_msecInterval = engine->GetTime ();
   m_msecVal = static_cast <uint8_t> (g_pGlobals->frametime * 1000.0f);
   m_msecBuiltin = engine->RandomInt (1, 4);

   // assign how talkative this bot will be
   m_sayTextBuffer.chatDelay = engine->RandomFloat (3.8f, 10.0f);
   m_sayTextBuffer.chatProbability = engine->RandomInt (1, 100);

   m_notKilled = false;
   m_skill = skill;
   m_weaponBurstMode = BURST_DISABLED;

   m_lastThinkTime = engine->GetTime ();
   m_frameInterval = engine->GetTime ();

   bot->v.idealpitch = bot->v.v_angle.x;
   bot->v.ideal_yaw = bot->v.v_angle.y;

   bot->v.yaw_speed = engine->RandomFloat (g_skillTab[m_skill / 20].minTurnSpeed, g_skillTab[m_skill / 20].maxTurnSpeed);
   bot->v.pitch_speed = engine->RandomFloat (g_skillTab[m_skill / 20].minTurnSpeed, g_skillTab[m_skill / 20].maxTurnSpeed);

   switch (personality)
   {
   case 1:
      m_personality = PERSONALITY_RUSHER;
      m_baseAgressionLevel = engine->RandomFloat (0.7f, 1.0f);
      m_baseFearLevel = engine->RandomFloat (0.0f, 0.4f);
      break;

   case 2:
      m_personality = PERSONALITY_CAREFUL;
      m_baseAgressionLevel = engine->RandomFloat (0.0f, 0.4f);
      m_baseFearLevel = engine->RandomFloat (0.7f, 1.0f);
      break;

   default:
      m_personality = PERSONALITY_NORMAL;
      m_baseAgressionLevel = engine->RandomFloat (0.4f, 0.7f);
      m_baseFearLevel = engine->RandomFloat (0.4f, 0.7f);
      break;
   }

   memset (&m_ammoInClip, 0, sizeof (m_ammoInClip));
   memset (&m_ammo, 0, sizeof (m_ammo));

   m_currentWeapon = 0; // current weapon is not assigned at start
   m_voicePitch = engine->RandomInt (166, 250) / 2; // assign voice pitch

   // copy them over to the temp level variables
   m_agressionLevel = m_baseAgressionLevel;
   m_fearLevel = m_baseFearLevel;
   m_nextEmotionUpdate = engine->GetTime () + 0.5f;

   // just to be sure
   m_actMessageIndex = 0;
   m_pushMessageIndex = 0;

   // assign team and class
   m_wantedTeam = team;
   m_wantedClass = member;

   NewRound ();
}
コード例 #6
0
ファイル: netmsg.cpp プロジェクト: CCNHsK-Dev/SyPB
void NetworkMsg::Execute (void *p)
{
   if (m_message == NETMSG_UNDEFINED)
      return; // no message or not for bot, return

   // some needed variables
   static uint8_t r, g, b;
   static uint8_t enabled;

   static int damageArmor, damageTaken, damageBits;
   static int killerIndex, victimIndex, playerIndex;
   static int index, numPlayers;
   static int state, id, clip;

   static Vector damageOrigin;
   static WeaponProperty weaponProp;

   // now starts of netmessage execution
   switch (m_message)
   {
   case NETMSG_VGUI:
      // this message is sent when a VGUI menu is displayed.

      if (m_state == 0)
      {
         switch (PTR_TO_INT (p))
         {
         case GMENU_TEAM:
            m_bot->m_startAction = CMENU_TEAM;
            break;

         case GMENU_TERRORIST:
         case GMENU_COUNTER:
            m_bot->m_startAction = CMENU_CLASS;
            break;
         }
      }
      break;

   case NETMSG_SHOWMENU:
      // this message is sent when a text menu is displayed.

      if (m_state < 3) // ignore first 3 fields of message
         break;

      if (strcmp (PTR_TO_STR (p), "#Team_Select") == 0) // team select menu?
         m_bot->m_startAction = CMENU_TEAM;
      else if (strcmp (PTR_TO_STR (p), "#Team_Select_Spect") == 0) // team select menu?
         m_bot->m_startAction = CMENU_TEAM;
      else if (strcmp (PTR_TO_STR (p), "#IG_Team_Select_Spect") == 0) // team select menu?
         m_bot->m_startAction = CMENU_TEAM;
      else if (strcmp (PTR_TO_STR (p), "#IG_Team_Select") == 0) // team select menu?
         m_bot->m_startAction = CMENU_TEAM;
      else if (strcmp (PTR_TO_STR (p), "#IG_VIP_Team_Select") == 0) // team select menu?
         m_bot->m_startAction = CMENU_TEAM;
      else if (strcmp (PTR_TO_STR (p), "#IG_VIP_Team_Select_Spect") == 0) // team select menu?
         m_bot->m_startAction = CMENU_TEAM;
      else if (strcmp (PTR_TO_STR (p), "#Terrorist_Select") == 0) // T model select?
         m_bot->m_startAction = CMENU_CLASS;
      else if (strcmp (PTR_TO_STR (p), "#CT_Select") == 0) // CT model select menu?
         m_bot->m_startAction = CMENU_CLASS;

      break;

   case NETMSG_WLIST:
      // this message is sent when a client joins the game. All of the weapons are sent with the weapon ID and information about what ammo is used.

      switch (m_state)
      {
      case 0:
         strcpy (weaponProp.className, PTR_TO_STR (p));
         break;

      case 1:
         weaponProp.ammo1 = PTR_TO_INT (p); // ammo index 1
         break;

      case 2:
         weaponProp.ammo1Max = PTR_TO_INT (p); // max ammo 1
         break;

      case 5:
         weaponProp.slotID = PTR_TO_INT (p); // slot for this weapon
         break;

      case 6:
         weaponProp.position = PTR_TO_INT (p); // position in slot
         break;

      case 7:
         weaponProp.id = PTR_TO_INT (p); // weapon ID
         break;

      case 8:
         weaponProp.flags = PTR_TO_INT (p); // flags for weapon (WTF???)
         g_weaponDefs[weaponProp.id] = weaponProp; // store away this weapon with it's ammo information...
         break;
      }
      break;

   case NETMSG_CURWEAPON:
      // this message is sent when a weapon is selected (either by the bot chosing a weapon or by the server auto assigning the bot a weapon). In CS it's also called when Ammo is increased/decreased

      switch (m_state)
      {
      case 0:
         state = PTR_TO_INT (p); // state of the current weapon (WTF???)
         break;

      case 1:
         id = PTR_TO_INT (p); // weapon ID of current weapon
         break;

      case 2:
         clip = PTR_TO_INT (p); // ammo currently in the clip for this weapon

         if (id <= 31)
         {
            if (state != 0)
               m_bot->m_currentWeapon = id;

            // ammo amount decreased ? must have fired a bullet...
            if (id == m_bot->m_currentWeapon && m_bot->m_ammoInClip[id] > clip)
            {
               // time fired with in burst firing time ?
               if (m_bot->m_timeLastFired + 1.0f > engine->GetTime ())
                  m_bot->m_burstShotsFired++;

               m_bot->m_timeLastFired = engine->GetTime (); // remember the last bullet time
            }
            m_bot->m_ammoInClip[id] = clip;
         }
         break;
      }
      break;

   case NETMSG_AMMOX:
      // this message is sent whenever ammo amounts are adjusted (up or down). NOTE: Logging reveals that CS uses it very unreliable!

      switch (m_state)
      {
      case 0:
         index = PTR_TO_INT (p); // ammo index (for type of ammo)
         break;

      case 1:
         m_bot->m_ammo[index] = PTR_TO_INT (p); // store it away
         break;
      }
      break;

   case NETMSG_AMMOPICK:
      // this message is sent when the bot picks up some ammo (AmmoX messages are also sent so this message is probably
      // not really necessary except it allows the HUD to draw pictures of ammo that have been picked up.  The bots
      // don't really need pictures since they don't have any eyes anyway.

      switch (m_state)
      {
      case 0:
         index = PTR_TO_INT (p);
         break;

      case 1:
         m_bot->m_ammo[index] = PTR_TO_INT (p);
         break;
      }
      break;

   case NETMSG_DAMAGE:
      // this message gets sent when the bots are getting damaged.

      switch (m_state)
      {
      case 0:
         damageArmor = PTR_TO_INT (p);
         break;

      case 1:
         damageTaken = PTR_TO_INT (p);
         break;

      case 2:
         damageBits = PTR_TO_INT (p);

         if (damageArmor > 0 || damageTaken > 0)
            m_bot->TakeDamage (m_bot->pev->dmg_inflictor, damageTaken, damageArmor, damageBits);
         break;
      }
      break;

   case NETMSG_MONEY:
      // this message gets sent when the bots money amount changes

      if (m_state == 0)
         m_bot->m_moneyAmount = PTR_TO_INT (p); // amount of money
      break;

   case NETMSG_STATUSICON:
      switch (m_state)
      {
      case 0:
         enabled = PTR_TO_BYTE (p);
         break;

      case 1:
         if (strcmp (PTR_TO_STR (p), "defuser") == 0)
            m_bot->m_hasDefuser = (enabled != 0);
         else if (strcmp (PTR_TO_STR (p), "buyzone") == 0)
         {
            m_bot->m_inBuyZone = (enabled != 0);

            // try to equip in buyzone
            m_bot->EquipInBuyzone (0);
         }
         else if (strcmp (PTR_TO_STR (p), "vipsafety") == 0)
            m_bot->m_inVIPZone = (enabled != 0);
         else if (strcmp (PTR_TO_STR (p), "c4") == 0)
            m_bot->m_inBombZone = (enabled == 2);
         break;
      }
      break;

   case NETMSG_DEATH: // this message sends on death
      switch (m_state)
      {
      case 0:
         killerIndex = PTR_TO_INT (p);
         break;

      case 1:
         victimIndex = PTR_TO_INT (p);
         break;

      case 2:
         if (killerIndex != 0 && killerIndex != victimIndex)
         {
            edict_t *killer = INDEXENT (killerIndex);
            edict_t *victim = INDEXENT (victimIndex);

            if (FNullEnt (killer) || FNullEnt (victim))
               break;

            // need to send congrats on well placed shot
            for (int i = 0; i < engine->GetMaxClients (); i++)
            {
               Bot *bot = g_botManager->GetBot (i);

               if (bot != null && IsAlive (bot->GetEntity ()) && killer != bot->GetEntity () && bot->EntityIsVisible (victim->v.origin) && GetTeam (killer) == GetTeam (bot->GetEntity ()) && GetTeam (killer) != GetTeam (victim))
               {
                  if (killer == g_hostEntity)
                     bot->HandleChatterMessage ("#Bot_NiceShotCommander");
                  else
                     bot->HandleChatterMessage ("#Bot_NiceShotPall");

                  break;
               }
            }
            
            // SyPB Pro P.15
            if (GetGameMod () == 0)
            {
	            // notice nearby to victim teammates, that attacker is near
	            for (int i = 0; i < engine->GetMaxClients (); i++)
	            {
	               Bot *bot = g_botManager->GetBot (i);

	               if (bot != null && IsAlive (bot->GetEntity ()) && GetTeam (bot->GetEntity ()) == GetTeam (victim) && IsVisible (killer->v.origin, bot->GetEntity ()) && FNullEnt (bot->m_enemy) && GetTeam (killer) != GetTeam (victim))
	               {
	                  bot->m_actualReactionTime = 0.0f;
	                  bot->m_seeEnemyTime = engine->GetTime ();
	                  bot->m_enemy = killer;
	                  bot->m_lastEnemy = killer;
	                  bot->m_lastEnemyOrigin = killer->v.origin;
	               }
	            }
	        }

            Bot *bot = g_botManager->GetBot (killer);

            // is this message about a bot who killed somebody?
            if (bot != null)
               bot->m_lastVictim = victim;

            else // did a human kill a bot on his team?
            {
               Bot *iter = g_botManager->GetBot (victim);

               if (iter != null)
               {
                  if (GetTeam (killer) == GetTeam (victim))
                     iter->m_voteKickIndex = killerIndex;

                  iter->m_notKilled = false;
               }
            }
         }
         break;
      }
      break;

   case NETMSG_SCREENFADE: // this message gets sent when the Screen fades (Flashbang)
      switch (m_state)
      {
      case 3:
         r = PTR_TO_BYTE (p);
         break;

      case 4:
         g = PTR_TO_BYTE (p);
         break;

      case 5:
         b = PTR_TO_BYTE (p);
         break;

      case 6:
         m_bot->TakeBlinded (Vector (r, g, b), PTR_TO_BYTE (p));
         break;
      }
      break;

   case NETMSG_HLTV: // round restart in steam cs
      switch (m_state)
      {
      case 0:
         numPlayers = PTR_TO_INT (p);
         break;

      case 1:
         if (numPlayers == 0 && PTR_TO_INT (p) == 0)
            RoundInit ();
         break;
      }
      break;


   case NETMSG_RESETHUD:
#if 0
      if (m_bot != null)
         m_bot->NewRound ();
#endif
      break;

   case NETMSG_TEXTMSG:
      if (m_state == 1)
      {
         if (FStrEq (PTR_TO_STR (p), "#CTs_Win") ||
            FStrEq (PTR_TO_STR (p), "#Bomb_Defused") ||
            FStrEq (PTR_TO_STR (p), "#Terrorists_Win") ||
            FStrEq (PTR_TO_STR (p), "#Round_Draw") ||
            FStrEq (PTR_TO_STR (p), "#All_Hostages_Rescued") ||
            FStrEq (PTR_TO_STR (p), "#Target_Saved") ||
            FStrEq (PTR_TO_STR (p), "#Hostages_Not_Rescued") ||
            FStrEq (PTR_TO_STR (p), "#Terrorists_Not_Escaped") ||
            FStrEq (PTR_TO_STR (p), "#VIP_Not_Escaped") ||
            FStrEq (PTR_TO_STR (p), "#Escaping_Terrorists_Neutralized") ||
            FStrEq (PTR_TO_STR (p), "#VIP_Assassinated") ||
            FStrEq (PTR_TO_STR (p), "#VIP_Escaped") ||
            FStrEq (PTR_TO_STR (p), "#Terrorists_Escaped") ||
            FStrEq (PTR_TO_STR (p), "#CTs_PreventEscape") ||
            FStrEq (PTR_TO_STR (p), "#Target_Bombed") ||
            FStrEq (PTR_TO_STR (p), "#Game_Commencing") ||
            FStrEq (PTR_TO_STR (p), "#Game_will_restart_in"))
         {
            g_roundEnded = true;

            if (FStrEq (PTR_TO_STR (p), "#Game_Commencing"))
               g_isCommencing = true;

            if (FStrEq (PTR_TO_STR (p), "#CTs_Win"))
               g_botManager->SetLastWinner (TEAM_COUNTER); // update last winner for economics

            if (FStrEq (PTR_TO_STR (p), "#Terrorists_Win"))
               g_botManager->SetLastWinner (TEAM_TERRORIST); // update last winner for economics

            g_waypoint->SetBombPosition (true);
         }
         else if (!g_bombPlanted && FStrEq (PTR_TO_STR (p), "#Bomb_Planted"))
         {
            g_bombPlanted = true;
            g_bombSayString = true;
            g_timeBombPlanted = engine->GetTime ();

            for (int i = 0; i < engine->GetMaxClients (); i++)
            {
               Bot *bot = g_botManager->GetBot (i);

               if (bot != null && IsAlive (bot->GetEntity ()))
               {
                  bot->DeleteSearchNodes ();
                  bot->ResetTasks ();

                  if (engine->RandomInt (0, 100) < 85 && GetTeam (bot->GetEntity ()) == TEAM_COUNTER)
                     bot->ChatterMessage (Chatter_WhereIsTheBomb);
               }
            }
            g_waypoint->SetBombPosition ();
         }
         else if (m_bot != null && FStrEq (PTR_TO_STR (p), "#Switch_To_BurstFire"))
            m_bot->m_weaponBurstMode = BURST_ENABLED;
         else if (m_bot != null && FStrEq (PTR_TO_STR (p), "#Switch_To_SemiAuto"))
            m_bot->m_weaponBurstMode = BURST_DISABLED;
      }
      break;

   case NETMSG_SCOREINFO:
      switch (m_state)
      {
      case 0:
         playerIndex = PTR_TO_INT (p);
         break;

      case 4:
         if (playerIndex >= 0 && playerIndex <= engine->GetMaxClients ())
         {
            if (PTR_TO_INT (p) == 1)
               g_clients[playerIndex - 1].realTeam = TEAM_TERRORIST;
            else if (PTR_TO_INT (p) == 2)
               g_clients[playerIndex - 1].realTeam = TEAM_COUNTER;

               g_clients[playerIndex - 1].team = g_clients[playerIndex - 1].realTeam;
         }
         break;
      }
      break;

   case NETMSG_BARTIME:
      if (m_state == 0)
      {
         if (PTR_TO_INT (p) > 0)
            m_bot->m_hasProgressBar = true; // the progress bar on a hud
         else if (PTR_TO_INT (p) == 0)
            m_bot->m_hasProgressBar = false; // no progress bar or disappeared
      }
      break;

   default:
      AddLogEntry (true, LOG_FATAL, "Network message handler error. Call to unrecognized message id (%d).\n", m_message);
   }
   m_state++; // and finally update network message state
}
コード例 #7
0
__declspec(dllexport) BOOL SoaronModuleFunc(void)
{
	SQLHDBC  hdbc;
	HSTMT hstmt;
	unsigned int NumOfLinks, LinkID;
	WSADATA wd;
	SQLRETURN sqlret;
	HANDLE hHeap;
	FTNAddr LinkAddr;
	wchar_t Ip[256];

	lpLinksCheckInfo LinksTable;
	WSAEVENT * EventsTable;
	WSANETWORKEVENTS evt;
	unsigned int i, j;
	int res;

	ADDRINFOW *result = NULL;
	ADDRINFOW hints;
	wchar_t LogStr[255];
	memset(&hints, 0, sizeof(hints));

	LinkAddr.point = 0;
	NumOfLinks = 0;
	SQLAllocHandle(SQL_HANDLE_DBC, cfg.henv, &hdbc);
	sqlret = SQLDriverConnectW(hdbc, NULL, cfg.ConnectionString, SQL_NTS, NULL, 0, NULL, SQL_DRIVER_NOPROMPT);
	if (sqlret != SQL_SUCCESS && sqlret != SQL_SUCCESS_WITH_INFO)
	{
		SetEvent(cfg.hExitEvent); return FALSE;//fatal error
	}
	SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);

	AddLogEntry(L"Checking binkp links alive");
	//get links info
	SQLExecDirectW(hstmt, L"update Links set DialOut=0 where datediff(minute,LastSessionTime,GetDate())>40 and LinkType=1", SQL_NTS);
	sqlret = SQLExecDirectW(hstmt, L"select count(*) from Links where dialout=0 and passivelink=0 and LinkType=1 and isnull(ip,'')<>''", SQL_NTS);
	if ((sqlret == SQL_SUCCESS) || (sqlret = SQL_SUCCESS_WITH_INFO))
	{
		sqlret = SQLFetch(hstmt);
		if ((sqlret == SQL_SUCCESS) || (sqlret = SQL_SUCCESS_WITH_INFO))
		{
			SQLGetData(hstmt, 1, SQL_C_ULONG, &NumOfLinks, 0, NULL);
		}
	}
	SQLCloseCursor(hstmt);
	if (NumOfLinks == 0) goto exit;
	hHeap = HeapCreate(HEAP_NO_SERIALIZE, 8192, 0);
	LinksTable = HeapAlloc(hHeap, HEAP_ZERO_MEMORY, NumOfLinks*sizeof(LinksCheckInfo));
	EventsTable = HeapAlloc(hHeap, HEAP_ZERO_MEMORY, sizeof(WSAEVENT)*NumOfLinks);
	i = 0;
	hints.ai_family = AF_INET;
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_protocol = IPPROTO_TCP;


	WSAStartup(MAKEWORD(2, 2), &wd);
	sqlret = SQLExecDirectW(hstmt, L"select LinkID,Zone,Net,Node, Ip from Links where dialout=0 and passivelink=0 and LinkType=1 and isnull(ip,'')<>''", SQL_NTS);
	if ((sqlret == SQL_SUCCESS) || (sqlret = SQL_SUCCESS_WITH_INFO))
	{
		
		SQLBindCol(hstmt, 1, SQL_C_ULONG, &LinkID, 0, NULL);
		SQLBindCol(hstmt, 2, SQL_C_USHORT, &(LinkAddr.zone), 0, NULL);
		SQLBindCol(hstmt, 3, SQL_C_USHORT, &(LinkAddr.net), 0, NULL);
		SQLBindCol(hstmt, 4, SQL_C_USHORT, &(LinkAddr.node), 0, NULL);
		SQLBindCol(hstmt, 5, SQL_C_WCHAR, Ip, 512, NULL);
		sqlret = SQLFetch(hstmt);
		while ((sqlret == SQL_SUCCESS) || (sqlret == SQL_SUCCESS_WITH_INFO))
		{
			//


			res = GetAddrInfoW(Ip, L"24554", &hints, &result);
			if (res == 0)
			{

				memcpy(&(LinksTable[i].sa), result->ai_addr, sizeof(struct sockaddr_in));
				//				printf("%u  %u %S %u.%u.%u.%u\n", i,LinkID, Ip, LinksTable[i].sa.sin_addr.S_un.S_un_b.s_b1, LinksTable[i].sa.sin_addr.S_un.S_un_b.s_b2, LinksTable[i].sa.sin_addr.S_un.S_un_b.s_b3, LinksTable[i].sa.sin_addr.S_un.S_un_b.s_b4);

				LinksTable[i].LinkID = LinkID;
				LinksTable[i].LinkAddr.FullAddr = LinkAddr.FullAddr;
				LinksTable[i].s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
				EventsTable[i] = WSACreateEvent();
				WSAEventSelect(LinksTable[i].s, EventsTable[i], FD_CONNECT);
				FreeAddrInfoW(result);
				++i;
			}
			else
			{
				wsprintfW(LogStr,L"%u:%u/%u: Ip address %s cannot be resolved", LinkAddr.zone, LinkAddr.net, LinkAddr.node,Ip);
				AddLogEntry(LogStr);
			}


			sqlret = SQLFetch(hstmt);

		}

	}
	SQLCloseCursor(hstmt);
	SQLFreeStmt(hstmt, SQL_UNBIND);
	NumOfLinks = i;
	for (i = 0; i < NumOfLinks; i++)
	{
		connect(LinksTable[i].s, (struct sockaddr *)&(LinksTable[i].sa), sizeof(struct sockaddr_in));
	}
	j = 0;

	SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_ULONG, SQL_INTEGER, 0, 0, &LinkID, 0, NULL);
	SQLPrepareW(hstmt, L"Update Links set DialOut=1 where LinkID=?", SQL_NTS);

	while (j < NumOfLinks)
	{
		res = WSAWaitForMultipleEvents(NumOfLinks, EventsTable, FALSE, WSA_INFINITE, FALSE);
		WSAEnumNetworkEvents(LinksTable[res].s, EventsTable[res], &evt);
		shutdown(LinksTable[res].s, SD_BOTH);
		closesocket(LinksTable[res].s);
		if (evt.iErrorCode[FD_CONNECT_BIT] == 0)
		{
			wsprintfW(LogStr, L"%u:%u/%u: OK", LinksTable[res].LinkAddr.zone, LinksTable[res].LinkAddr.net, LinksTable[res].LinkAddr.node);
			LinkID = LinksTable[res].LinkID;
			SQLExecute(hstmt);
		}
		else
		{
			switch (evt.iErrorCode[FD_CONNECT_BIT])
			{
				case WSAECONNREFUSED:
					wsprintfW(LogStr, L"%u:%u/%u: Connection refused", LinksTable[res].LinkAddr.zone, LinksTable[res].LinkAddr.net, LinksTable[res].LinkAddr.node);
					break;
				case WSAETIMEDOUT:
					wsprintfW(LogStr, L"%u:%u/%u: Connection timed out", LinksTable[res].LinkAddr.zone, LinksTable[res].LinkAddr.net, LinksTable[res].LinkAddr.node);
					break;
				default:wsprintfW(LogStr, L"%u:%u/%u: Unknown connection error", LinksTable[res].LinkAddr.zone, LinksTable[res].LinkAddr.net, LinksTable[res].LinkAddr.node);

			
			}

		}
		AddLogEntry(LogStr);
		++j;
	}
	//

	for (j = 0; j < NumOfLinks; j++)
	{
		WSACloseEvent(EventsTable[j]);
	}
	SQLFreeStmt(hstmt, SQL_RESET_PARAMS);
	//
	WSACleanup();
	HeapDestroy(hHeap);
exit:
	SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
	SQLDisconnect(hdbc);
	SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
	AddLogEntry(L"Links alive check done");
	SetEvent(cfg.hLinksUpdateEvent);
	return TRUE;
}
コード例 #8
0
ファイル: NetmailOut.c プロジェクト: YuriMyakotin/Soaron
void LogSessionAndSendNetmailToLink(lpFTNAddr lpLinkAddr, unsigned char SoftwareCode)
{
	SQLHDBC   hdbc;
	SQLHSTMT  hstmt;
	SQLRETURN sqlret;
	SQLLEN cb;

	HANDLE hHeap;
	HANDLE hPktFile;
	
	wchar_t tmpPktFileName[MAX_PATH], finalPktFileName[MAX_PATH], FileboxDirName[MAX_PATH];
	wchar_t LogStr[255];
	unsigned int PktNumber;

	unsigned int LinkID;
	NetmailOutQueue NOQ;
	char PktPwd[9];



	hHeap = HeapCreate(HEAP_NO_SERIALIZE, 16384, 0);
	SQLAllocHandle(SQL_HANDLE_DBC, cfg.henv, &hdbc);
	sqlret = SQLDriverConnectW(hdbc, NULL, cfg.ConnectionString, SQL_NTS, NULL, 0, NULL, SQL_DRIVER_NOPROMPT);
	if (sqlret != SQL_SUCCESS && sqlret != SQL_SUCCESS_WITH_INFO)
	{
		SetEvent(cfg.hExitEvent);
		return;
		//fatal error
	}
	SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);

	SQLBindParameter(hstmt, 1, SQL_PARAM_OUTPUT, SQL_C_ULONG, SQL_INTEGER, 0, 0, &LinkID, 0, NULL);
	SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_USHORT, SQL_SMALLINT, 0, 0, &(lpLinkAddr->zone), 0, NULL);
	SQLBindParameter(hstmt, 3, SQL_PARAM_INPUT, SQL_C_USHORT, SQL_SMALLINT, 0, 0, &(lpLinkAddr->net), 0, NULL);
	SQLBindParameter(hstmt, 4, SQL_PARAM_INPUT, SQL_C_USHORT, SQL_SMALLINT, 0, 0, &(lpLinkAddr->node), 0, NULL);
	SQLBindParameter(hstmt, 5, SQL_PARAM_INPUT, SQL_C_USHORT, SQL_SMALLINT, 0, 0, &(lpLinkAddr->point), 0, NULL);
	SQLBindParameter(hstmt, 6, SQL_PARAM_INPUT, SQL_C_UTINYINT , SQL_TINYINT, 0, 0, &SoftwareCode, 0, NULL);
	SQLExecDirectW(hstmt, L"{?=call sp_GetLinkIdForNetmailRouting(?,?,?,?,?)}", SQL_NTS);

	

	NOQ.First = NULL;
	NOQ.Last = NULL;

	SQLFreeStmt(hstmt, SQL_RESET_PARAMS);
	if (SoftwareCode != 1) goto exit;

	if (LinkID != 0)
	{
		//netmail out//
		memset(PktPwd, 0, 9);
		SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_ULONG, SQL_INTEGER, 0, 0, &LinkID, 0, NULL);
		sqlret = SQLExecDirectW(hstmt, L"select PktPassword from Links where LinkID=?", SQL_NTS);//
		if ((sqlret == SQL_SUCCESS) || (sqlret == SQL_SUCCESS_WITH_INFO))
		{
			sqlret = SQLFetch(hstmt);
			if ((sqlret == SQL_SUCCESS) || (sqlret == SQL_SUCCESS_WITH_INFO))
			{
				SQLGetData(hstmt, 1, SQL_C_CHAR, PktPwd, 9, &cb);
			}
		}
		SQLCloseCursor(hstmt);
		
		EnterCriticalSection(&NetmailRouteCritSect);
		sqlret = SQLExecDirectW(hstmt, L"select Netmail.MessageID,FromZone,FromNet,FromNode,FromPoint,ToZone,ToNet,ToNode,ToPoint,CreateTime,FromName,ToName,Subject,MsgId,ReplyTo,MsgText,KillSent,Pvt,FileAttach,Arq,RRq,ReturnReq,Direct,Cfm,recv from Netmail,NetmailOutbound where Netmail.MessageID=NetmailOutbound.MessageID and NetmailOutbound.ToLinkID=? order by Netmail.MessageID", SQL_NTS);//
		if ((sqlret == SQL_SUCCESS) || (sqlret == SQL_SUCCESS_WITH_INFO))
		{
			GetNetmailMessages(hstmt, hHeap, &NOQ);
		}
		SQLFreeStmt(hstmt, SQL_RESET_PARAMS);

		if (NOQ.First != NULL)
		{

			PktNumber = GetPktNumber(hstmt);
			wsprintfW(FileboxDirName, L"%s\\%u.%u.%u.0", cfg.FileboxesDir, lpLinkAddr->zone, lpLinkAddr->net, lpLinkAddr->node);
			wsprintfW(tmpPktFileName, L"%s\\%08X.NETMAIL", cfg.TmpOutboundDir, PktNumber);
			wsprintfW(finalPktFileName, L"%s\\%08X.PKT", FileboxDirName, PktNumber);
			hPktFile = CreateFileW(tmpPktFileName, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_NEW, 0, NULL);
			
			WritePktHeader(hPktFile, &(cfg.MyAddr),lpLinkAddr, PktPwd); 
			//
			while (NOQ.First != NULL)
			{
				lpNetmailMessage lpTmp;
				//
				wsprintfW(LogStr, L"Dynamic netmail %u:%u/%u.%u -> %u:%u/%u.%u thru %u:%u/%u", NOQ.First->FromAddr.zone, NOQ.First->FromAddr.net, NOQ.First->FromAddr.node, NOQ.First->FromAddr.point, NOQ.First->ToAddr.zone, NOQ.First->ToAddr.net, NOQ.First->ToAddr.node, NOQ.First->ToAddr.point, lpLinkAddr->zone, lpLinkAddr->net, lpLinkAddr->node);
				AddLogEntry(LogStr);
				
				WriteNetmailMessage(hPktFile, hHeap, NOQ.First);

				SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_ULONG, SQL_INTEGER, 0, 0, &(NOQ.First->MessageID), 0, NULL);
				sqlret = SQLExecDirectW(hstmt, L"{call sp_NetmailMessageSent(?)}", SQL_NTS);
				SQLFreeStmt(hstmt, SQL_RESET_PARAMS);
				//
				lpTmp = NOQ.First->NextMsg;
				HeapFree(hHeap, 0, NOQ.First->MsgText);
				if (NOQ.First->ReplyTo != NULL) HeapFree(hHeap, 0, NOQ.First->ReplyTo);
				if (NOQ.First->MsgId != NULL) HeapFree(hHeap, 0, NOQ.First->MsgId);
				HeapFree(hHeap, 0, NOQ.First->Subject);
				HeapFree(hHeap, 0, NOQ.First->ToName);
				HeapFree(hHeap, 0, NOQ.First->FromName);
				HeapFree(hHeap, 0, NOQ.First);
				NOQ.First = lpTmp;
			}
			if (hPktFile != INVALID_HANDLE_VALUE)
			{
				ClosePktFile(hPktFile);
				CreateDirectoryW(FileboxDirName, NULL);
				MoveFileExW(tmpPktFileName, finalPktFileName, MOVEFILE_COPY_ALLOWED);
			}
			//
		}
		LeaveCriticalSection(&NetmailRouteCritSect);
	}

	exit:
	SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
	SQLDisconnect(hdbc);
	SQLFreeHandle(SQL_HANDLE_DBC, hdbc);
	HeapDestroy(hHeap);
}
コード例 #9
0
ファイル: NetmailOut.c プロジェクト: YuriMyakotin/Soaron
DWORD WINAPI NetmailOutThread(LPVOID param)
{
	SQLHDBC   hdbc;
	SQLHSTMT  hstmt;
	SQLRETURN sqlret;
	SQLLEN cb;
	HANDLE hHeap;

	FTNAddr LastAddr;
	HANDLE hPktFile;
	wchar_t tmpFileName[MAX_PATH], finalPktFileName[MAX_PATH],FileboxDirName[MAX_PATH];
	wchar_t LogStr[255];
	unsigned int PktNumber;
	char PktPwd[9];

	NetmailOutQueue NDOQ;



	int WaitTime;
	int result; 

	HANDLE hEvent[2];
	
	InterlockedIncrement(&(cfg.ThreadCount));

	WaitTime=INFINITE;


	hEvent[0]=cfg.hExitEvent;
	hEvent[1]=cfg.hNetmailOutEvent;
	AddLogEntry(L"Netmail out thread started");

loop:
	result=WaitForMultipleObjects(2,hEvent,FALSE,WaitTime);
	if (result==WAIT_TIMEOUT)
	{
		SQLFreeHandle(SQL_HANDLE_STMT,hstmt);
		SQLDisconnect(hdbc);
		SQLFreeHandle(SQL_HANDLE_DBC,hdbc);
		WaitTime=INFINITE;
		HeapDestroy(hHeap);
		goto loop;

	}
	if (WaitTime==INFINITE)
	{
		hHeap=HeapCreate(HEAP_NO_SERIALIZE,16384,0);
		SQLAllocHandle(SQL_HANDLE_DBC, cfg.henv, &hdbc); 
		sqlret=SQLDriverConnectW(hdbc, NULL, cfg.ConnectionString, SQL_NTS, NULL, 0, NULL, SQL_DRIVER_NOPROMPT);
		if (sqlret != SQL_SUCCESS && sqlret != SQL_SUCCESS_WITH_INFO)
		{		
			SetEvent(cfg.hExitEvent);
			goto threadexit;
			//fatal error
		}
		SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt);
		
		WaitTime=10000;
	}

	switch(result)
	{
	case (WAIT_OBJECT_0):
		{
			goto threadexit;
		}
	case (WAIT_OBJECT_0+1):
		{
			
			NDOQ.First=NULL;
			NDOQ.Last=NULL;
			
			EnterCriticalSection(&NetmailRouteCritSect);
			SQLExecDirectW(hstmt, L"execute sp_DirectNetmail", SQL_NTS); // обработать директный нетмейл для использующих FTN Service линков
			LeaveCriticalSection(&NetmailRouteCritSect);

			sqlret=SQLExecDirectW(hstmt,L"select MessageID,FromZone,FromNet,FromNode,FromPoint,ToZone,ToNet,ToNode,ToPoint,CreateTime,FromName,ToName,Subject,MsgId,ReplyTo,MsgText,KillSent,Pvt,FileAttach,Arq,RRq,ReturnReq,Direct,Cfm,recv from Netmail where direct=1 and sent=0 and Locked=0 order by ToZone,ToNet,ToNode,MessageID",SQL_NTS);
			if ((sqlret==SQL_SUCCESS)||(sqlret==SQL_SUCCESS_WITH_INFO))
			{
				GetNetmailMessages(hstmt,hHeap,&NDOQ);
			}	
			
			sqlret=SQLExecDirectW(hstmt,L"select MessageID,FromZone,FromNet,FromNode,FromPoint,ToZone,ToNet,ToNode,ToPoint,CreateTime,FromName,ToName,Subject,MsgId,ReplyTo,MsgText,KillSent,Pvt,FileAttach,Arq,RRq,ReturnReq,Direct,Cfm,recv from Netmail,MyAka where direct=0 and sent=0 and Locked=0 and MyAka.Point=0 and Netmail.ToPoint<>0 and Netmail.ToZone=MyAka.Zone and Netmail.ToNet=MyAka.Net and Netmail.ToNode=MyAka.Node order by ToPoint,MessageID",SQL_NTS);
			if ((sqlret==SQL_SUCCESS)||(sqlret==SQL_SUCCESS_WITH_INFO))
			{
				GetNetmailMessages(hstmt, hHeap, &NDOQ);
			}	
			
			sqlret = SQLExecDirectW(hstmt, L"select MessageID,FromZone,FromNet,FromNode,FromPoint,ToZone,ToNet,ToNode,ToPoint,CreateTime,FromName,ToName,Subject,MsgId,ReplyTo,MsgText,KillSent,Pvt,FileAttach,Arq,RRq,ReturnReq,Direct,Cfm,recv from Netmail,Links where direct=0 and sent=0 and Locked=0 and Netmail.ToZone=Links.Zone and Netmail.ToNet=Links.Net and Netmail.ToNode=Links.Node and Links.NetmailDirect<>0 and Links.LinkType=2 order by Links.LinkID,MessageID", SQL_NTS);
			if ((sqlret == SQL_SUCCESS) || (sqlret == SQL_SUCCESS_WITH_INFO))
			{
				GetNetmailMessages(hstmt, hHeap, &NDOQ);
			}

			
			LastAddr.FullAddr=0;
			hPktFile=INVALID_HANDLE_VALUE;
			
			while (NDOQ.First!=NULL)
			{
				lpNetmailMessage lpTmp;
				wsprintfW(LogStr,L"Direct netmail From %u:%u/%u.%u To %u:%u/%u.%u",NDOQ.First->FromAddr.zone,NDOQ.First->FromAddr.net,NDOQ.First->FromAddr.node,NDOQ.First->FromAddr.point,NDOQ.First->ToAddr.zone,NDOQ.First->ToAddr.net,NDOQ.First->ToAddr.node,NDOQ.First->ToAddr.point);
				AddLogEntry(LogStr);
				
				if (LastAddr.FullAddr!=NDOQ.First->ToAddr.FullAddr)
				{
					if(LastAddr.FullAddr!=0)
					{
						ClosePktFile(hPktFile);
						CreateDirectoryW(FileboxDirName,NULL);
						MoveFileExW(tmpFileName,finalPktFileName,MOVEFILE_COPY_ALLOWED);
						
					}
					LastAddr.FullAddr=NDOQ.First->ToAddr.FullAddr;
					//create file
					PktNumber=GetPktNumber(hstmt);
					wsprintfW(FileboxDirName, L"%s\\%u.%u.%u.%u", cfg.FileboxesDir, NDOQ.First->ToAddr.zone, NDOQ.First->ToAddr.net, NDOQ.First->ToAddr.node, NDOQ.First->ToAddr.point);
					wsprintfW(tmpFileName, L"%s\\%08X.NETMAIL", cfg.TmpOutboundDir, PktNumber);
					wsprintfW(finalPktFileName,L"%s\\%08X.PKT",FileboxDirName,PktNumber);
					hPktFile=CreateFileW(tmpFileName,GENERIC_READ|GENERIC_WRITE,0,NULL,CREATE_NEW,0,NULL);
					
					
					
					memset(PktPwd, 0, 9);
					SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_USHORT, SQL_SMALLINT, 0, 0, &(NDOQ.First->ToAddr.zone), 0, NULL);
					SQLBindParameter(hstmt, 2, SQL_PARAM_INPUT, SQL_C_USHORT, SQL_SMALLINT, 0, 0, &(NDOQ.First->ToAddr.net), 0, NULL);
					SQLBindParameter(hstmt, 3, SQL_PARAM_INPUT, SQL_C_USHORT, SQL_SMALLINT, 0, 0, &(NDOQ.First->ToAddr.node), 0, NULL);
					SQLBindParameter(hstmt, 4, SQL_PARAM_INPUT, SQL_C_USHORT, SQL_SMALLINT, 0, 0, &(NDOQ.First->ToAddr.point), 0, NULL);
					sqlret = SQLExecDirectW(hstmt, L"Select PktPassword from Links where Zone=? and Net=? and Node=? and Point=?", SQL_NTS);
					if ((sqlret == SQL_SUCCESS) || (sqlret == SQL_SUCCESS_WITH_INFO))
					{
						sqlret = SQLFetch(hstmt);
						if ((sqlret == SQL_SUCCESS) || (sqlret == SQL_SUCCESS_WITH_INFO))
						{
							SQLGetData(hstmt, 1, SQL_C_CHAR, PktPwd, 9, &cb);
						}
					}
					SQLCloseCursor(hstmt);
					SQLFreeStmt(hstmt, SQL_RESET_PARAMS);



					WritePktHeader(hPktFile,&(cfg.MyAddr),&(NDOQ.First->ToAddr),PktPwd); 
					
				}
				//
				WriteNetmailMessage(hPktFile,hHeap,NDOQ.First);
				//
				
				SQLBindParameter(hstmt,1,SQL_PARAM_INPUT,SQL_C_ULONG,SQL_INTEGER,0,0,&(NDOQ.First->MessageID),0,NULL);
				sqlret=SQLExecDirectW(hstmt,L"{call sp_NetmailMessageSent(?)}",SQL_NTS);
				SQLFreeStmt(hstmt,SQL_RESET_PARAMS);

				//
				lpTmp=NDOQ.First->NextMsg;
				HeapFree(hHeap,0,NDOQ.First->MsgText);
				if (NDOQ.First->ReplyTo!=NULL) HeapFree(hHeap,0,NDOQ.First->ReplyTo);
				if (NDOQ.First->MsgId!=NULL) HeapFree(hHeap,0,NDOQ.First->MsgId);
				HeapFree(hHeap,0,NDOQ.First->Subject);
				HeapFree(hHeap,0,NDOQ.First->ToName);
				HeapFree(hHeap,0,NDOQ.First->FromName);
				HeapFree(hHeap,0,NDOQ.First);
				NDOQ.First=lpTmp;
			}

			if (hPktFile!=INVALID_HANDLE_VALUE)
			{
				ClosePktFile(hPktFile);
				CreateDirectoryW(FileboxDirName,NULL);
				MoveFileExW(tmpFileName,finalPktFileName,MOVEFILE_COPY_ALLOWED);
			}

			
			//
			EnterCriticalSection(&NetmailRouteCritSect);
					
			SQLExecDirectW(hstmt, L"EXECUTE sp_RouteNetmail",SQL_NTS);
			
			LeaveCriticalSection(&NetmailRouteCritSect);
			
			SetEvent(cfg.hMailerCallGeneratingEvent);

			//make polls
			sqlret = SQLExecDirectW(hstmt, L"select Zone,Net,Node from Links,NetmailOutbound,Netmail where Links.LinkID=NetmailOutbound.ToLinkID and Netmail.MessageID=NetmailOutbound.MessageID and Netmail.Locked=0 and Links.DialOut<>0 and Links.LinkType<=2 and Links.Point=0", SQL_NTS);
			if ((sqlret == SQL_SUCCESS) || (sqlret == SQL_SUCCESS_WITH_INFO))
			{
				unsigned short zone, net, node;
				SQLBindCol(hstmt, 1, SQL_C_USHORT, &zone, 0, NULL);
				SQLBindCol(hstmt, 2, SQL_C_USHORT, &net, 0, NULL);
				SQLBindCol(hstmt, 3, SQL_C_USHORT, &node, 0, NULL);
				
				sqlret = SQLFetch(hstmt);
				while ((sqlret == SQL_SUCCESS) || (sqlret == SQL_SUCCESS_WITH_INFO))
				{
					if (zone == cfg.MyAddr.zone)
					{
						wsprintfW(LogStr,L"Creating poll to %u:%u/%u", zone, net, node);
						AddLogEntry(LogStr);
												
						swprintf_s(tmpFileName, MAX_PATH, L"%s\\%04hX%04hX.CLO", cfg.BinkOutboundDir, net, node);
						hPktFile = CreateFileW(tmpFileName, GENERIC_ALL, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
						CloseHandle(hPktFile);
						//
					}
					sqlret = SQLFetch(hstmt);
				}
				SQLCloseCursor(hstmt);
				SQLFreeStmt(hstmt, SQL_UNBIND);
			}

	
		}
	}
	goto loop;

threadexit:
	_InterlockedDecrement(&(cfg.ThreadCount));
	SetEvent(cfg.hThreadEndEvent);
	return 0;
}