WindowsXP-SP1/base/ntsetup/win95upg/tools/appc_cnv/appc_cnv.c
2020-09-30 16:53:49 +02:00

505 lines
17 KiB
C

/*++
Copyright (c) 1997 Microsoft Corporation
Module Name:
appc_cnv.c
Abstract:
Author:
Calin Negreanu (calinn) 25-Mar-1999
Revision History:
<alias> <date> <comments>
--*/
#ifndef UNICODE
#error UNICODE needs to be defined
#else
#define _UNICODE
#endif
#include <windows.h>
#include <tchar.h>
#include <winnt.h>
#include <stdlib.h>
#include <stdio.h>
#include <setupapi.h>
#include <badapps.h>
BOOL CancelFlag = FALSE;
BOOL *g_CancelFlagPtr = &CancelFlag;
#ifdef DEBUG
extern BOOL g_DoLog;
#endif
HANDLE g_hHeap;
HINSTANCE g_hInst;
BOOL g_UseInf = FALSE;
PCTSTR g_DestInf = NULL;
DWORD g_ValueSeq = 0;
VOID
HelpAndExit (
VOID
)
{
printf ("Command line syntax:\n\n"
"tstbadap [-i:<inffile>]\n\n"
"Optional Arguments:\n"
" -i:<inffile> - Specifies INF file that will contain CheckBadApps data.\n"
);
exit(255);
}
BOOL
DoesFileExistW(
IN PCWSTR FileName,
OUT PWIN32_FIND_DATAW FindData
);
BOOL
pWorkerFn (
VOID
);
INT
__cdecl
main (
INT argc,
CHAR *argv[]
)
{
INT i;
WCHAR destInf[MAX_PATH];
#ifdef DEBUG
g_DoLog = TRUE;
#endif
//
// Parse command line
//
for (i = 1 ; i < argc ; i++) {
if (argv[i][0] == '-' || argv[i][0] == '/') {
switch (tolower (argv[i][1])) {
case 'i':
g_UseInf = TRUE;
if (argv[i][2] == ':') {
MultiByteToWideChar (CP_ACP, MB_PRECOMPOSED, &argv[i][3], -1, destInf, MAX_PATH);
g_DestInf = destInf;
} else if (i + 1 < argc) {
i++;
MultiByteToWideChar (CP_ACP, MB_PRECOMPOSED, argv[i], -1, destInf, MAX_PATH);
g_DestInf = destInf;
} else {
HelpAndExit();
}
break;
default:
HelpAndExit();
}
} else {
HelpAndExit();
}
}
if ((g_UseInf) && (g_DestInf == NULL)) {
HelpAndExit();
}
g_hHeap = GetProcessHeap();
g_hInst = GetModuleHandle (NULL);
pWorkerFn ();
return 0;
}
PCWSTR
GetFileNameFromPathW (
IN PCWSTR PathSpec
);
#define S_CHECK_BAD_APPS TEXT("SYSTEM\\CurrentControlSet\\Control\\Session Manager\\CheckBadApps")
#define S_CHECK_BAD_APPS_400 TEXT("SYSTEM\\CurrentControlSet\\Control\\Session Manager\\CheckBadApps400")
#define S_APP_COMPATIBILITY TEXT("SYSTEM\\CurrentControlSet\\Control\\Session Manager\\~AppCompatibility")
BOOL
OutputStrValue (
IN PCTSTR VersionValue,
OUT DWORD *Size,
OUT PBYTE *Data
)
{
PTSTR result;
*Size = (_tcslen (VersionValue) + 1) * sizeof (TCHAR);
result = HeapAlloc (g_hHeap, 0, *Size);
if (!result) {
return FALSE;
}
_tcscpy (result, VersionValue);
*Data = (PBYTE)result;
return TRUE;
}
typedef struct {
ULONGLONG Value;
ULONGLONG Mask;
} BINVER_DATA, *PBINVER_DATA;
BOOL
OutputBinVerValue (
IN PCTSTR VersionValue,
OUT DWORD *Size,
OUT PBYTE *Data
)
{
PBINVER_DATA result;
PWORD maskIdx;
PWORD valueIdx;
UINT index;
result = HeapAlloc (g_hHeap, 0, sizeof (BINVER_DATA));
if (!result) {
return FALSE;
}
result->Value = 0;
result->Mask = 0;
*Size = sizeof (BINVER_DATA);
maskIdx = (PWORD)&(result->Mask) + 3;
valueIdx = (PWORD)&(result->Value) + 3;
index = 0;
while (VersionValue && *VersionValue) {
*valueIdx = (WORD) _tcstoul ((PTSTR)VersionValue, &((PTSTR)VersionValue), 10);
if (*VersionValue && (_tcsnextc (VersionValue) != TEXT('.'))) {
return 0;
}
VersionValue = _tcsinc (VersionValue);
*maskIdx = 0xFFFF;
valueIdx --;
maskIdx --;
index ++;
if (index >= 4) {
break;
}
}
*Data = (PBYTE)result;
return TRUE;
}
BOOL
OutputUpToBinVerValue (
IN PCTSTR VersionValue,
OUT DWORD *Size,
OUT PBYTE *Data
)
{
PULONGLONG result;
PWORD valueIdx;
UINT index;
result = HeapAlloc (g_hHeap, 0, sizeof (ULONGLONG));
if (!result) {
return FALSE;
}
*result = 0;
*Size = sizeof (ULONGLONG);
valueIdx = (PWORD)result + 3;
index = 0;
while (VersionValue && *VersionValue) {
*valueIdx = (WORD) _tcstoul ((PTSTR)VersionValue, &((PTSTR)VersionValue), 10);
if (*VersionValue && (_tcsnextc (VersionValue) != TEXT('.'))) {
return 0;
}
VersionValue = _tcsinc (VersionValue);
valueIdx --;
index ++;
if (index >= 4) {
break;
}
}
*Data = (PBYTE)result;
return TRUE;
}
VOID
pPrintBadAppsData (
PCTSTR BadAppsName,
PCTSTR AddnlBadAppsName,
PCTSTR KeyName,
PCTSTR ValueName,
DWORD MsgId,
DWORD AppType,
BOOL AppBinVer,
PCTSTR AppBinVerData
)
{
BYTE blob [8192];
PBYTE blobPtr;
BADAPP_PROP appProp;
DWORD verId;
PBYTE Data;
DWORD DataSize;
LONG status;
HKEY addnlKey;
HKEY exeKey;
TCHAR valueName [MAX_PATH];
blobPtr = blob;
appProp.Size = sizeof (BADAPP_PROP);
appProp.MsgId = MsgId;
appProp.AppType = AppType;
CopyMemory (blobPtr, &appProp, sizeof (BADAPP_PROP));
blobPtr += sizeof (BADAPP_PROP);
if (AppBinVer) {
verId = VTID_UPTOBINPRODUCTVER;
CopyMemory (blobPtr, &verId, sizeof (DWORD));
blobPtr += sizeof (DWORD);
OutputUpToBinVerValue (AppBinVerData, &DataSize, &Data);
CopyMemory (blobPtr, &DataSize, sizeof (DWORD));
blobPtr += sizeof (DWORD);
CopyMemory (blobPtr, Data, DataSize);
blobPtr += DataSize;
HeapFree (g_hHeap, 0, Data);
}
verId = VTID_REQFILE;
CopyMemory (blobPtr, &verId, sizeof (DWORD));
blobPtr += sizeof (DWORD);
OutputStrValue (ValueName, &DataSize, &Data);
CopyMemory (blobPtr, &DataSize, sizeof (DWORD));
blobPtr += sizeof (DWORD);
CopyMemory (blobPtr, Data, DataSize);
blobPtr += DataSize;
HeapFree (g_hHeap, 0, Data);
DataSize = 0;
CopyMemory (blobPtr, &DataSize, sizeof (DWORD));
blobPtr += sizeof (DWORD);
if (g_UseInf) {
} else {
status = RegCreateKey (HKEY_LOCAL_MACHINE, AddnlBadAppsName, &addnlKey);
if (status == ERROR_SUCCESS) {
status = RegCreateKey (addnlKey, KeyName, &exeKey);
if (status == ERROR_SUCCESS) {
_itot (g_ValueSeq, valueName, 10);
RegSetValueEx (exeKey, valueName, 0, REG_BINARY, blob, blobPtr - blob);
}
}
}
}
BOOL
pWorkerFn (
VOID
)
{
HKEY badAppKey = NULL;
TCHAR exeKeyStr [MAX_PATH + 1];
DWORD idxKey = 0;
LONG statKey;
HKEY exeKey = NULL;
LONG status;
DWORD index;
TCHAR valueName [MAX_PATH];
DWORD valueSize;
DWORD valueType;
DWORD blobSize;
BYTE blobData[4096];
DWORD msgId;
DWORD appType;
BOOL appBinVer;
TCHAR appBinVerStr[MAX_PATH];
TCHAR flagsValue [MAX_PATH];
TCHAR binVerValue [MAX_PATH];
BYTE addnlData[4096];
PCTSTR flagsPtr;
DWORD addnlSize;
if (RegOpenKey (HKEY_LOCAL_MACHINE, S_CHECK_BAD_APPS, &badAppKey) == ERROR_SUCCESS) {
idxKey = 0;
statKey = ERROR_SUCCESS;
while (statKey == ERROR_SUCCESS) {
statKey = RegEnumKey (badAppKey, idxKey, exeKeyStr, MAX_PATH + 1);
if (statKey == ERROR_SUCCESS) {
if (RegOpenKey (badAppKey, exeKeyStr, &exeKey) == ERROR_SUCCESS) {
index = 0;
status = ERROR_SUCCESS;
while (status == ERROR_SUCCESS) {
blobSize = 4096;
valueSize = MAX_PATH;
status = RegEnumValue(exeKey, index, valueName, &valueSize, NULL, &valueType, blobData, &blobSize);
if ((status == ERROR_SUCCESS) ||
(status == ERROR_MORE_DATA)
) {
if (valueType == REG_SZ) {
msgId = 0;
appType = 0;
appBinVer = FALSE;
msgId = _ttoi ((PCTSTR) blobData);
if (msgId) {
g_ValueSeq ++;
_tcscpy (flagsValue, TEXT("Flags"));
_tcscat (flagsValue, valueName);
_tcscpy (binVerValue, TEXT("Version"));
_tcscat (binVerValue, valueName);
addnlSize = 4096;
status = RegQueryValueEx (exeKey, flagsValue, NULL, &valueType, addnlData, &addnlSize);
if (((status == ERROR_SUCCESS) || (status == ERROR_MORE_DATA)) && (valueType == REG_SZ)) {
flagsPtr = (PCTSTR) addnlData;
while (*flagsPtr) {
if (_tcsnextc (flagsPtr) == TEXT('Y')) {
appType = appType | APPTYPE_INC_HARDBLOCK;
}
if (_tcsnextc (flagsPtr) == TEXT('L')) {
appType = appType | APPTYPE_MINORPROBLEM;
}
if (_tcsnextc (flagsPtr) == TEXT('N')) {
appType = appType | APPTYPE_FLAG_NONET;
}
if (_tcsnextc (flagsPtr) == TEXT('F')) {
appType = appType | APPTYPE_FLAG_FAT32;
}
flagsPtr = _tcsinc (flagsPtr);
}
}
if ((appType & APPTYPE_TYPE_MASK) == 0) {
appType |= APPTYPE_INC_NOBLOCK;
}
addnlSize = 4096;
status = RegQueryValueEx (exeKey, binVerValue, NULL, &valueType, addnlData, &addnlSize);
if (((status == ERROR_SUCCESS) || (status == ERROR_MORE_DATA)) && (valueType == REG_BINARY)) {
PWORD valueIdx;
appBinVer = TRUE;
valueIdx = (PWORD) (addnlData);
_stprintf (appBinVerStr, TEXT("%d.%d.%d.%d"), *(valueIdx + 1), *valueIdx, *(valueIdx + 3), *(valueIdx + 2));
}
pPrintBadAppsData (
S_CHECK_BAD_APPS,
S_APP_COMPATIBILITY,
exeKeyStr,
valueName,
msgId,
appType,
appBinVer,
appBinVerStr
);
status = ERROR_SUCCESS;
}
}
}
index ++;
}
}
}
idxKey ++;
}
}
if (RegOpenKey (HKEY_LOCAL_MACHINE, S_CHECK_BAD_APPS_400, &badAppKey) == ERROR_SUCCESS) {
idxKey = 0;
statKey = ERROR_SUCCESS;
while (statKey == ERROR_SUCCESS) {
statKey = RegEnumKey (badAppKey, idxKey, exeKeyStr, MAX_PATH + 1);
if (statKey == ERROR_SUCCESS) {
if (RegOpenKey (badAppKey, exeKeyStr, &exeKey) == ERROR_SUCCESS) {
index = 0;
status = ERROR_SUCCESS;
while (status == ERROR_SUCCESS) {
blobSize = 4096;
valueSize = MAX_PATH;
status = RegEnumValue(exeKey, index, valueName, &valueSize, NULL, &valueType, blobData, &blobSize);
if ((status == ERROR_SUCCESS) ||
(status == ERROR_MORE_DATA)
) {
if (valueType == REG_SZ) {
msgId = 0;
appType = 0;
appBinVer = FALSE;
msgId = _ttoi ((PCTSTR) blobData);
if (msgId) {
g_ValueSeq ++;
_tcscpy (flagsValue, TEXT("Flags"));
_tcscat (flagsValue, valueName);
_tcscpy (binVerValue, TEXT("Version"));
_tcscat (binVerValue, valueName);
addnlSize = 4096;
status = RegQueryValueEx (exeKey, flagsValue, NULL, &valueType, addnlData, &addnlSize);
if (((status == ERROR_SUCCESS) || (status == ERROR_MORE_DATA)) && (valueType == REG_SZ)) {
flagsPtr = (PCTSTR) addnlData;
while (*flagsPtr) {
if (_tcsnextc (flagsPtr) == TEXT('Y')) {
appType = appType | APPTYPE_INC_HARDBLOCK;
}
if (_tcsnextc (flagsPtr) == TEXT('L')) {
appType = appType | APPTYPE_MINORPROBLEM;
}
if (_tcsnextc (flagsPtr) == TEXT('N')) {
appType = appType | APPTYPE_FLAG_NONET;
}
if (_tcsnextc (flagsPtr) == TEXT('F')) {
appType = appType | APPTYPE_FLAG_FAT32;
}
flagsPtr = _tcsinc (flagsPtr);
}
}
if ((appType & APPTYPE_TYPE_MASK) == 0) {
appType |= APPTYPE_INC_NOBLOCK;
}
addnlSize = 4096;
status = RegQueryValueEx (exeKey, binVerValue, NULL, &valueType, addnlData, &addnlSize);
if (((status == ERROR_SUCCESS) || (status == ERROR_MORE_DATA)) && (valueType == REG_BINARY)) {
PWORD valueIdx;
appBinVer = TRUE;
valueIdx = (PWORD) (addnlData);
_stprintf (appBinVerStr, TEXT("%d.%d.%d.%d"), *(valueIdx + 1), *valueIdx, *(valueIdx + 3), *(valueIdx + 2));
}
pPrintBadAppsData (
S_CHECK_BAD_APPS_400,
S_APP_COMPATIBILITY,
exeKeyStr,
valueName,
msgId,
appType,
appBinVer,
appBinVerStr
);
status = ERROR_SUCCESS;
}
}
}
index ++;
}
}
}
idxKey ++;
}
}
return TRUE;
}