WarAPI.cpp
上传用户:surprise9
上传日期:2007-01-04
资源大小:426k
文件大小:9k
源码类别:

Ftp客户端

开发平台:

Visual C++

  1. // This is part of the WAR SOFTWARE SERIES initiated by Jarle Aase
  2. // Copyright 1996 by Jarle Aase. All rights reserved.
  3. // See the "War Software Series License Agreement" for details concerning 
  4. // use and distribution.
  5. // ---
  6. // This source code, executables and programs containing source code or
  7. // binaries or proprietetary technology from the War Software Series are
  8. // NOT alloed used, viewed or tested by any governmental agencies in
  9. // any countries. This includes the government, departments, police, 
  10. // military etc.
  11. // ---
  12. // This file is intended for use with Tab space = 2
  13. // Created and maintained in MSVC Developer Studio
  14. // ---
  15. // NAME : WarAPI.cpp
  16. // PURPOSE : Daemon extention dll core
  17. // PROGRAM : 
  18. // DATE : Febr 17 1997
  19. // AUTHOR : Jarle Aase
  20. // ---
  21. // REVISION HISTORY
  22. // 
  23. #include "stdafx.h"
  24. #include "WarSoftware.h"
  25. #ifdef _DEBUG
  26. #define new DEBUG_NEW
  27. #undef THIS_FILE
  28. static char THIS_FILE[] = __FILE__;
  29. #endif
  30. static const LPCSTR KnownFuncNames[] =
  31. {
  32. "?CallApiInitInstance@@YAHPAXHIJ@Z",
  33. "?CallApiExitInstance@@YAHPAXHIJ@Z",
  34. "?CallOnLogin@@YAHPAXHIJ@Z",
  35. "?CallOnLogout@@YAHPAXHIJ@Z",
  36. "?CallOnPassword@@YAHPAXHIJ@Z",
  37. "?CallOnNewSocket@@YAHPAXHIJ@Z",
  38. "?CallOnNewTextSocket@@YAHPAXHIJ@Z",
  39. "?CallOnNewFTPDataSocket@@YAHPAXHIJ@Z",
  40. "?CallOnFTPDCoreCtrlSock@@YAHPAXHIJ@Z",
  41. "?CallOnPreFTPDAccept@@YAHPAXHIJ@Z",
  42. "?CallOnPostFTPDAccept@@YAHPAXHIJ@Z",
  43. };
  44. ////////////////////////////////////////////////////////////////////////////////
  45. // CSocketAPI
  46. CSocketAPI::CSocketAPI()
  47. {
  48. }
  49. CSocketAPI::~CSocketAPI()
  50. {
  51. ASSERT(CAPIHandler::GetPtr() != NULL);
  52. if (CAPIHandler::GetPtr())
  53. CAPIHandler::GetPtr()->Unload(this);
  54. }
  55. ////////////////////////////////////////////////////////////////////////////////
  56. // CFuncList
  57. int CFuncList::Process(int nEvent, WPARAM wParam, LPARAM lParam)
  58. {
  59. int Rval, SuggestRval = 0;
  60. CLinkedListItem *pNext;
  61. for (CLinkedListItem *Item = First(); Item; Item = pNext)
  62. {
  63. pNext = Next(Item);
  64. SFUNC *pFunc = (SFUNC *)Ptr(Item);
  65. Rval = pFunc->pFunc(pFunc->pOrigin, nEvent, wParam, lParam);
  66. if (Rval)
  67. {
  68. switch(Rval)
  69. {
  70. case OkNoNext:
  71. return OkContinue;
  72. case SuggestNo:
  73. case SuggestYes:
  74. SuggestRval = Rval;
  75. break;
  76. default:
  77. return Rval;
  78. }
  79. }
  80. }
  81. if (SuggestRval == SuggestNo)
  82. return AbortError;
  83. return OkContinue;
  84. }
  85. LPVOID CFuncList::Alloc(CDllInfo *pDLL, int Index, CDaemonAPI *pAPI, int (*pCallFunc)(LPVOID,int,WPARAM,LPARAM))
  86. {
  87. SFUNC *pFunc = new SFUNC;
  88. pFunc->pFunc = pCallFunc;
  89. pFunc->pOrigin = pAPI;
  90. SFUNCREF *pFR = new SFUNCREF;
  91. pFR->pFunc = pFunc;
  92. pFR->Index = Index;
  93. pFR->pList = this;
  94. pDLL->m_Refs.AddLast((LPVOID)pFR);
  95. return (LPVOID)pFunc;
  96. }
  97. BOOL CFuncList::AddFirst(CDllInfo *pDLL, int Index, CDaemonAPI *pAPI, int (*pCallFunc)(LPVOID,int,WPARAM,LPARAM))
  98. {
  99. CLinkedList::AddFirst(Alloc(pDLL, Index, pAPI, pCallFunc));
  100. return TRUE;
  101. }
  102. BOOL CFuncList::AddLast(CDllInfo *pDLL, int Index, CDaemonAPI *pAPI, int (*pCallFunc)(LPVOID,int,WPARAM,LPARAM))
  103. {
  104. CLinkedList::AddLast(Alloc(pDLL, Index, pAPI, pCallFunc));
  105. return TRUE;
  106. }
  107. BOOL CFuncList::AddFirst(CDllInfo *pDLL, int Index, CSocketAPI *pAPI, int (*pFunc)(LPVOID,int,WPARAM,LPARAM))
  108. {
  109.  return AddFirst(pDLL, Index, (CDaemonAPI *)pAPI, pFunc);
  110. }
  111. BOOL CFuncList::AddLast(CDllInfo *pDLL, int Index, CSocketAPI *pAPI, int (*pFunc)(LPVOID,int,WPARAM,LPARAM))
  112. {
  113. return AddLast(pDLL, Index, (CDaemonAPI *)pAPI, pFunc);
  114. }
  115. CAPIHandler *CAPIHandler::m_pMe;
  116. CDaemonAPI *CAPIHandler::m_pCurrentLoadingModule;
  117. int CAPIHandler::m_CurrentLoadingModuleNum;
  118. CAPIHandler::CAPIHandler()
  119. {
  120. if (m_pMe)
  121. AfxThrowUserException();
  122. DECLARE_APIHANDLER_OPTIONS
  123. Create(NULL,NULL,"CAPIHandler", COPTION_APIHANDLER);
  124. m_pMe = this;
  125. LoadAll();
  126. }
  127. CAPIHandler::~CAPIHandler()
  128. {
  129. CDllInfo *pDLL;
  130. PrcExt(ApiExitInstance, 0,0,0);
  131. while(pDLL = (CDllInfo *)m_Plugins.FirstPtr())
  132. {
  133. if (pDLL->m_pHI)
  134. FreeLibrary(pDLL->m_pHI);
  135. m_Plugins.GetAndDeleteFirst();
  136. delete pDLL;
  137. }
  138. SaveAll();
  139. m_pMe = NULL;
  140. }
  141. // Load all extentions for this server type
  142. BOOL CAPIHandler::LoadExtentions()
  143. {
  144. CString SrcPath, SrcPathSave;
  145. SrcPath.Format("%s\%s", GetStartupPath(), m_ScanDir);
  146. if (!SrcPath.IsEmpty() && (SrcPath[SrcPath.GetLength() -1] != '\'))
  147. SrcPath += '\';
  148. SrcPathSave = SrcPath;
  149. SrcPath += "*.emod";
  150. HANDLE h;
  151. WIN32_FIND_DATA Data;
  152. if ((h = FindFirstFile(SrcPath,&Data)) != INVALID_HANDLE_VALUE)
  153. {
  154. do
  155. {
  156. CString Name;
  157. Name.Format("%s%s", SrcPathSave, Data.cFileName);
  158. CDaemonStatus *pStat = CDaemonStatus::GetStat();
  159. BOOL DoLoad = GetPrivateProfileInt("type", pStat->m_ServerType, 0, Name)
  160. ||GetPrivateProfileInt("type", "ALL", 0, Name);
  161. DoLoadModule(Name, DoLoad);
  162. } while (FindNextFile(h,&Data));
  163. FindClose(h);
  164. }
  165. PrcExt(ApiInitInstance, 0,0,0);
  166. return TRUE;
  167. }
  168. BOOL CAPIHandler::DoLoadModule(LPCSTR IniName, BOOL DoLoad)
  169. {
  170. CString Name, Path, MgrPath, Descr, bBuf;
  171. HINSTANCE hi = NULL;
  172. m_CurrentLoadingModuleNum = 0;
  173. GetPrivateProfileString("inf", "Filename", "", Path.GetBuffer(MAX_PATH), MAX_PATH, IniName);
  174. GetPrivateProfileString("mgr", "Filename", "", MgrPath.GetBuffer(MAX_PATH), MAX_PATH, IniName);
  175. GetPrivateProfileString("inf", "Name", "", Name.GetBuffer(MAX_PATH), MAX_PATH, IniName);
  176. GetPrivateProfileString("inf", "Descr", "", Descr.GetBuffer(MAX_PATH), MAX_PATH, IniName);
  177. Path.ReleaseBuffer();
  178. MgrPath.ReleaseBuffer();
  179. Name.ReleaseBuffer();
  180. Descr.ReleaseBuffer();
  181. CDllInfo *pDLL = new CDllInfo;
  182. pDLL->m_Name = Name;
  183. pDLL->m_Description = Descr;
  184. pDLL->m_ServerPath = Path;
  185. pDLL->m_ManagerPath = MgrPath;
  186. pDLL->m_pHI = NULL;
  187. pDLL->m_OptionNum = 0;
  188. pDLL->m_pAPI = NULL;
  189. pDLL->m_IniPath = IniName;
  190. if (DoLoad)
  191. {
  192. if (hi = LoadLibrary(Path))
  193. {
  194. CLog::GetLog()->LogMsg(
  195. LOGF_SYSTEM,"Loading extention module %s (%s) %s...", 
  196. Name, Path, Descr);
  197. // Search for functions to use
  198. for(int Index = 0; Index < invalid; Index++)
  199. {
  200. int (*func)(LPVOID,int,WPARAM,LPARAM);
  201. if (func = (int (*)(LPVOID,int,WPARAM,LPARAM))GetProcAddress(hi, KnownFuncNames[Index]))
  202. m_Funcs[Index].AddLast(pDLL, Index, m_pCurrentLoadingModule, func);
  203. }
  204. }
  205. else
  206. {
  207. CLog::GetLog()->LogMsg(
  208. LOGF_ERROR,"Failed to load extention module %s (%s) - %s", 
  209. Path, Path, GetLastErrorText(GetLastError()));
  210. }
  211. }
  212. pDLL->m_pHI = hi;
  213. pDLL->m_OptionNum = m_CurrentLoadingModuleNum;
  214. pDLL->m_pAPI = m_pCurrentLoadingModule;
  215. m_Plugins.AddFirst((LPVOID)pDLL);
  216. return TRUE;
  217. }
  218. // List all known extensions, including verison number
  219. CString CAPIHandler::ListAll()
  220. {
  221. CLinkedListItem *Item;
  222. CString cBuf("Enum, Name, Description, SvrPath, MgrPath"), cTmp;
  223. for(Item = GetPtr()->m_Plugins.First(); Item; Item = GetPtr()->m_Plugins.Next(Item))
  224. {
  225. CDllInfo *pDLL = (CDllInfo *)GetPtr()->m_Plugins.Ptr(Item);
  226. cTmp.Format("n%d 1%s1 1%s1 1%s1 1%s1",
  227. pDLL->m_OptionNum,
  228. pDLL->m_Name,
  229. pDLL->m_Description,
  230. pDLL->m_ServerPath,
  231. pDLL->m_ManagerPath);
  232. cBuf += cTmp;
  233. }
  234. return cBuf;
  235. }
  236. // Unload all entry points used by an extension dll
  237. void CAPIHandler::Unload(CDaemonAPI *pAPI)
  238. {
  239. CLinkedListItem *ApiItem, *Item;
  240. for(ApiItem = m_Plugins.First(); ApiItem; ApiItem = m_Plugins.Next(ApiItem))
  241. {
  242. CDllInfo *pDLL = (CDllInfo *)m_Plugins.Ptr(ApiItem);
  243. if (pDLL->m_pAPI == pAPI)
  244. {
  245. // Found it. Now, unloadd all resources...
  246. for(Item = pDLL->m_Refs.First(); Item;)
  247. {
  248. CLinkedListItem *Curr = Item;
  249. Item = pDLL->m_Refs.Next(Item);
  250. SFUNCREF *pRef = (SFUNCREF *)pDLL->m_Refs.Ptr(Curr);
  251. pRef->pList->DeletePtr(pRef->pFunc);
  252. delete pRef->pFunc;
  253. delete pRef;
  254. pDLL->m_Refs.DeleteItem(Curr);
  255. // Set the dll info to 'list only' state
  256. pDLL->m_pAPI = NULL;
  257. pDLL->m_pHI = NULL;
  258. pDLL->m_OptionNum = 0;
  259. }
  260. break; // No need to test the rest...
  261. }
  262. }
  263. }
  264. // Unload all entry points used by a socket
  265. void CAPIHandler::Unload(CSocketAPI *pSockAPI)
  266. {
  267. CLinkedListItem *ApiItem, *Item;
  268. for(ApiItem = m_Plugins.First(); ApiItem; ApiItem = m_Plugins.Next(ApiItem))
  269. {
  270. CDllInfo *pDLL = (CDllInfo *)m_Plugins.Ptr(ApiItem);
  271. for(Item = pDLL->m_Refs.First(); Item;)
  272. {
  273. CLinkedListItem *Curr = Item;
  274. Item = pDLL->m_Refs.Next(Item);
  275. SFUNCREF *pRef = (SFUNCREF *)pDLL->m_Refs.Ptr(Curr);
  276. if (pRef->pFunc->pOrigin == (CDaemonAPI *)pSockAPI)
  277. {
  278. // Got one!
  279. pRef->pList->DeletePtr(pRef->pFunc); // This deletes the socket's own reference
  280. delete pRef->pFunc;
  281. delete pRef;
  282. pDLL->m_Refs.DeleteItem(Curr);
  283. }
  284. }
  285. }
  286. }
  287. BOOL CAPIHandler::EnableDll(LPCSTR Cmd)
  288. {
  289. CLinkedListItem *Item;
  290. BOOL Enable;
  291. CString Name = Cmd;
  292. CDaemonStatus *pStat = CDaemonStatus::GetStat();
  293. LPSTR p = strchr(Name.GetBuffer(1), '=');
  294. if (!p)
  295. return FALSE;
  296. *p++ = 0;
  297. Enable = atoi(p) != 0;
  298. Name.ReleaseBuffer();
  299. Name.TrimRight();
  300. for(Item = m_Plugins.First(); Item; Item = m_Plugins.Next(Item))
  301. {
  302. CDllInfo *pDLL = (CDllInfo *)m_Plugins.Ptr(Item);
  303. if (!stricmp(pDLL->m_Name, Name))
  304. {
  305. WritePrivateProfileString("type", pStat->m_ServerType, Enable ? "1" : "0", pDLL->m_IniPath);
  306. return TRUE;
  307. }
  308. }
  309. return FALSE;
  310. }