@@ -97,6 +97,94 @@ static bool extract_version_from_path(
9797 return true ;
9898}
9999
100+
101+ #pragma comment(lib, "version.lib")
102+ // -------------------------------------------------------------------------
103+ DWORD GetFileVersionNumber (const char *filename, DWORD *pdwMSVer, DWORD *pdwLSVer)
104+ {
105+ DWORD dwResult = NOERROR;
106+ unsigned uiSize;
107+ DWORD dwVerInfoSize;
108+ DWORD dwHandle;
109+ PBYTE prgbVersionInfo = NULL ;
110+ VS_FIXEDFILEINFO *lpVSFixedFileInfo = NULL ;
111+
112+ DWORD dwMSVer = 0xffffffff ;
113+ DWORD dwLSVer = 0xffffffff ;
114+
115+ qwstring wfilename;
116+ if ( !utf8_utf16 (&wfilename, filename) )
117+ {
118+ dwResult = ERROR_INVALID_PARAMETER;
119+ goto Finish;
120+ }
121+
122+ dwVerInfoSize = GetFileVersionInfoSizeW (wfilename.c_str (), &dwHandle);
123+ if ( dwVerInfoSize != 0 )
124+ {
125+ prgbVersionInfo = (PBYTE)qalloc (dwVerInfoSize);
126+ if ( prgbVersionInfo == NULL )
127+ {
128+ dwResult = ERROR_NOT_ENOUGH_MEMORY;
129+ goto Finish;
130+ }
131+
132+ // Read version stamping info
133+ if ( GetFileVersionInfoW (wfilename.c_str (), dwHandle, dwVerInfoSize, prgbVersionInfo) )
134+ {
135+ // get the value for VS_FIXEDFILEINFO
136+ if ( VerQueryValueW (prgbVersionInfo, L" \\ " , (LPVOID*)&lpVSFixedFileInfo, &uiSize) && (uiSize != 0 ) )
137+ {
138+ dwMSVer = lpVSFixedFileInfo->dwFileVersionMS ;
139+ dwLSVer = lpVSFixedFileInfo->dwFileVersionLS ;
140+ }
141+ }
142+ else
143+ {
144+ dwResult = GetLastError ();
145+ goto Finish;
146+ }
147+ }
148+ else
149+ {
150+ dwResult = GetLastError ();
151+ }
152+
153+ out_verb (" %s is version %d.%d.%d.%d\n " , filename, HIWORD (dwMSVer), LOWORD (dwMSVer), HIWORD (dwLSVer), LOWORD (dwLSVer));
154+
155+ Finish:
156+ if ( prgbVersionInfo != NULL )
157+ qfree (prgbVersionInfo);
158+ if ( pdwMSVer != NULL )
159+ *pdwMSVer = dwMSVer;
160+ if ( pdwLSVer != NULL )
161+ *pdwLSVer = dwLSVer;
162+
163+ return dwResult;
164+ }
165+ // -------------------------------------------------------------------------
166+ static bool extract_version_from_dll (
167+ pylib_version_t *out,
168+ const char *fname)
169+ {
170+ DWORD dwMSVer, dwLSVer;
171+ DWORD res = GetFileVersionNumber (fname, &dwMSVer, &dwLSVer);
172+ if ( res == NOERROR )
173+ {
174+ out->raw .sprnt (" %d.%d.%d.%d" , HIWORD (dwMSVer), LOWORD (dwMSVer), HIWORD (dwLSVer), LOWORD (dwLSVer));
175+ // Python DLL versions look like 3.7.4150.1013 -> 3.7.4
176+ out->major = HIWORD (dwMSVer);
177+ out->minor = LOWORD (dwMSVer);
178+ out->revision = HIWORD (dwLSVer) / 1000 ;
179+ return true ;
180+ }
181+ else
182+ {
183+ out_verb (" error getting version of \" %s\" : %s\n " , fname, winerr (res));
184+ return false ;
185+ }
186+ }
187+
100188// -------------------------------------------------------------------------
101189static bool is_python3Y_dll_file_name (const char *fname)
102190{
@@ -138,6 +226,9 @@ static bool probe_python_install_dir_from_dll_path(
138226 {
139227 char dll_path[QMAXPATH];
140228 qmakepath (dll_path, sizeof (dll_path), dir, fb.ff_name , nullptr );
229+ pylib_version_t tmp;
230+ if ( extract_version_from_dll (&tmp, path) )
231+ *out_version = tmp;
141232 out_verb (" Found: \" %s\" (version: %s)\n " , dll_path, out_version->str (&verbuf));
142233 out_paths->push_back (dll_path);
143234
@@ -392,10 +483,24 @@ void pyver_tool_t::do_find_python_libs(pylib_entries_t *result) const
392483 out (" IDA previously used: \" %s\" (guessed version: %s). "
393484 " Making this the preferred version.\n " ,
394485 existing.c_str (), version.str (&verbuf));
395- pylib_entry_t e (version);
396- e.paths .swap (paths);
397- e.preferred = true ;
398- result->entries .push_back (e);
486+ // do we have it in the list?
487+ bool found = false ;
488+ for ( pylib_entry_t &e : result->entries )
489+ {
490+ if ( e.paths .has (existing) )
491+ {
492+ found = true ;
493+ e.preferred = true ;
494+ }
495+ }
496+ if ( !found )
497+ {
498+ // add a new one
499+ pylib_entry_t e (version);
500+ e.paths .swap (paths);
501+ e.preferred = true ;
502+ result->entries .push_back (e);
503+ }
399504 }
400505 else
401506 {
0 commit comments