2121#include < cstring> // For memcmp
2222#include < string> // Required for std::wstring
2323#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
2628
2729namespace firebase {
2830namespace analytics {
2931namespace internal {
3032
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+
3178// Helper function to calculate SHA256 hash of a file.
3279static std::vector<BYTE> CalculateFileSha256 (HANDLE hFile) {
3380 HCRYPTPROV hProv = 0 ;
@@ -129,13 +176,6 @@ HMODULE VerifyAndLoadAnalyticsLibrary(
129176 LOAD_LIBRARY_SEARCH_APPLICATION_DIR);
130177 }
131178
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- }
139179 std::wstring executable_path_str (_wpgmptr);
140180
141181 size_t last_slash_pos = executable_path_str.find_last_of (L" \\ " );
@@ -145,7 +185,23 @@ HMODULE VerifyAndLoadAnalyticsLibrary(
145185 return nullptr ;
146186 }
147187
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 =
149205 executable_path_str.substr (0 , last_slash_pos + 1 );
150206 full_dll_path_str += library_filename; // library_filename is the filename
151207
0 commit comments