windows-nt/Source/XPSP1/NT/sdktools/sysparse/genapwlk.cpp
2020-09-26 16:20:57 +08:00

580 lines
17 KiB
C++

// General app walking helper routines to be used in 9xapwlk.cpp and ntappwlk.cpp
#include "globals.h"
#include <objidl.h>
CLASS_GeneralAppWalk::CLASS_GeneralAppWalk(kLogFile *Proc, HWND hIn)
{
LogProc=Proc;
gHandleToMainWindow=hIn;
}
BOOL CLASS_GeneralAppWalk::OpenRegistry(void)
{
DWORD Return;
lstrcpy(RootKeyString, TEXT("Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall"));
Return=RegOpenKeyEx(HKEY_LOCAL_MACHINE,
RootKeyString,
0,
KEY_READ,
&HandleToUninstallKeyRoot);
if (Return==ERROR_SUCCESS)
{
return TRUE;
}
else
{
return FALSE;
}
return TRUE;
}
BOOL CLASS_GeneralAppWalk::Walk(void)
{
if (OpenRegistry())
{
CurrentKey=0;
LogProc->LogString(",#Uninstall_APPS,,\r\n");
while ( TRUE == NextKey() );
RegCloseKey(HandleToUninstallKeyRoot);
}
return WalkStartMenu();
}
BOOL CLASS_GeneralAppWalk::NextKey(void) {
PTCHAR KeyName = NULL;
DWORD SizeOfName = MAX_PATH * 4;
if(!GetCurrentWinDir())
return FALSE;
KeyName = (PTCHAR)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, MAX_PATH * 4);
if(!KeyName)
return FALSE;
if (ERROR_SUCCESS != RegEnumKeyEx(HandleToUninstallKeyRoot, CurrentKey, KeyName, &SizeOfName, NULL, NULL, NULL, NULL)) {
HeapFree(GetProcessHeap(), NULL, KeyName);
return FALSE;
}
CurrentKey++;
GetUninstallValues(KeyName);
HeapFree(GetProcessHeap(), NULL, KeyName);
return TRUE;
}
BOOL CLASS_GeneralAppWalk::GetUninstallValues(TCHAR *KeyName)
{
HKEY UninstallKey;
char FullKey[1024];
PUCHAR ProductName=(PUCHAR)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 1024*sizeof(TCHAR));
DWORD ProductSize=1024;
DWORD Return=0;
DWORD Type=REG_SZ;
lstrcpy(FullKey, RootKeyString);
lstrcat(FullKey, "\\");
lstrcat(FullKey, KeyName);
Return=RegOpenKeyEx(HKEY_LOCAL_MACHINE, FullKey, 0, KEY_READ, &UninstallKey);
if (ERROR_SUCCESS == Return)
{
Return = RegQueryValueEx(UninstallKey, "DisplayName", NULL, &Type,
ProductName, &ProductSize);
if (ERROR_SUCCESS == Return)
{
LogProc->StripCommas((TCHAR*)ProductName);
// printf("Product = %s\r\n", ProductName);
LogProc->LogString(",%s,\r\n", ProductName);
HeapFree(GetProcessHeap(), HEAP_ZERO_MEMORY, ProductName);
RegCloseKey(UninstallKey);
return TRUE;
}
else
{
// printf("Product = %s\r\n", szName);
LogProc->StripCommas((TCHAR*)KeyName);
LogProc->LogString(",%s,\r\n", KeyName);
HeapFree(GetProcessHeap(), HEAP_ZERO_MEMORY, ProductName);
RegCloseKey(UninstallKey);
return TRUE;
//Check for other ways to get product name
}
}
else
{
HeapFree(GetProcessHeap(), HEAP_ZERO_MEMORY, ProductName);
RegCloseKey(UninstallKey);
return FALSE;
}
HeapFree(GetProcessHeap(), HEAP_ZERO_MEMORY, ProductName);
RegCloseKey(UninstallKey);
return FALSE;
}
BOOL CLASS_GeneralAppWalk::WalkStartMenu(void)
{
LogProc->LogString(",#StartMenu_APPS,,\r\n");
PTCHAR Windir = NULL;
UINT Size = 512;
if(!GetCurrentWinDir())
return FALSE;
Windir = (PTCHAR)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, MAX_PATH * 4);
if(!Windir)
return FALSE;
wsprintf(Windir, "%s\\Start Menu", g_WindowsDirectory);
StartMenuLen = (UINT)lstrlen(Windir);
WalkDir(Windir, NULL);
wsprintf(Windir, "%s\\profiles", g_WindowsDirectory);
StartMenuLen = (UINT)lstrlen(Windir);
WalkDir(Windir, NULL);
wsprintf(Windir, "%s\\Documents and Settings", g_WindowsDirectory);
StartMenuLen = (UINT)lstrlen(Windir);
WalkDir(Windir, NULL);
lstrcpy(Windir, g_WindowsDirectory);
Windir[2]='\0';
lstrcat(Windir, "\\Documents and Settings");
StartMenuLen = (UINT)lstrlen(Windir);
WalkDir(Windir, NULL);
/*
if (S_OK == SHGetFolderPath(NULL, CSIDL_STARTMENU, NULL, SHGFP_TYPE_CURRENT, Windir)) {
StartMenuLen = lstrlen(Windir);
WalkDir(Windir, NULL);
}
if (S_OK == SHGetFolderPath(NULL, CSIDL_COMMON_STARTMENU,NULL, SHGFP_TYPE_CURRENT, Windir)) {
StartMenuLen = lstrlen(Windir);
WalkDir(Windir, NULL);
}
*/
HeapFree(GetProcessHeap(), NULL, Windir);
return TRUE;
}
BOOL CLASS_GeneralAppWalk::WalkDir(TCHAR *TempPath, TCHAR *File)
{
WORD PathLen;
PTCHAR Path = NULL;
HANDLE HandleToSearch;
WIN32_FIND_DATA FindFile;
TCHAR CurrentDirectory[MAX_PATH];
Path = (PTCHAR)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, MAX_PATH *4);
if(!Path)
return FALSE;
SetErrorMode (SEM_FAILCRITICALERRORS);
lstrcpy(Path, TempPath);
PathLen = (UINT)lstrlen(Path);
Path = Path + PathLen - 1;
if (Path[0] != '\\')
lstrcat(Path, "\\");
Path = Path - PathLen + 1;
if (File)
lstrcat(Path, File);
if (SetCurrentDirectory(Path))
{
GetCurrentDirectory(MAX_PATH, CurrentDirectory);
HandleToSearch = FindFirstFile("*.*", &FindFile);
if (lstrcmp(FindFile.cFileName,".") && lstrcmp(FindFile.cFileName,".."))
{
if ( FILE_ATTRIBUTE_DIRECTORY == (FindFile.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY))
{
WalkDir(Path, FindFile.cFileName);
}
else
{
TCHAR *cT1 = (TCHAR*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 1024*sizeof(TCHAR));
TCHAR *cT2 = (TCHAR*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 1024*sizeof(TCHAR));
lstrcpy(cT2, Path);
if (cT2[lstrlen(cT2)-1] != '\\')
lstrcat(cT2, "\\");
lstrcat(cT2, FindFile.cFileName);
if (EndsInLnk(cT2))
ResolveIt(cT2, cT1);
HeapFree(GetProcessHeap(), HEAP_ZERO_MEMORY, cT1);
HeapFree(GetProcessHeap(), HEAP_ZERO_MEMORY, cT2);
}
}
while (FindNextFile(HandleToSearch, &FindFile))
{
if (lstrcmp(FindFile.cFileName,".") && lstrcmp(FindFile.cFileName,".."))
{
if(FILE_ATTRIBUTE_DIRECTORY == (FindFile.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY))
{
PathLen = (UINT)lstrlen(Path);
Path = Path + PathLen - 1;
if (Path[0] != '\\')
lstrcat(Path, "\\");
Path = Path - PathLen + 1;
WalkDir(Path, FindFile.cFileName);
}
else
{
TCHAR *cT1 = (TCHAR*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 1024*sizeof(TCHAR));
TCHAR *cT2 = (TCHAR*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 1024*sizeof(TCHAR));
lstrcpy(cT2, Path);
if (cT2[lstrlen(cT2)-1] != '\\')
lstrcat(cT2, "\\");
lstrcat(cT2, FindFile.cFileName);
if (EndsInLnk(cT2))
{
ResolveIt(cT2, cT1);
}
HeapFree(GetProcessHeap(), HEAP_ZERO_MEMORY, cT1);
HeapFree(GetProcessHeap(), HEAP_ZERO_MEMORY, cT2);
}
}
}
FindClose(HandleToSearch);
}
HeapFree(GetProcessHeap(), NULL, Path);
return TRUE;
}
BOOL CLASS_GeneralAppWalk::EndsInLnk(TCHAR *File)
{
TCHAR szTO[1024];
lstrcpy(szTO, File);
if ( (szTO[lstrlen(szTO)-4] == '.') &&
((szTO[lstrlen(szTO)-3] == 'l') || (szTO[lstrlen(szTO)-3] == 'L')) &&
((szTO[lstrlen(szTO)-2] == 'n') || (szTO[lstrlen(szTO)-2] == 'N')) &&
((szTO[lstrlen(szTO)-1] == 'k') || (szTO[lstrlen(szTO)-1] == 'K')) )
{
return TRUE;
}
else return FALSE;
}
HRESULT CLASS_GeneralAppWalk::ResolveIt(LPCSTR LinkFile, LPSTR Path)
{
HRESULT HandleToResult;
IShellLink *ShellLink;
WIN32_FIND_DATA wfd;
UINT uiPrevErrorMode = 0;
#ifdef MAXDEBUG
LogProc->LogString("Working on %s:\r\n", lpszLinkFile);
#endif
*Path = '\0';
HandleToResult = CoInitialize(NULL);
HandleToResult = CoCreateInstance( CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
IID_IShellLink, (LPVOID *)&ShellLink );
if (SUCCEEDED(HandleToResult))
{
IPersistFile *ppf;
HandleToResult = ShellLink->QueryInterface(IID_IPersistFile, (LPVOID *)&ppf );
if (SUCCEEDED(HandleToResult))
{
WCHAR wsz[MAX_PATH];
MultiByteToWideChar( CP_ACP, 0, LinkFile, -1, wsz, MAX_PATH ); // Load the file.
HandleToResult = ppf->Load(wsz, STGM_READ );
if (SUCCEEDED(HandleToResult))
{
// HandleToResult = ShellLink->Resolve(g_MainWindow, SLR_ANY_MATCH | SLR_NO_UI);
// if (SUCCEEDED(HandleToResult))
// {
HandleToResult = ShellLink->GetPath(Path, 1024, &wfd, SLGP_SHORTPATH );
// HandleToResult = ShellLink->GetDescription(Path, 1024);
WORD wLen=(UINT)lstrlen(Path);
Path += wLen - 4;
TCHAR szExt[10];
lstrcpy (szExt, Path);
if ( (szExt[0] == '.') &&
((szExt[1] == 'e') || (szExt[1] == 'E')) &&
((szExt[2] == 'x') || (szExt[2] == 'X')) &&
((szExt[3] == 'e') || (szExt[3] == 'E')) )
// if (!lstrcmp(lpszPath, ".EXE"))
{
uiPrevErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS);
Path -= wLen - 4;
LinkFile += StartMenuLen + 1;
// LinkFile[strlen(lpszLinkFile)-4]='\0';
TCHAR szTemp[1024];
lstrcpy (szTemp, LinkFile);
szTemp[lstrlen (szTemp) - 4] = '\0';
//crop off preceding \'s
if (szTemp[0] == '\\')
{
TCHAR szTwo[1024];
for (DWORD dwi = 0; dwi<(DWORD)lstrlen (szTemp); dwi++)
{
szTwo[dwi] = szTemp[dwi + 1];
}
szTwo[dwi + 1] = '\0';
lstrcpy (szTemp, szTwo);
}
//crop off preceding \'s
if (szTemp[0] == '\\')
{
TCHAR szTwo[1024];
for (DWORD dwi=0; dwi<(DWORD)lstrlen(szTemp); dwi++)
{
szTwo[dwi]=szTemp[dwi+1];
}
szTwo[dwi+1]='\0';
lstrcpy(szTemp, szTwo);
}
// nuke duplicate \'s in file name
for (DWORD dwArgh = 0; dwArgh < 5; dwArgh++)
{
BOOL Glob1, Glob2, Glob3;
Glob1 = Glob2 = Glob3 =TRUE;
TCHAR szFin[1024];
for (DWORD dw1 = 0; (dw1 < (DWORD)lstrlen(szTemp)) && (Glob1 == TRUE); dw1++)
{
szFin[dw1] = szTemp[dw1];
if (szTemp[dw1] == '\\' && szTemp[dw1+1] == '\\')
{
for (DWORD dwThree = 0; dwThree < (DWORD)lstrlen(szTemp); dwThree++)
{
szFin[dw1 + dwThree] = szTemp[dw1+dwThree + 1];
}
szFin[dwThree + 1] = '\0';
lstrcpy (szTemp, szFin);
Glob1 = FALSE;
}
}
}
LogProc->StripCommas (szTemp);
LogProc->LogString(",%s", szTemp);
#ifdef MAXDEBUG
LogProc->LogString("\r\nGetting version: %s\r\n", lpszLinkFile);
#endif
GetAppVer (Path);
LinkFile -= StartMenuLen;
SetErrorMode(uiPrevErrorMode);
}
else
{
Path -= wLen - 4;
}
// }
}
}
ppf->Release();
}
ShellLink->Release();
return HandleToResult;
}
BOOL CLASS_GeneralAppWalk::GetAppVer(LPSTR AppName)
{
DWORD dwVerInfoSize;
DWORD dwZero;
LPVOID lpvFileInfo;
DWORD dwRetCode;
PDWORD pdwVerBuf;
UINT uLen;
DWORD dwTranslation;
TCHAR szString[MAX_PATH * 4];
TCHAR szFullString[MAX_PATH * 4];
TCHAR szTempString[MAX_PATH * 4];
dwVerInfoSize = GetFileVersionInfoSize(AppName, &dwZero);
if (!dwVerInfoSize) {
LogProc->LogString(",Blank,Blank,Blank,Blank,Blank,\r\n");
return TRUE;
}
lpvFileInfo = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwVerInfoSize);
if(!lpvFileInfo) {
LogProc->LogString(",Blank,Blank,Blank,Blank,Blank,\r\n");
return TRUE;
}
dwRetCode = GetFileVersionInfo(AppName, dwZero, dwVerInfoSize, lpvFileInfo);
if (!dwRetCode)
{
LogProc->LogString(",Blank,Blank,Blank,Blank,Blank,\r\n");
HeapFree(GetProcessHeap(), NULL, lpvFileInfo);
return TRUE;
}
uLen = 0;
pdwVerBuf = 0;
dwRetCode = VerQueryValue(lpvFileInfo, (LPSTR)"\\VarFileInfo\\Translation", (LPVOID*)&pdwVerBuf, &uLen);
if (!dwRetCode || !pdwVerBuf)
{
LogProc->LogString(",Blank,Blank,Blank,Blank,Blank,\r\n");
HeapFree(GetProcessHeap(), NULL, lpvFileInfo);
return TRUE;
}
dwTranslation = *pdwVerBuf;
wsprintf (szString, "\\StringFileInfo\\%04x%04x\\", LOWORD (dwTranslation), HIWORD(dwTranslation));
wsprintf (szFullString, "%sOriginalFileName", szString);
dwRetCode = VerQueryValue(lpvFileInfo, szFullString, (LPVOID*)&pdwVerBuf, &uLen);
if (uLen)
{
lstrcpy (szTempString, (TCHAR *)pdwVerBuf);
if (0 != lstrlen (szTempString) )
{
LogProc->StripCommas(szTempString);
LogProc->LogString(",%s", szTempString);
}
else
{
LogProc->LogString(",Blank");
}
}
else
{
LogProc->LogString(",Blank");
}
wsprintf(szFullString, "%sFileVersion", szString);
dwRetCode = VerQueryValue(lpvFileInfo, szFullString, (LPVOID*)&pdwVerBuf, &uLen);
if (uLen)
{
lstrcpy(szTempString, (TCHAR *)pdwVerBuf);
if (0 != lstrlen(szTempString))
{
LogProc->StripCommas(szTempString);
LogProc->LogString(",%s", szTempString);
}
else
{
LogProc->LogString(",Blank");
}
}
else
{
LogProc->LogString(",Blank");
}
wsprintf(szFullString, "%sProductName", szString);
dwRetCode = VerQueryValue(lpvFileInfo, szFullString, (LPVOID*)&pdwVerBuf, &uLen);
if (uLen)
{
lstrcpy(szTempString, (TCHAR *)pdwVerBuf);
if (0 != lstrlen(szTempString))
{
LogProc->StripCommas(szTempString);
LogProc->LogString(",%s", szTempString);
}
else
{
LogProc->LogString(",Blank");
}
}
else
{
LogProc->LogString(",Blank");
}
wsprintf(szFullString, "%sProductVersion", szString);
dwRetCode = VerQueryValue(lpvFileInfo, szFullString, (LPVOID*)&pdwVerBuf, &uLen);
if (uLen)
{
lstrcpy(szTempString, (TCHAR *)pdwVerBuf);
if (0 != strlen(szTempString))
{
LogProc->StripCommas(szTempString);
LogProc->LogString(",%s", szTempString);
}
else
{
LogProc->LogString(",Blank");
}
}
else
{
LogProc->LogString(",Blank");
}
wsprintf(szFullString, "%sCompanyName", szString);
dwRetCode = VerQueryValue(lpvFileInfo, szFullString, (LPVOID*)&pdwVerBuf, &uLen);
if (uLen)
{
lstrcpy(szTempString, (TCHAR *)pdwVerBuf);
if (lstrlen(szTempString))
{
LogProc->StripCommas(szTempString);
LogProc->LogString(",%s", szTempString);
}
else
{
LogProc->LogString(",Blank");
}
}
else
{
LogProc->LogString(",Blank");
}
LogProc->LogString(",\r\n");
HeapFree(GetProcessHeap(), NULL, lpvFileInfo);
return TRUE;
}
BOOL CLASS_GeneralAppWalk::GetCurrentWinDir(void)
{
HINSTANCE hInst2 = NULL;
LPFNDLLFUNC2 fProc = NULL;
hInst2 = LoadLibraryEx("kernel32.dll", NULL, DONT_RESOLVE_DLL_REFERENCES);
if(hInst2)
fProc = (LPFNDLLFUNC2)GetProcAddress(hInst2, "GetSystemWindowsDirectoryA");
if(fProc) {
if(!fProc(g_WindowsDirectory, MAX_PATH)) {
FreeLibrary(hInst2);
return FALSE;
}
}
else {
if(!GetWindowsDirectory(g_WindowsDirectory, MAX_PATH))
return FALSE;
}
if ( '\\' == g_WindowsDirectory[lstrlen(g_WindowsDirectory) - sizeof(TCHAR)] ) {
g_WindowsDirectory[lstrlen(g_WindowsDirectory) - sizeof(TCHAR)] = '\0';
}
if(hInst2)
FreeLibrary(hInst2);
return TRUE;
}