Common.cpp 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952
  1. //---------------------------------------------------------------------------
  2. #include <vcl.h>
  3. #pragma hdrstop
  4. #include "Common.h"
  5. #include "Exceptions.h"
  6. #include "TextsCore.h"
  7. #include "Interface.h"
  8. #include <math.h>
  9. #include <shellapi.h>
  10. //---------------------------------------------------------------------------
  11. #pragma package(smart_init)
  12. //---------------------------------------------------------------------------
  13. #ifdef _DEBUG
  14. #include <stdio.h>
  15. void __fastcall Trace(const AnsiString SourceFile, const AnsiString Func,
  16. int Line, const AnsiString Message)
  17. {
  18. const char * FileName = getenv(TRACEENV);
  19. //!!!
  20. if (FileName == NULL)
  21. {
  22. FileName = "C:\\winscptrace.log";
  23. }
  24. //!!!
  25. if (FileName != NULL)
  26. {
  27. FILE * File = fopen(FileName, "a");
  28. if (File != NULL)
  29. {
  30. fprintf(File, "[%s] %s:%d:%s\n %s\n",
  31. Now().TimeString().c_str(),
  32. ExtractFileName(SourceFile).c_str(), Line, Func.c_str(), Message.c_str());
  33. fclose(File);
  34. }
  35. }
  36. }
  37. #endif // ifdef _DEBUG
  38. //---------------------------------------------------------------------------
  39. // TCriticalSection
  40. //---------------------------------------------------------------------------
  41. __fastcall TCriticalSection::TCriticalSection()
  42. {
  43. InitializeCriticalSection(&FSection);
  44. }
  45. //---------------------------------------------------------------------------
  46. __fastcall TCriticalSection::~TCriticalSection()
  47. {
  48. DeleteCriticalSection(&FSection);
  49. }
  50. //---------------------------------------------------------------------------
  51. void __fastcall TCriticalSection::Enter()
  52. {
  53. EnterCriticalSection(&FSection);
  54. }
  55. //---------------------------------------------------------------------------
  56. void __fastcall TCriticalSection::Leave()
  57. {
  58. LeaveCriticalSection(&FSection);
  59. }
  60. //---------------------------------------------------------------------------
  61. // TGuard
  62. //---------------------------------------------------------------------------
  63. __fastcall TGuard::TGuard(TCriticalSection * ACriticalSection) :
  64. FCriticalSection(ACriticalSection)
  65. {
  66. assert(ACriticalSection != NULL);
  67. FCriticalSection->Enter();
  68. }
  69. //---------------------------------------------------------------------------
  70. __fastcall TGuard::~TGuard()
  71. {
  72. FCriticalSection->Leave();
  73. }
  74. //---------------------------------------------------------------------------
  75. // TUnguard
  76. //---------------------------------------------------------------------------
  77. __fastcall TUnguard::TUnguard(TCriticalSection * ACriticalSection) :
  78. FCriticalSection(ACriticalSection)
  79. {
  80. assert(ACriticalSection != NULL);
  81. FCriticalSection->Leave();
  82. }
  83. //---------------------------------------------------------------------------
  84. __fastcall TUnguard::~TUnguard()
  85. {
  86. FCriticalSection->Enter();
  87. }
  88. //---------------------------------------------------------------------------
  89. //---------------------------------------------------------------------------
  90. const char EngShortMonthNames[12][4] =
  91. {"Jan", "Feb", "Mar", "Apr", "May", "Jun",
  92. "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
  93. //---------------------------------------------------------------------------
  94. AnsiString ReplaceChar(AnsiString Str, Char A, Char B)
  95. {
  96. for (Integer Index = 0; Index < Str.Length(); Index++)
  97. if (Str[Index+1] == A) Str[Index+1] = B;
  98. return Str;
  99. }
  100. //---------------------------------------------------------------------------
  101. AnsiString DeleteChar(AnsiString Str, Char C)
  102. {
  103. int P;
  104. while ((P = Str.Pos(C)) > 0)
  105. {
  106. Str.Delete(P, 1);
  107. }
  108. return Str;
  109. }
  110. //---------------------------------------------------------------------------
  111. void PackStr(AnsiString &Str)
  112. {
  113. // Following will free unnecessary bytes
  114. Str = Str.c_str();
  115. }
  116. //---------------------------------------------------------------------------
  117. AnsiString MakeValidFileName(AnsiString FileName)
  118. {
  119. AnsiString IllegalChars = ";,=+<>|\"[] \\/?*";
  120. for (int Index = 0; Index < IllegalChars.Length(); Index++)
  121. {
  122. ReplaceChar(FileName, IllegalChars[Index+1], '-');
  123. }
  124. return FileName;
  125. }
  126. //---------------------------------------------------------------------------
  127. AnsiString RootKeyToStr(HKEY RootKey)
  128. {
  129. if (RootKey == HKEY_USERS) return "HKEY_USERS";
  130. else
  131. if (RootKey == HKEY_LOCAL_MACHINE) return "HKEY_LOCAL_MACHINE";
  132. else
  133. if (RootKey == HKEY_CURRENT_USER) return "HKEY_CURRENT_USER";
  134. else
  135. if (RootKey == HKEY_CLASSES_ROOT) return "HKEY_CLASSES_ROOT";
  136. else
  137. if (RootKey == HKEY_CURRENT_CONFIG) return "HKEY_CURRENT_CONFIG";
  138. else
  139. if (RootKey == HKEY_DYN_DATA) return "HKEY_DYN_DATA";
  140. else
  141. { Abort(); return ""; };
  142. }
  143. //---------------------------------------------------------------------------
  144. AnsiString BooleanToEngStr(bool B)
  145. {
  146. return B ? "Yes" : "No";
  147. }
  148. //---------------------------------------------------------------------------
  149. AnsiString BooleanToStr(bool B)
  150. {
  151. return B ? LoadStr(YES_STR) : LoadStr(NO_STR);
  152. }
  153. //---------------------------------------------------------------------------
  154. AnsiString CutToChar(AnsiString &Str, Char Ch, bool Trim)
  155. {
  156. Integer P = Str.Pos(Ch);
  157. AnsiString Result;
  158. if (P)
  159. {
  160. Result = Str.SubString(1, P-1);
  161. Str.Delete(1, P);
  162. }
  163. else
  164. {
  165. Result = Str;
  166. Str = "";
  167. }
  168. if (Trim)
  169. {
  170. Result = Result.TrimRight();
  171. Str = Str.TrimLeft();
  172. }
  173. return Result;
  174. }
  175. //---------------------------------------------------------------------------
  176. AnsiString ExceptionLogString(Exception *E)
  177. {
  178. assert(E);
  179. if (E->InheritsFrom(__classid(Exception)))
  180. {
  181. AnsiString Msg;
  182. Msg = FORMAT("(%s) %s", (E->ClassName(), E->Message));
  183. if (E->InheritsFrom(__classid(ExtException)))
  184. {
  185. TStrings * MoreMessages = ((ExtException*)E)->MoreMessages;
  186. if (MoreMessages)
  187. {
  188. Msg += "\n" +
  189. StringReplace(MoreMessages->Text, "\r", "", TReplaceFlags() << rfReplaceAll);
  190. }
  191. }
  192. return Msg;
  193. }
  194. else
  195. {
  196. char Buffer[1024];
  197. ExceptionErrorMessage(ExceptObject(), ExceptAddr(), Buffer, sizeof(Buffer));
  198. return AnsiString(Buffer);
  199. }
  200. }
  201. //---------------------------------------------------------------------------
  202. bool IsDots(const AnsiString Str)
  203. {
  204. char * str = Str.c_str();
  205. return (str[strspn(str, ".")] == '\0');
  206. }
  207. //---------------------------------------------------------------------------
  208. AnsiString __fastcall SystemTemporaryDirectory()
  209. {
  210. AnsiString TempDir;
  211. TempDir.SetLength(MAX_PATH);
  212. TempDir.SetLength(GetTempPath(MAX_PATH, TempDir.c_str()));
  213. return TempDir;
  214. }
  215. //---------------------------------------------------------------------------
  216. AnsiString __fastcall StripPathQuotes(const AnsiString Path)
  217. {
  218. if ((Path.Length() >= 2) &&
  219. (Path[1] == '\"') && (Path[Path.Length()] == '\"'))
  220. {
  221. return Path.SubString(2, Path.Length() - 2);
  222. }
  223. else
  224. {
  225. return Path;
  226. }
  227. }
  228. //---------------------------------------------------------------------------
  229. AnsiString __fastcall AddPathQuotes(AnsiString Path)
  230. {
  231. Path = StripPathQuotes(Path);
  232. if (Path.Pos(" "))
  233. {
  234. Path = "\"" + Path + "\"";
  235. }
  236. return Path;
  237. }
  238. //---------------------------------------------------------------------------
  239. void __fastcall SplitCommand(AnsiString Command, AnsiString &Program,
  240. AnsiString & Params, AnsiString & Dir)
  241. {
  242. Command = Command.Trim();
  243. Params = "";
  244. Dir = "";
  245. if (!Command.IsEmpty() && (Command[1] == '\"'))
  246. {
  247. Command.Delete(1, 1);
  248. int P = Command.Pos('"');
  249. if (P)
  250. {
  251. Program = Command.SubString(1, P-1).Trim();
  252. Params = Command.SubString(P + 1, Command.Length() - P).Trim();
  253. }
  254. else
  255. {
  256. throw Exception(FMTLOAD(INVALID_SHELL_COMMAND, ("\"" + Command)));
  257. }
  258. }
  259. else
  260. {
  261. int P = Command.Pos(" ");
  262. if (P)
  263. {
  264. Program = Command.SubString(1, P).Trim();
  265. Params = Command.SubString(P + 1, Command.Length() - P).Trim();
  266. }
  267. else
  268. {
  269. Program = Command;
  270. }
  271. }
  272. int B = Program.LastDelimiter("\\/");
  273. if (B)
  274. {
  275. Dir = Program.SubString(1, B).Trim();
  276. }
  277. }
  278. //---------------------------------------------------------------------------
  279. AnsiString __fastcall ExtractProgram(AnsiString Command)
  280. {
  281. AnsiString Program;
  282. AnsiString Params;
  283. AnsiString Dir;
  284. SplitCommand(Command, Program, Params, Dir);
  285. return Program;
  286. }
  287. //---------------------------------------------------------------------------
  288. AnsiString __fastcall FormatCommand(AnsiString Program, AnsiString Params)
  289. {
  290. Program = Program.Trim();
  291. Params = Params.Trim();
  292. if (!Params.IsEmpty()) Params = " " + Params;
  293. if (Program.Pos(" ")) Program = "\"" + Program + "\"";
  294. return Program + Params;
  295. }
  296. //---------------------------------------------------------------------------
  297. bool __fastcall IsDisplayableStr(const AnsiString Str)
  298. {
  299. bool Displayable = true;
  300. int Index = 1;
  301. while ((Index <= Str.Length()) && Displayable)
  302. {
  303. if (Str[Index] < '\32')
  304. {
  305. Displayable = false;
  306. }
  307. Index++;
  308. }
  309. return Displayable;
  310. }
  311. //---------------------------------------------------------------------------
  312. AnsiString __fastcall StrToHex(const AnsiString Str)
  313. {
  314. AnsiString Result;
  315. for (int i = 1; i <= Str.Length(); i++)
  316. {
  317. Result += IntToHex(Str[i], 2);
  318. }
  319. return Result;
  320. }
  321. //---------------------------------------------------------------------------
  322. AnsiString __fastcall HexToStr(const AnsiString Hex)
  323. {
  324. static AnsiString Digits = "0123456789ABCDEF";
  325. AnsiString Result;
  326. int L, P1, P2;
  327. L = Hex.Length();
  328. if (L % 2 == 0)
  329. {
  330. for (int i = 1; i <= Hex.Length(); i += 2)
  331. {
  332. P1 = Digits.Pos(Hex[i]);
  333. P2 = Digits.Pos(Hex[i + 1]);
  334. if (P1 <= 0 || P2 <= 0)
  335. {
  336. break;
  337. }
  338. else
  339. {
  340. Result += static_cast<char>((P1 - 1) * 16 + P2 - 1);
  341. }
  342. }
  343. }
  344. return Result;
  345. }
  346. //---------------------------------------------------------------------------
  347. unsigned int __fastcall HexToInt(const AnsiString Hex)
  348. {
  349. static AnsiString Digits = "0123456789ABCDEF";
  350. int Result = 0;
  351. int I = 1;
  352. while (I <= Hex.Length())
  353. {
  354. int A = Digits.Pos(Hex[I]);
  355. if (A <= 0)
  356. {
  357. break;
  358. }
  359. Result = (Result * 16) + (A - 1);
  360. I++;
  361. }
  362. return Result;
  363. }
  364. //---------------------------------------------------------------------------
  365. bool __fastcall FileSearchRec(const AnsiString FileName, TSearchRec & Rec)
  366. {
  367. int FindAttrs = faReadOnly | faHidden | faSysFile | faDirectory | faArchive;
  368. bool Result = (FindFirst(FileName, FindAttrs, Rec) == 0);
  369. if (Result)
  370. {
  371. FindClose(Rec);
  372. }
  373. return Result;
  374. }
  375. //---------------------------------------------------------------------------
  376. void __fastcall ProcessLocalDirectory(AnsiString DirName,
  377. TProcessLocalFileEvent CallBackFunc, void * Param,
  378. int FindAttrs)
  379. {
  380. assert(CallBackFunc);
  381. if (FindAttrs < 0)
  382. {
  383. FindAttrs = faReadOnly | faHidden | faSysFile | faDirectory | faArchive;
  384. }
  385. TSearchRec SearchRec;
  386. DirName = IncludeTrailingBackslash(DirName);
  387. if (FindFirst(DirName + "*.*", FindAttrs, SearchRec) == 0)
  388. {
  389. try
  390. {
  391. do
  392. {
  393. if ((SearchRec.Name != ".") && (SearchRec.Name != ".."))
  394. {
  395. CallBackFunc(DirName + SearchRec.Name, SearchRec, Param);
  396. }
  397. } while (FindNext(SearchRec) == 0);
  398. }
  399. __finally
  400. {
  401. FindClose(SearchRec);
  402. }
  403. }
  404. }
  405. //---------------------------------------------------------------------------
  406. struct TDateTimeParams
  407. {
  408. TDateTime UnixEpoch;
  409. double BaseDifference;
  410. long BaseDifferenceSec;
  411. double CurrentDaylightDifference;
  412. long CurrentDaylightDifferenceSec;
  413. double CurrentDifference;
  414. long CurrentDifferenceSec;
  415. double StandardDifference;
  416. long StandardDifferenceSec;
  417. double DaylightDifference;
  418. long DaylightDifferenceSec;
  419. SYSTEMTIME StandardDate;
  420. SYSTEMTIME DaylightDate;
  421. };
  422. static bool DateTimeParamsInitialized = false;
  423. static TDateTimeParams DateTimeParams;
  424. static TCriticalSection DateTimeParamsSection;
  425. //---------------------------------------------------------------------------
  426. static TDateTimeParams * __fastcall GetDateTimeParams()
  427. {
  428. if (!DateTimeParamsInitialized)
  429. {
  430. TGuard Guard(&DateTimeParamsSection);
  431. if (!DateTimeParamsInitialized)
  432. {
  433. TIME_ZONE_INFORMATION TZI;
  434. unsigned long GTZI;
  435. GTZI = GetTimeZoneInformation(&TZI);
  436. switch (GTZI)
  437. {
  438. case TIME_ZONE_ID_UNKNOWN:
  439. DateTimeParams.CurrentDifferenceSec = 0;
  440. DateTimeParams.CurrentDaylightDifferenceSec = 0;
  441. break;
  442. case TIME_ZONE_ID_STANDARD:
  443. DateTimeParams.CurrentDaylightDifferenceSec = TZI.StandardBias;
  444. break;
  445. case TIME_ZONE_ID_DAYLIGHT:
  446. DateTimeParams.CurrentDaylightDifferenceSec = TZI.DaylightBias;
  447. break;
  448. case TIME_ZONE_ID_INVALID:
  449. default:
  450. throw Exception(TIMEZONE_ERROR);
  451. }
  452. // Is it same as SysUtils::UnixDateDelta = 25569 ??
  453. DateTimeParams.UnixEpoch = EncodeDate(1970, 1, 1);
  454. DateTimeParams.BaseDifferenceSec = TZI.Bias;
  455. DateTimeParams.BaseDifference = double(TZI.Bias) / 1440;
  456. DateTimeParams.BaseDifferenceSec *= 60;
  457. DateTimeParams.CurrentDifferenceSec = TZI.Bias +
  458. DateTimeParams.CurrentDaylightDifferenceSec;
  459. DateTimeParams.CurrentDifference =
  460. double(DateTimeParams.CurrentDifferenceSec) / 1440;
  461. DateTimeParams.CurrentDifferenceSec *= 60;
  462. DateTimeParams.CurrentDaylightDifference =
  463. double(DateTimeParams.CurrentDaylightDifferenceSec) / 1440;
  464. DateTimeParams.CurrentDaylightDifferenceSec *= 60;
  465. DateTimeParams.DaylightDifferenceSec = TZI.DaylightBias * 60;
  466. DateTimeParams.DaylightDifference = double(TZI.DaylightBias) / 1440;
  467. DateTimeParams.StandardDifferenceSec = TZI.StandardBias * 60;
  468. DateTimeParams.StandardDifference = double(TZI.StandardBias) / 1440;
  469. DateTimeParams.StandardDate = TZI.StandardDate;
  470. DateTimeParams.DaylightDate = TZI.DaylightDate;
  471. DateTimeParamsInitialized = true;
  472. }
  473. }
  474. return &DateTimeParams;
  475. }
  476. //---------------------------------------------------------------------------
  477. static void __fastcall EncodeDSTMargin(const SYSTEMTIME & Date, unsigned short Year,
  478. TDateTime & Result)
  479. {
  480. if (Date.wYear == 0)
  481. {
  482. TDateTime Temp = EncodeDate(Year, Date.wMonth, 1);
  483. Result = Temp + ((Date.wDayOfWeek - DayOfWeek(Temp) + 8) % 7) +
  484. (7 * (Date.wDay - 1));
  485. if (Date.wDay == 5)
  486. {
  487. unsigned short Month = static_cast<unsigned short>(Date.wMonth + 1);
  488. if (Month > 12)
  489. {
  490. Month = static_cast<unsigned short>(Month - 12);
  491. Year++;
  492. }
  493. if (Result > EncodeDate(Year, Month, 1))
  494. {
  495. Result -= 7;
  496. }
  497. }
  498. Result += EncodeTime(Date.wHour, Date.wMinute, Date.wSecond,
  499. Date.wMilliseconds);
  500. }
  501. else
  502. {
  503. Result = EncodeDate(Year, Date.wMonth, Date.wDay) +
  504. EncodeTime(Date.wHour, Date.wMinute, Date.wSecond, Date.wMilliseconds);
  505. }
  506. }
  507. //---------------------------------------------------------------------------
  508. static bool __fastcall IsDateInDST(const TDateTime & DateTime)
  509. {
  510. struct TDSTCache
  511. {
  512. bool Filled;
  513. unsigned short Year;
  514. TDateTime StandardDate;
  515. TDateTime DaylightDate;
  516. };
  517. static TDSTCache DSTCache[10];
  518. static int DSTCacheCount = 0;
  519. static TCriticalSection Section;
  520. TDateTimeParams * Params = GetDateTimeParams();
  521. bool Result;
  522. if (Params->StandardDate.wMonth == 0)
  523. {
  524. Result = false;
  525. }
  526. else
  527. {
  528. unsigned short Year, Month, Day;
  529. DecodeDate(DateTime, Year, Month, Day);
  530. TDSTCache * CurrentCache = &DSTCache[0];
  531. int CacheIndex = 0;
  532. while ((CacheIndex < DSTCacheCount) && (CacheIndex < LENOF(DSTCache)) &&
  533. CurrentCache->Filled && (CurrentCache->Year != Year))
  534. {
  535. CacheIndex++;
  536. CurrentCache++;
  537. }
  538. if ((CacheIndex < DSTCacheCount) && (CacheIndex < LENOF(DSTCache)) &&
  539. CurrentCache->Filled)
  540. {
  541. assert(CurrentCache->Year == Year);
  542. Result = (DateTime >= CurrentCache->DaylightDate) &&
  543. (DateTime < CurrentCache->StandardDate);
  544. }
  545. else
  546. {
  547. TDSTCache NewCache;
  548. EncodeDSTMargin(Params->StandardDate, Year, NewCache.StandardDate);
  549. EncodeDSTMargin(Params->DaylightDate, Year, NewCache.DaylightDate);
  550. AnsiString SD = FormatDateTime("dddddd tt", NewCache.StandardDate);
  551. AnsiString DD = FormatDateTime("dddddd tt", NewCache.DaylightDate);
  552. if (DSTCacheCount < LENOF(DSTCache))
  553. {
  554. TGuard Guard(&Section);
  555. if (DSTCacheCount < LENOF(DSTCache))
  556. {
  557. NewCache.Year = Year;
  558. DSTCache[DSTCacheCount] = NewCache;
  559. DSTCache[DSTCacheCount].Filled = true;
  560. DSTCacheCount++;
  561. }
  562. }
  563. Result = (DateTime >= NewCache.DaylightDate) &&
  564. (DateTime < NewCache.StandardDate);
  565. }
  566. }
  567. return Result;
  568. }
  569. //---------------------------------------------------------------------------
  570. TDateTime __fastcall UnixToDateTime(__int64 TimeStamp, bool ConsiderDST)
  571. {
  572. TDateTimeParams * Params = GetDateTimeParams();
  573. TDateTime Result;
  574. Result = Params->UnixEpoch + (double(TimeStamp) / 86400) - Params->CurrentDifference;
  575. if (ConsiderDST)
  576. {
  577. Result -= (IsDateInDST(Result) ?
  578. Params->DaylightDifference : Params->StandardDifference);
  579. }
  580. return Result;
  581. }
  582. //---------------------------------------------------------------------------
  583. inline __int64 __fastcall Round(double Number)
  584. {
  585. double Floor = floor(Number);
  586. double Ceil = ceil(Number);
  587. return ((Number - Floor) > (Ceil - Number)) ? Ceil : Floor;
  588. }
  589. //---------------------------------------------------------------------------
  590. #define TIME_POSIX_TO_WIN(t, ft) (*(LONGLONG*)&(ft) = \
  591. ((LONGLONG) (t) + (LONGLONG) 11644473600) * (LONGLONG) 10000000)
  592. #define TIME_WIN_TO_POSIX(ft, t) ((t) = (__int64) \
  593. ((*(LONGLONG*)&(ft)) / (LONGLONG) 10000000 - (LONGLONG) 11644473600))
  594. //---------------------------------------------------------------------------
  595. FILETIME __fastcall DateTimeToFileTime(const TDateTime DateTime,
  596. bool /*ConsiderDST*/)
  597. {
  598. TDateTimeParams * Params = GetDateTimeParams();
  599. __int64 UnixTimeStamp;
  600. FILETIME Result;
  601. UnixTimeStamp = Round(double(DateTime - Params->UnixEpoch) * 86400) +
  602. Params->CurrentDifferenceSec;
  603. TIME_POSIX_TO_WIN(UnixTimeStamp, Result);
  604. return Result;
  605. }
  606. //---------------------------------------------------------------------------
  607. __int64 __fastcall ConvertTimestampToUnix(const FILETIME & FileTime,
  608. bool ConsiderDST)
  609. {
  610. __int64 Result;
  611. TIME_WIN_TO_POSIX(FileTime, Result);
  612. if (ConsiderDST)
  613. {
  614. FILETIME LocalFileTime;
  615. SYSTEMTIME SystemTime;
  616. TDateTime DateTime;
  617. FileTimeToLocalFileTime(&FileTime, &LocalFileTime);
  618. FileTimeToSystemTime(&LocalFileTime, &SystemTime);
  619. DateTime = SystemTimeToDateTime(SystemTime);
  620. TDateTimeParams * Params = GetDateTimeParams();
  621. Result += (IsDateInDST(DateTime) ?
  622. Params->DaylightDifferenceSec : Params->StandardDifferenceSec);
  623. }
  624. return Result;
  625. }
  626. //---------------------------------------------------------------------------
  627. TDateTime __fastcall AdjustDateTimeFromUnix(TDateTime DateTime, bool ConsiderDST)
  628. {
  629. TDateTimeParams * Params = GetDateTimeParams();
  630. DateTime = DateTime - Params->CurrentDaylightDifference;
  631. bool IsInDST = IsDateInDST(DateTime);
  632. // shift always, even with ConsiderDST == false
  633. DateTime = DateTime - (!IsInDST ? Params->DaylightDifference :
  634. Params->StandardDifference);
  635. if (ConsiderDST)
  636. {
  637. if (IsInDST)
  638. {
  639. //DateTime = DateTime - Params->DaylightDifference;
  640. }
  641. else
  642. {
  643. DateTime = DateTime + Params->DaylightDifference;
  644. }
  645. }
  646. return DateTime;
  647. }
  648. //---------------------------------------------------------------------------
  649. __inline static bool __fastcall UnifySignificance(unsigned short & V1,
  650. unsigned short & V2)
  651. {
  652. bool Result = (V1 == 0) || (V2 == 0);
  653. if (Result)
  654. {
  655. V1 = 0;
  656. V2 = 0;
  657. }
  658. return Result;
  659. }
  660. //---------------------------------------------------------------------------
  661. void __fastcall UnifyDateTimePrecision(TDateTime & DateTime1, TDateTime & DateTime2)
  662. {
  663. unsigned short Y1, M1, D1, H1, N1, S1, MS1;
  664. unsigned short Y2, M2, D2, H2, N2, S2, MS2;
  665. bool Changed;
  666. if (DateTime1 != DateTime2)
  667. {
  668. DateTime1.DecodeDate(&Y1, &M1, &D1);
  669. DateTime1.DecodeTime(&H1, &N1, &S1, &MS1);
  670. DateTime2.DecodeDate(&Y2, &M2, &D2);
  671. DateTime2.DecodeTime(&H2, &N2, &S2, &MS2);
  672. Changed = UnifySignificance(MS1, MS2);
  673. if (Changed && UnifySignificance(S1, S2) && UnifySignificance(N1, N2) &&
  674. UnifySignificance(H1, H2) && UnifySignificance(D1, D2) &&
  675. UnifySignificance(M1, M2))
  676. {
  677. UnifySignificance(Y1, Y2);
  678. }
  679. if (Changed)
  680. {
  681. DateTime1 = EncodeDate(Y1, M1, D1) + EncodeTime(H1, N1, S1, MS1);
  682. DateTime2 = EncodeDate(Y2, M2, D2) + EncodeTime(H2, N2, S2, MS2);
  683. }
  684. }
  685. }
  686. //---------------------------------------------------------------------------
  687. AnsiString __fastcall FixedLenDateTimeFormat(const AnsiString & Format)
  688. {
  689. AnsiString Result = Format;
  690. bool AsIs = false;
  691. int Index = 1;
  692. while (Index <= Result.Length())
  693. {
  694. char F = Result[Index];
  695. if ((F == '\'') || (F == '\"'))
  696. {
  697. AsIs = !AsIs;
  698. Index++;
  699. }
  700. else if (!AsIs && ((F == 'a') || (F == 'A')))
  701. {
  702. if (Result.SubString(Index, 5).LowerCase() == "am/pm")
  703. {
  704. Index += 5;
  705. }
  706. else if (Result.SubString(Index, 3).LowerCase() == "a/p")
  707. {
  708. Index += 3;
  709. }
  710. else if (Result.SubString(Index, 4).LowerCase() == "ampm")
  711. {
  712. Index += 4;
  713. }
  714. else
  715. {
  716. Index++;
  717. }
  718. }
  719. else
  720. {
  721. if (!AsIs && (strchr("dDeEmMhHnNsS", F) != NULL) &&
  722. ((Index == Result.Length()) || (Result[Index + 1] != F)))
  723. {
  724. Result.Insert(F, Index);
  725. }
  726. while ((Index <= Result.Length()) && (F == Result[Index]))
  727. {
  728. Index++;
  729. }
  730. }
  731. }
  732. return Result;
  733. }
  734. //---------------------------------------------------------------------------
  735. int __fastcall CompareFileTime(TDateTime T1, TDateTime T2)
  736. {
  737. // "FAT" time precision
  738. // 1 ms more solves the rounding issues (see also CustomDirView.pas)
  739. static TDateTime Second(0, 0, 1, 1);
  740. int Result;
  741. if (T1 == T2)
  742. {
  743. // just optimalisation
  744. Result = 0;
  745. }
  746. else if ((T1 < T2) && (T2 - T1 > Second))
  747. {
  748. Result = -1;
  749. }
  750. else if ((T1 > T2) && (T1 - T2 > Second))
  751. {
  752. Result = 1;
  753. }
  754. else
  755. {
  756. Result = 0;
  757. }
  758. return Result;
  759. }
  760. //---------------------------------------------------------------------------
  761. bool __fastcall RecursiveDeleteFile(const AnsiString FileName, bool ToRecycleBin)
  762. {
  763. SHFILEOPSTRUCT Data;
  764. memset(&Data, 0, sizeof(Data));
  765. Data.hwnd = NULL;
  766. Data.wFunc = FO_DELETE;
  767. AnsiString FileList(FileName);
  768. FileList.SetLength(FileList.Length() + 2);
  769. FileList[FileList.Length() - 1] = '\0';
  770. FileList[FileList.Length()] = '\0';
  771. Data.pFrom = FileList.c_str();
  772. Data.pTo = "";
  773. Data.fFlags = FOF_NOCONFIRMATION | FOF_RENAMEONCOLLISION | FOF_NOCONFIRMMKDIR |
  774. FOF_NOERRORUI | FOF_SILENT;
  775. if (ToRecycleBin)
  776. {
  777. Data.fFlags |= FOF_ALLOWUNDO;
  778. }
  779. int Result = SHFileOperation(&Data);
  780. return (Result == 0);
  781. }
  782. //---------------------------------------------------------------------------
  783. int __fastcall CancelAnswer(int Answers)
  784. {
  785. int Result;
  786. if ((Answers & qaCancel) != 0)
  787. {
  788. Result = qaCancel;
  789. }
  790. else if ((Answers & qaNo) != 0)
  791. {
  792. Result = qaNo;
  793. }
  794. else if ((Answers & qaAbort) != 0)
  795. {
  796. Result = qaAbort;
  797. }
  798. else if ((Answers & qaOK) != 0)
  799. {
  800. Result = qaOK;
  801. }
  802. else
  803. {
  804. assert(false);
  805. Result = qaCancel;
  806. }
  807. return Result;
  808. }
  809. //---------------------------------------------------------------------------
  810. int __fastcall AbortAnswer(int Answers)
  811. {
  812. int Result;
  813. if (FLAGSET(Answers, qaAbort))
  814. {
  815. Result = qaAbort;
  816. }
  817. else
  818. {
  819. Result = CancelAnswer(Answers);
  820. }
  821. return Result;
  822. }
  823. //---------------------------------------------------------------------------
  824. TPasLibModule * __fastcall FindModule(void * Instance)
  825. {
  826. TPasLibModule * CurModule;
  827. CurModule = reinterpret_cast<TPasLibModule*>(LibModuleList);
  828. while (CurModule)
  829. {
  830. if (CurModule->Instance == Instance)
  831. {
  832. break;
  833. }
  834. else
  835. {
  836. CurModule = CurModule->Next;
  837. }
  838. }
  839. return CurModule;
  840. }
  841. //---------------------------------------------------------------------------
  842. AnsiString __fastcall LoadStr(int Ident, unsigned int MaxLength)
  843. {
  844. TPasLibModule * MainModule = FindModule(HInstance);
  845. assert(MainModule != NULL);
  846. AnsiString Result;
  847. Result.SetLength(MaxLength);
  848. int Length = LoadString(MainModule->ResInstance, Ident, Result.c_str(), MaxLength);
  849. Result.SetLength(Length);
  850. return Result;
  851. }
  852. //---------------------------------------------------------------------------
  853. AnsiString __fastcall LoadStrPart(int Ident, int Part)
  854. {
  855. AnsiString Result;
  856. AnsiString Str = LoadStr(Ident);
  857. while (Part > 0)
  858. {
  859. Result = CutToChar(Str, '|', false);
  860. Part--;
  861. }
  862. return Result;
  863. }
  864. //---------------------------------------------------------------------------
  865. AnsiString __fastcall DecodeUrlChars(AnsiString S)
  866. {
  867. int i = 1;
  868. while (i <= S.Length())
  869. {
  870. switch (S[i])
  871. {
  872. case '+':
  873. S[i] = ' ';
  874. break;
  875. case '%':
  876. if (i <= S.Length() - 2)
  877. {
  878. S[i] = HexToStr(S.SubString(i + 1, 2))[1];
  879. S.Delete(i + 1, 2);
  880. }
  881. break;
  882. }
  883. i++;
  884. }
  885. return S;
  886. }
  887. //---------------------------------------------------------------------------
  888. void __fastcall OemToAnsi(AnsiString & Str)
  889. {
  890. if (!Str.IsEmpty())
  891. {
  892. Str.Unique();
  893. OemToChar(Str.c_str(), Str.c_str());
  894. }
  895. }
  896. //---------------------------------------------------------------------------
  897. void __fastcall AnsiToOem(AnsiString & Str)
  898. {
  899. if (!Str.IsEmpty())
  900. {
  901. Str.Unique();
  902. CharToOem(Str.c_str(), Str.c_str());
  903. }
  904. }