21
21
#include < cstring> // For memcmp
22
22
#include < string> // Required for std::wstring
23
23
#include < vector>
24
-
25
- #include " app/src/log.h"
24
+ #include < string> // Required for std::wstring
25
+ #include < cstdlib> // Required for _wpgmptr
26
+ #include < cstring> // For memcmp
27
+ #include " app/src/log.h" // NOLINT
26
28
27
29
namespace firebase {
28
30
namespace analytics {
29
31
namespace internal {
30
32
33
+ // Helper function to retrieve the full path of the current executable.
34
+ // Returns an empty string on failure.
35
+ static std::wstring GetExecutablePath () {
36
+ std::wstring executable_path_str;
37
+ wchar_t * wpgmptr_val = nullptr ;
38
+
39
+ // Prefer _get_wpgmptr()
40
+ errno_t err_w = _get_wpgmptr (&wpgmptr_val);
41
+ if (err_w == 0 && wpgmptr_val != nullptr && wpgmptr_val[0 ] != L' \0 ' ) {
42
+ executable_path_str = wpgmptr_val;
43
+ } else {
44
+ // Fallback to _get_pgmptr() and convert to wide string
45
+ char * pgmptr_val = nullptr ;
46
+ errno_t err_c = _get_pgmptr (&pgmptr_val);
47
+ if (err_c == 0 && pgmptr_val != nullptr && pgmptr_val[0 ] != ' \0 ' ) {
48
+ // Convert narrow string to wide string using CP_ACP (system default ANSI code page)
49
+ int wide_char_count = MultiByteToWideChar (CP_ACP, MB_ERR_INVALID_CHARS, pgmptr_val, -1 , NULL , 0 );
50
+ if (wide_char_count == 0 ) { // Failure if count is 0
51
+ DWORD conversion_error = GetLastError ();
52
+ LogError (" GetExecutablePath: MultiByteToWideChar failed to calculate size for _get_pgmptr path. Error: %u" , conversion_error);
53
+ return L" " ;
54
+ }
55
+
56
+ std::vector<wchar_t > wide_path_buffer (wide_char_count);
57
+ if (MultiByteToWideChar (CP_ACP, MB_ERR_INVALID_CHARS, pgmptr_val, -1 , wide_path_buffer.data (), wide_char_count) == 0 ) {
58
+ DWORD conversion_error = GetLastError ();
59
+ LogError (" GetExecutablePath: MultiByteToWideChar failed to convert _get_pgmptr path. Error: %u" , conversion_error);
60
+ return L" " ;
61
+ }
62
+ executable_path_str = wide_path_buffer.data ();
63
+ } else {
64
+ // Both _get_wpgmptr and _get_pgmptr failed or returned empty/null
65
+ LogError (" GetExecutablePath: Failed to retrieve executable path using both _get_wpgmptr (err: %d) and _get_pgmptr (err: %d)." , err_w, err_c);
66
+ return L" " ;
67
+ }
68
+ }
69
+
70
+ // Safeguard if path somehow resolved to empty despite initial checks.
71
+ if (executable_path_str.empty ()) {
72
+ LogError (" GetExecutablePath: Executable path resolved to an empty string." );
73
+ return L" " ;
74
+ }
75
+ return executable_path_str;
76
+ }
77
+
31
78
// Helper function to calculate SHA256 hash of a file.
32
79
static std::vector<BYTE> CalculateFileSha256 (HANDLE hFile) {
33
80
HCRYPTPROV hProv = 0 ;
@@ -129,13 +176,6 @@ HMODULE VerifyAndLoadAnalyticsLibrary(
129
176
LOAD_LIBRARY_SEARCH_APPLICATION_DIR);
130
177
}
131
178
132
- // Get full path to the executable using _wpgmptr.
133
- // This global variable is provided by the CRT and is expected to be available
134
- // on Windows.
135
- if (_wpgmptr == nullptr || _wpgmptr[0 ] == L' \0 ' ) {
136
- LogError (" VerifyAndLoadAnalyticsLibrary: Can't determine executable path." );
137
- return nullptr ;
138
- }
139
179
std::wstring executable_path_str (_wpgmptr);
140
180
141
181
size_t last_slash_pos = executable_path_str.find_last_of (L" \\ " );
@@ -145,7 +185,23 @@ HMODULE VerifyAndLoadAnalyticsLibrary(
145
185
return nullptr ;
146
186
}
147
187
148
- std::wstring full_dll_path_str =
188
+ std::wstring executable_path_str = GetExecutablePath ();
189
+
190
+ if (executable_path_str.empty ()) {
191
+ // GetExecutablePath() is expected to log specific errors.
192
+ // This log indicates the failure to proceed within this function.
193
+ LogError (" VerifyAndLoadAnalyticsLibrary: Failed to determine executable path via GetExecutablePath(), cannot proceed." );
194
+ return nullptr ;
195
+ }
196
+
197
+ size_t last_slash_pos = executable_path_str.find_last_of (L" \\ " );
198
+ if (last_slash_pos == std::wstring::npos) {
199
+ // Log message updated to avoid using %ls for executable_path_str
200
+ LogError (" VerifyAndLoadAnalyticsLibrary: Could not determine executable directory from retrieved path (no backslash found)." );
201
+ return nullptr ;
202
+ }
203
+
204
+ std::wstring full_dll_path_str =
149
205
executable_path_str.substr (0 , last_slash_pos + 1 );
150
206
full_dll_path_str += library_filename; // library_filename is the filename
151
207
0 commit comments