W
Watchman
Original poster
Как-то утром на рассвете. Поезд рельсы потеряет.
Вспыхнет зарево в колодце. Хрустнет веточка в овраге.
Порвутся штаны от широкой походки...
Всем хай, не стану писать статью, как обычно. Просто скину сорцы с комментами.Вспыхнет зарево в колодце. Хрустнет веточка в овраге.
Порвутся штаны от широкой походки...
Имелся у меня криптор. который я поддерживал аж с 2010 года, точнее криптокомбайн. В его комплект входил автобилдер, выдающий сразу несколько копий криптованного софта с уникальными сигнатурами при компиляции стаба. С недавнего времени я его забросил практически, но назрел вопрос "защитить" новый софт. Так как он перекомбайнивался при помощи спец утилиты, которую я писал для MS VisualStudio 2010 SP1. Обнаружил, что новые студии уже как раньше в реестре не прописываются, поэтому сочинил приблуду, которая ищет ВСЕ студии установленные в винде. Но так как мой криптор Xeon далеко ушёл , впрочем как и АВ - его необходимо пересобирать на разных компиляторах/линкерах с учетом, что это будет автоматически и без всяких костылей.
В общем сабж (там не обращайте внимание на замеры производительности - это для крипта и OpenMP в принципе тож не надо, если токо пригодится кому).
Компилять под 2019 студию, солюшен в комплекте.
C++:
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <omp.h>
//Частота генератора
volatile LARGE_INTEGER li_freq;
//_______________________________________________________________________________________________________
//Есть ли файло?
bool __fastcall FileExists(char* szFullFileName)
{
return (GetFileAttributesA(szFullFileName) != DWORD(-1));
}
//_______________________________________________________________________________________________________
//Функа для замера текущих тиков проца ;)
__forceinline double PerfCounterX()
{
LARGE_INTEGER li_pc;
if (TRUE != QueryPerformanceCounter(&li_pc))
{
printf("Error in QueryPerformanceCounter() - Err=%d\n", GetLastError());
return -1.;
}
return (double)li_pc.QuadPart / li_freq.QuadPart;
}
int main()
{
if (TRUE != QueryPerformanceFrequency((LARGE_INTEGER*)&li_freq))
{
printf("Error in QueryPerformanceFrequency() - Err=%d\n", GetLastError());
return -1;
}
double t1_0 = PerfCounterX();
//распараллеливаем цикл на ядра через OpenMP для прикола ;)
//не удивляемся, что вывод идёт не по порядку но нам пофиг, мы выигрываем микросекунды :)))
//Включите в компиляторе /openmp - если делать нефиг
#pragma omp parallel
{
#pragma omp for
//Перебор всех студий начиная с 2010
for (int i = 0; i <=9; i++)
{
char szPathVS[MAX_PATH * 2] = { 0 };
char szCurPathVS[MAX_PATH * 2] = { 0 };
char szCurEnv[MAX_PATH * 2] = { 0 };
char szTemp[MAX_PATH * 2] = { 0 };
sprintf_s(szTemp, "VS1%d", i); //здесь название студии
sprintf_s(szCurEnv,"%s0COMNTOOLS", szTemp); //Формируем название системной переменной
if (GetEnvironmentVariableA(szCurEnv, szCurPathVS, MAX_PATH * 2 - 1))
{
//Есть такая переменная - уходим в подкаталоги
// printf("Path in Environment %s = %s\n", szTemp, szCurPathVS);
char* szNtemp = strrchr(szCurPathVS, '\\');
if (szNtemp)
{
szNtemp[0] = 0;
szNtemp = strrchr(szCurPathVS, '\\');
if (szNtemp)
{
szNtemp[sizeof(char)] = 0;
sprintf_s(szPathVS, "%sIDE\\devenv.exe", szCurPathVS);
if (FileExists(szPathVS))
{
//О и файло студии есть!
printf("Path Devenv %s = %s\n", szTemp, szPathVS);
}
}
}
}
else
{
//Если через COMMONTOOLS не нашли то более поздние версии через VS....INSTALLDIR
sprintf_s(szTemp, "VS201%d", i); ////здесь название студии
sprintf_s(szCurEnv, "%sINSTALLDIR", szTemp); //Формируем название системной переменной
//printf("---%s\n", szCurEnv);
if (GetEnvironmentVariableA(szCurEnv, szPathVS, MAX_PATH * 2 - 1))
{
//Есть такая переменная
strcat_s(szPathVS, "\\Common7\\IDE\\devenv.exe");
if (FileExists(szPathVS))
{
//О и файло студии есть!
printf("Path Devenv %s = %s\n", szTemp, szPathVS);
}
}
}
}
}
double t1 = PerfCounterX();
printf("Found in: %.8lf[sec]\n",t1 - t1_0);
printf("Press any key to exit...\n");
_getch();
}
//P.S.: для чего это нужно иногда.
//Недавно стала задача автоматически собирать солюшены из своего собственного приложения
//Так как после 2010 студии к сожалению уже не прокатывает как для 2010 студии - брать чисто в реестре
//вот так:
//***************
////Получение пути к devenv 10 -й студии
//BOOL GetStudioPath()
//{
// LONG lResult;
// LPCWSTR lpSubKey = L"SOFTWARE\\Microsoft\\VisualStudio\\10.0_Config";
// HKEY hKey;
// if (lResult = RegOpenKeyEx(HKEY_CURRENT_USER, lpSubKey, 0, KEY_READ, &hKey) != ERROR_SUCCESS)
// {
// printf("Error open key\n");
// }
// else
// {
// DWORD BuffLen = sizeof(wcDevenv);
// if (RegQueryValueEx(hKey, L"InstallDir", NULL, NULL, (LPBYTE)&wcDevenv, &BuffLen) != ERROR_SUCCESS)
// {
// printf("Error RegQueryValue key\n");
// RegCloseKey(hKey);
// return FALSE;
// }
// else
// {
// wcscat(wcDevenv, L"devenv.exe");
// wprintf(L"Path: %s Found \n________________________________________________________________________\n", wcDevenv);
// }
// RegCloseKey(hKey);
// return TRUE;
// }
// return FALSE;
//}
//*************
//То путём небольших исследований пришлось сделать по другому, это с угетом что ни через SetipAPI ,
// ни через WMI мы не получим всех VisualStudio что установлены, и конкретно нас интересующего
//его шелла devenv.exe так необходимого для пересборки криптора и так удобного.
//P.P.S: за openMP и замеры производительности не обессудьте - это кусок проекта, так сказать "надо".