ScpMain.cpp 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. //---------------------------------------------------------------------------
  2. #include <vcl.h>
  3. #pragma hdrstop
  4. #include <stdio.h>
  5. #include "ScpMain.h"
  6. #define PUTTY_DO_GLOBALS
  7. #include "PuttyIntf.h"
  8. #include "Common.h"
  9. #include "Interface.h"
  10. #include "Configuration.h"
  11. #include "Terminal.h"
  12. #include "Net.h"
  13. //---------------------------------------------------------------------------
  14. #pragma package(smart_init)
  15. //---------------------------------------------------------------------------
  16. #define CATCH(command) \
  17. try {command;} catch (Exception &E) {ShowExtendedException(&E);}
  18. //---------------------------------------------------------------------------
  19. TConfiguration *Configuration;
  20. TStoredSessionList *StoredSessions;
  21. TCriticalSection * CoreCriticalSection = NULL;
  22. CRITICAL_SECTION noise_section;
  23. //---------------------------------------------------------------------------
  24. TCoreGuard::TCoreGuard() : TGuard(CoreCriticalSection)
  25. {
  26. }
  27. //---------------------------------------------------------------------------
  28. #ifdef SCP_CONSOLE
  29. /* TODO 1 : Won't be needed (while debuggin we hang TSessionLog::OnAddLine to it) */
  30. class TCallExceptionClass : public TObject
  31. {
  32. public:
  33. void __fastcall PrintLine(TObject* Sender, const AnsiString Line);
  34. void __fastcall QueryUser(TObject* Sender, const AnsiString Query, int Answers,
  35. const Boolean FatalAbort, int & Answer);
  36. void __fastcall ShowException(TObject* Sender, Exception* E);
  37. };
  38. //---------------------------------------------------------------------------
  39. TCallExceptionClass *CallExceptionClass;
  40. //---------------------------------------------------------------------------
  41. void __fastcall TCallExceptionClass::ShowException(TObject* Sender, Exception* E)
  42. {
  43. ShowExtendedException(E);
  44. }
  45. //---------------------------------------------------------------------------
  46. void __fastcall TCallExceptionClass::PrintLine(TObject* Sender, const AnsiString Line)
  47. {
  48. // Used for debugging (e.g. hanged to TSessionLog::OnAddLine);
  49. puts(Line.c_str());
  50. }
  51. //---------------------------------------------------------------------------
  52. void __fastcall TCallExceptionClass::QueryUser(TObject* Sender, const AnsiString Query,
  53. int Answers, const bool FatalAbort, int & Answer)
  54. {
  55. /* TODO : QueryUser: user FatalAbort parametr */
  56. Answer = MessageDialog(Query, mtConfirmation, Answers, 0);
  57. }
  58. #endif
  59. //---------------------------------------------------------------------------
  60. TQueryParams::TQueryParams(unsigned int AParams, AnsiString AHelpKeyword)
  61. {
  62. Params = AParams;
  63. Aliases = NULL;
  64. AliasesCount = 0;
  65. Timer = NULL;
  66. TimerEvent = NULL;
  67. TimerAnswers = 0;
  68. HelpKeyword = AHelpKeyword;
  69. }
  70. //---------------------------------------------------------------------------
  71. void Initialize(const AnsiString IniFileName)
  72. {
  73. // initialize default seed path value same way as putty does (only change filename)
  74. putty_get_seedpath();
  75. InitializeCriticalSection(&noise_section);
  76. flags = FLAG_VERBOSE | FLAG_SYNCAGENT; // verbose log
  77. default_protocol = ptSSH;
  78. default_port = 22;
  79. Randomize();
  80. CoreCriticalSection = new TCriticalSection();
  81. #ifdef SCP_CONSOLE
  82. CallExceptionClass = new TCallExceptionClass();
  83. Application->OnException = CallExceptionClass->ShowException;
  84. #endif
  85. Configuration = CreateConfiguration();
  86. if (!IniFileName.IsEmpty()) Configuration->IniFileStorageName = IniFileName;
  87. CATCH( Configuration->Load(); );
  88. StoredSessions = new TStoredSessionList();
  89. CATCH( StoredSessions->Load(); );
  90. }
  91. //---------------------------------------------------------------------------
  92. void Finalize()
  93. {
  94. delete StoredSessions;
  95. StoredSessions = NULL;
  96. Configuration->Save();
  97. delete Configuration;
  98. Configuration = NULL;
  99. #ifdef SCP_CONSOLE
  100. Application->OnException = NULL;
  101. delete CallExceptionClass;
  102. CallExceptionClass = NULL;
  103. #endif
  104. delete CoreCriticalSection;
  105. CoreCriticalSection = NULL;
  106. DeleteCriticalSection(&noise_section);
  107. }
  108. //---------------------------------------------------------------------------
  109. static long OpenWinSCPKey(HKEY Key, const char * SubKey, HKEY * Result, bool CanCreate)
  110. {
  111. // This is called once even before Configuration is created
  112. // (see Initialize()) from get_seedpath() (winstore.c).
  113. // In that case we don't mind that it's looked for in Putty regkey,
  114. // it's even better.
  115. long R;
  116. if (Configuration != NULL)
  117. {
  118. assert(Key == HKEY_CURRENT_USER);
  119. AnsiString RegKey = SubKey;
  120. int PuttyKeyLen = Configuration->PuttyRegistryStorageKey.Length();
  121. assert(RegKey.SubString(1, PuttyKeyLen) == Configuration->PuttyRegistryStorageKey);
  122. RegKey = RegKey.SubString(PuttyKeyLen + 1, RegKey.Length() - PuttyKeyLen);
  123. if (!RegKey.IsEmpty())
  124. {
  125. assert(RegKey[1] == '\\');
  126. RegKey.Delete(1, 1);
  127. }
  128. // we expect this to be called only from verify_host_key() or store_host_key()
  129. assert(RegKey == "SshHostKeys");
  130. THierarchicalStorage * Storage = Configuration->CreateScpStorage(false);
  131. Storage->AccessMode = (CanCreate ? smReadWrite : smRead);
  132. if (Storage->OpenSubKey(RegKey, CanCreate))
  133. {
  134. *Result = static_cast<HKEY>(Storage);
  135. R = ERROR_SUCCESS;
  136. }
  137. else
  138. {
  139. delete Storage;
  140. R = ERROR_CANTOPEN;
  141. }
  142. }
  143. else
  144. {
  145. if (CanCreate)
  146. {
  147. R = RegCreateKey(Key, SubKey, Result);
  148. }
  149. else
  150. {
  151. R = RegOpenKey(Key, SubKey, Result);
  152. }
  153. }
  154. return R;
  155. }
  156. //---------------------------------------------------------------------------
  157. long RegOpenWinSCPKey(HKEY Key, const char * SubKey, HKEY * Result)
  158. {
  159. return OpenWinSCPKey(Key, SubKey, Result, false);
  160. }
  161. //---------------------------------------------------------------------------
  162. long RegCreateWinSCPKey(HKEY Key, const char * SubKey, HKEY * Result)
  163. {
  164. return OpenWinSCPKey(Key, SubKey, Result, true);
  165. }
  166. //---------------------------------------------------------------------------
  167. long RegQueryWinSCPValueEx(HKEY Key, const char * ValueName, unsigned long * Reserved,
  168. unsigned long * Type, unsigned char * Data, unsigned long * DataSize)
  169. {
  170. long R;
  171. if (Configuration != NULL)
  172. {
  173. THierarchicalStorage * Storage = static_cast<THierarchicalStorage *>(Key);
  174. if (Storage->ValueExists(ValueName))
  175. {
  176. AnsiString Value;
  177. Value = Storage->ReadStringRaw(ValueName, "");
  178. assert(Type != NULL);
  179. *Type = REG_SZ;
  180. char * DataStr = reinterpret_cast<char *>(Data);
  181. strncpy(DataStr, Value.c_str(), *DataSize);
  182. DataStr[*DataSize - 1] = '\0';
  183. *DataSize = strlen(DataStr);
  184. R = ERROR_SUCCESS;
  185. }
  186. else
  187. {
  188. R = ERROR_READ_FAULT;
  189. }
  190. }
  191. else
  192. {
  193. R = RegQueryValueEx(Key, ValueName, Reserved, Type, Data, DataSize);
  194. }
  195. return R;
  196. }
  197. //---------------------------------------------------------------------------
  198. long RegSetWinSCPValueEx(HKEY Key, const char * ValueName, unsigned long Reserved,
  199. unsigned long Type, const unsigned char * Data, unsigned long DataSize)
  200. {
  201. long R;
  202. if (Configuration != NULL)
  203. {
  204. assert(Type == REG_SZ);
  205. THierarchicalStorage * Storage = static_cast<THierarchicalStorage *>(Key);
  206. AnsiString Value(reinterpret_cast<const char*>(Data), DataSize - 1);
  207. Storage->WriteStringRaw(ValueName, Value);
  208. R = ERROR_SUCCESS;
  209. }
  210. else
  211. {
  212. R = RegSetValueEx(Key, ValueName, Reserved, Type, Data, DataSize);
  213. }
  214. return R;
  215. }
  216. //---------------------------------------------------------------------------
  217. long RegCloseWinSCPKey(HKEY Key)
  218. {
  219. long R;
  220. if (Configuration != NULL)
  221. {
  222. THierarchicalStorage * Storage = static_cast<THierarchicalStorage *>(Key);
  223. delete Storage;
  224. R = ERROR_SUCCESS;
  225. }
  226. else
  227. {
  228. R = RegCloseKey(Key);
  229. }
  230. return R;
  231. }
  232. //---------------------------------------------------------------------------