Misc.cpp 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. #include <stddef.h>
  2. #include <stdint.h>
  3. #include <tchar.h>
  4. #include <windows.h>
  5. #include <ExceptionWin32.hpp>
  6. #include <xstring.hpp>
  7. #undef NKG_CURRENT_SOURCE_FILE
  8. #undef NKG_CURRENT_SOURCE_LINE
  9. #define NKG_CURRENT_SOURCE_FILE() TEXT(".\\navicat-patcher\\Misc.cpp")
  10. #define NKG_CURRENT_SOURCE_LINE() __LINE__
  11. namespace nkg {
  12. template<typename __Type>
  13. static inline bool ProbeForRead(const void* p, void* out) {
  14. __try {
  15. *reinterpret_cast<__Type*>(out) = *reinterpret_cast<const __Type*>(p);
  16. return true;
  17. } __except (EXCEPTION_EXECUTE_HANDLER) {
  18. return false;
  19. }
  20. }
  21. //
  22. // Print memory data in [lpMemBegin, lpMemEnd)
  23. // If `base` is not nullptr, print address as offset. Otherwise, as absolute address.
  24. // NOTICE:
  25. // `base` must >= `from`
  26. //
  27. void PrintMemory(const void* lpMemBegin, const void* lpMemEnd, const void* lpBase) noexcept {
  28. auto pbBegin = reinterpret_cast<const uint8_t*>(lpMemBegin);
  29. auto pbEnd = reinterpret_cast<const uint8_t*>(lpMemEnd);
  30. auto pbBase = reinterpret_cast<const uint8_t*>(lpBase);
  31. if (pbBegin >= pbEnd)
  32. return;
  33. while (reinterpret_cast<uintptr_t>(pbBegin) % 16)
  34. pbBegin--;
  35. while (reinterpret_cast<uintptr_t>(pbEnd) % 16)
  36. pbEnd++;
  37. while (pbBegin < pbEnd) {
  38. uint16_t Values[16] = {};
  39. if (pbBase) {
  40. uintptr_t d = pbBegin >= lpBase ? pbBegin - pbBase : pbBase - pbBegin;
  41. if (pbBegin >= lpBase) {
  42. _tprintf_s(TEXT("+0x%.*zx "), static_cast<int>(2 * sizeof(void*)), d);
  43. } else {
  44. _tprintf_s(TEXT("-0x%.*zx "), static_cast<int>(2 * sizeof(void*)), d);
  45. }
  46. } else {
  47. _tprintf_s(TEXT("0x%.*zx "), static_cast<int>(2 * sizeof(void*)), reinterpret_cast<uintptr_t>(pbBegin));
  48. }
  49. for (int i = 0; i < 16; ++i) {
  50. if (pbBegin + i < lpMemBegin || pbBegin + i >= lpMemEnd) {
  51. _tprintf_s(TEXT(" "));
  52. Values[i] = 0xfffe;
  53. } else if (ProbeForRead<uint8_t>(pbBegin + i, Values + i)) {
  54. _tprintf_s(TEXT("%02x "), Values[i]);
  55. } else {
  56. _tprintf_s(TEXT("?? "));
  57. Values[i] = 0xffff;
  58. }
  59. }
  60. _tprintf_s(TEXT(" "));
  61. for (int i = 0; i < 16; ++i) { // NOLINT
  62. if (0x20 <= Values[i] && Values[i] < 0x7f) {
  63. _tprintf_s(TEXT("%c"), Values[i]);
  64. } else if (Values[i] == 0xfffe) {
  65. _tprintf_s(TEXT(" "));
  66. } else {
  67. _tprintf_s(TEXT("."));
  68. }
  69. }
  70. _tprintf_s(TEXT("\n"));
  71. pbBegin += 0x10;
  72. }
  73. }
  74. //
  75. // Print memory data in [lpMem, lpMem + cbMem)
  76. // If `base` is not nullptr, print address as offset. Otherwise, as absolute address.
  77. // NOTICE:
  78. // `base` must >= `from`
  79. //
  80. void PrintMemory(const void* lpMem, size_t cbMem, const void* lpBase) noexcept {
  81. PrintMemory(lpMem, reinterpret_cast<const uint8_t*>(lpMem) + cbMem, lpBase);
  82. }
  83. void PrintBytes(const void* lpMemBegin, const void* lpMemEnd) noexcept {
  84. auto pbMemBegin = reinterpret_cast<const uint8_t*>(lpMemBegin);
  85. auto pbMemEnd = reinterpret_cast<const uint8_t*>(lpMemEnd);
  86. if (pbMemBegin < pbMemEnd) {
  87. uint8_t v;
  88. if (ProbeForRead<uint8_t>(pbMemBegin, &v)) {
  89. _tprintf_s(TEXT("%.2x"), v);
  90. } else {
  91. _tprintf_s(TEXT("??"));
  92. }
  93. ++pbMemBegin;
  94. }
  95. while (pbMemBegin < pbMemEnd) {
  96. uint8_t v;
  97. if (ProbeForRead<uint8_t>(pbMemBegin, &v)) {
  98. _tprintf_s(TEXT(" %.2x"), v);
  99. } else {
  100. _tprintf_s(TEXT(" ??"));
  101. }
  102. ++pbMemBegin;
  103. }
  104. }
  105. void PrintBytes(const void* lpMem, size_t cbMem) noexcept {
  106. PrintBytes(lpMem, reinterpret_cast<const char*>(lpMem) + cbMem);
  107. }
  108. [[nodiscard]]
  109. bool IsValidDirectoryPath(PCTSTR lpszDirectoryPath) noexcept {
  110. DWORD Attribute = GetFileAttributes(lpszDirectoryPath);
  111. return Attribute != INVALID_FILE_ATTRIBUTES && (Attribute & FILE_ATTRIBUTE_DIRECTORY) != 0;
  112. }
  113. [[nodiscard]]
  114. bool IsValidFilePath(PCTSTR lpszFilePath) noexcept {
  115. DWORD Attribute = GetFileAttributes(lpszFilePath);
  116. return Attribute != INVALID_FILE_ATTRIBUTES && (Attribute & FILE_ATTRIBUTE_DIRECTORY) == 0;
  117. }
  118. [[nodiscard]]
  119. bool IsWineEnvironment() noexcept {
  120. static bool Checked = false;
  121. static bool IsWineEnv = false;
  122. if (Checked == false) {
  123. auto hNtdll = GetModuleHandle(TEXT("ntdll.dll"));
  124. IsWineEnv = hNtdll && GetProcAddress(hNtdll, "wine_get_version") != nullptr;
  125. Checked = true;
  126. }
  127. return IsWineEnv;
  128. }
  129. std::xstring GetCurrentWorkingDirectory() {
  130. std::xstring CurrentDirectory;
  131. auto s = ::GetCurrentDirectory(0, NULL);
  132. if (s == 0) {
  133. throw Win32Error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), GetLastError(), TEXT("GetCurrentDirectory failed"));
  134. }
  135. CurrentDirectory.resize(static_cast<size_t>(s) - 1);
  136. s = ::GetCurrentDirectory(s, CurrentDirectory.data());
  137. if (s == 0) {
  138. throw Win32Error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), GetLastError(), TEXT("GetCurrentDirectory failed"));
  139. }
  140. return CurrentDirectory;
  141. }
  142. }