Misc.cpp 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. #include "Misc.hpp"
  2. #include <stdint.h>
  3. #include <stdio.h>
  4. #include <signal.h>
  5. #include <setjmp.h>
  6. #include <filesystem>
  7. #include "ExceptionSystem.hpp"
  8. static jmp_buf g_jmbuf;
  9. static void SIGSEGV_handler(int sig) {
  10. siglongjmp(g_jmbuf, 1);
  11. }
  12. //
  13. // read byte(s) at address `p` as __Type to `out`
  14. // succeed if return true, otherwise return false
  15. //
  16. template<typename __Type>
  17. static inline bool probe_for_read(const void* p, void* out) {
  18. int r = sigsetjmp(g_jmbuf, 1);
  19. if (r == 0) {
  20. *reinterpret_cast<__Type*>(out) = *reinterpret_cast<const __Type*>(p);
  21. return true;
  22. } else {
  23. return false;
  24. }
  25. }
  26. namespace nkg::Misc {
  27. //
  28. // Print memory data in [lpMemBegin, lpMemEnd)
  29. // If `base` is not nullptr, print address as offset. Otherwise, as absolute address.
  30. // NOTICE:
  31. // `base` must >= `from`
  32. //
  33. void PrintMemory(const void* lpMemBegin, const void* lpMemEnd, const void* lpBase) noexcept {
  34. auto pbBegin = reinterpret_cast<const uint8_t*>(lpMemBegin);
  35. auto pbEnd = reinterpret_cast<const uint8_t*>(lpMemEnd);
  36. auto pbBase = reinterpret_cast<const uint8_t*>(lpBase);
  37. if (pbBegin >= pbEnd)
  38. return;
  39. while (reinterpret_cast<uintptr_t>(pbBegin) % 16)
  40. pbBegin--;
  41. while (reinterpret_cast<uintptr_t>(pbEnd) % 16)
  42. pbEnd++;
  43. while (pbBegin < pbEnd) {
  44. uint16_t Values[16] = {};
  45. if (pbBase) {
  46. uintptr_t d = pbBegin >= lpBase ? pbBegin - pbBase : pbBase - pbBegin;
  47. if (pbBegin >= lpBase) {
  48. printf("+0x%.*zx ", static_cast<int>(2 * sizeof(void*)), d);
  49. } else {
  50. printf("-0x%.*zx ", static_cast<int>(2 * sizeof(void*)), d);
  51. }
  52. } else {
  53. printf("0x%.*zx ", static_cast<int>(2 * sizeof(void*)), reinterpret_cast<uintptr_t>(pbBegin));
  54. }
  55. for (int i = 0; i < 16; ++i) {
  56. if (pbBegin + i < lpMemBegin || pbBegin + i >= lpMemEnd) {
  57. printf(" ");
  58. Values[i] = 0xfffe;
  59. } else if (probe_for_read<uint8_t>(pbBegin + i, Values + i)) {
  60. printf("%02x ", Values[i]);
  61. } else {
  62. printf("?? ");
  63. Values[i] = 0xffff;
  64. }
  65. }
  66. printf(" ");
  67. for (int i = 0; i < 16; ++i) {
  68. if (0x20 <= Values[i] && Values[i] < 0x7f) {
  69. printf("%c", Values[i]);
  70. } else if (Values[i] == 0xfffe) {
  71. printf(" ");
  72. } else {
  73. printf(".");
  74. }
  75. }
  76. printf("\n");
  77. pbBegin += 0x10;
  78. }
  79. }
  80. //
  81. // Print memory data in [lpMem, lpMem + cbMem)
  82. // If `base` is not nullptr, print address as offset. Otherwise, as absolute address.
  83. // NOTICE:
  84. // `base` must >= `from`
  85. //
  86. void PrintMemory(const void* lpMem, size_t cbMem, const void* lpBase) noexcept {
  87. PrintMemory(lpMem, reinterpret_cast<const uint8_t*>(lpMem) + cbMem, lpBase);
  88. }
  89. [[nodiscard]]
  90. bool FsIsExist(std::string_view szPath) {
  91. std::error_code ec;
  92. if (std::filesystem::exists(szPath, ec)) {
  93. return true;
  94. } else {
  95. if (ec) {
  96. throw ARL::SystemError(__BASE_FILE__, __LINE__, ec.value(), "std::filesystem::exists failed.");
  97. } else {
  98. return false;
  99. }
  100. }
  101. }
  102. [[nodiscard]]
  103. bool FsIsFile(std::string_view szPath) {
  104. std::error_code ec;
  105. if (std::filesystem::is_regular_file(szPath, ec)) {
  106. return true;
  107. } else {
  108. if (ec) {
  109. throw ARL::SystemError(__BASE_FILE__, __LINE__, ec.value(), "std::filesystem::is_regular_file failed.");
  110. } else {
  111. return false;
  112. }
  113. }
  114. }
  115. [[nodiscard]]
  116. bool FsIsDirectory(std::string_view szPath) {
  117. std::error_code ec;
  118. if (std::filesystem::is_directory(szPath, ec)) {
  119. return true;
  120. } else {
  121. if (ec) {
  122. throw ARL::SystemError(__BASE_FILE__, __LINE__, ec.value(), "std::filesystem::is_directory failed.");
  123. } else {
  124. return false;
  125. }
  126. }
  127. }
  128. void FsCopyFile(std::string_view szSourcePath, std::string_view szDestinationPath) {
  129. std::error_code ec;
  130. if (std::filesystem::copy_file(szSourcePath, szDestinationPath, ec) == false) {
  131. throw ARL::SystemError(__BASE_FILE__, __LINE__, ec.value(), "std::filesystem::copy_file failed.");
  132. }
  133. }
  134. void FsDeleteFile(std::string_view szPath) {
  135. std::error_code ec;
  136. if (std::filesystem::remove(szPath, ec) == false) {
  137. throw ARL::SystemError(__BASE_FILE__, __LINE__, ec.value(), "std::filesystem::remove failed.");
  138. }
  139. }
  140. std::string FsCurrentWorkingDirectory() {
  141. std::error_code ec;
  142. std::string path = std::filesystem::current_path(ec);
  143. if (ec) {
  144. throw ARL::SystemError(__BASE_FILE__, __LINE__, ec.value(), "std::filesystem::current_path failed.");
  145. } else {
  146. return path;
  147. }
  148. }
  149. }