windows-nt/Source/XPSP1/NT/shell/tools/chinproc/app.cpp
2020-09-26 16:20:57 +08:00

144 lines
3.8 KiB
C++

#include "priv.h"
#include <stdlib.h>
#include <stdio.h>
HINSTANCE g_hinst;
#define APP_VERSION "Version 0.2"
#define PFF_SYSTEM 0x00000001
void PrintSyntax(void)
{
fprintf(stderr, "chinproc.exe " APP_VERSION "\n\n");
fprintf(stderr, "Changes the InProcServer32 entry for any CLSID using\n");
fprintf(stderr, "<dll> from %%SystemRoot%%\\system32 to a local path,\n");
fprintf(stderr, "or vice versa.\n");
fprintf(stderr, "Syntax: chinproc [-s] {<path>|<dll>} \n\n");
fprintf(stderr, " -s Change to %%SystemRoot%%\\system32\\foo.dll\n");
fprintf(stderr, " (NT only)\n\n");
fprintf(stderr, " Default action is to set the InProcServer32 to <path>\n");
}
/*----------------------------------------------------------
Purpose: Worker function to do the work
Returns:
Cond: --
*/
int
DoWork(int cArgs, char * rgszArgs[])
{
LPSTR psz;
LPSTR pszDll = NULL;
DWORD dwFlags = 0;
int i;
int nRet = 0;
// (The first arg is actually the exe. Skip that.)
for (i = 1; i < cArgs; i++)
{
psz = rgszArgs[i];
// Check for options
if ('/' == *psz || '-' == *psz)
{
psz++;
switch (*psz)
{
case '?':
// Help
PrintSyntax();
return 0;
case 's':
dwFlags |= PFF_SYSTEM;
*psz++;
// Is this Win95?
if (0x80000000 & GetVersion())
{
// Yes; can't allow -s
fprintf(stderr, "Cannot use -s on Win95 machines.\n");
return -1;
}
break;
default:
// unknown
fprintf(stderr, "Invalid option -%c\n", *psz);
return -1;
}
}
else if (!pszDll)
pszDll = rgszArgs[i];
else
{
fprintf(stderr, "Ignoring invalid parameter - %s\n", rgszArgs[i]);
}
}
if (!pszDll)
{
PrintSyntax();
return -2;
}
// Enumerate the HKCR\CLSID for any CLSIDs that use pszDll.
DWORD dwRet;
HKEY hkeyCLSID;
dwRet = RegOpenKeyEx(HKEY_CLASSES_ROOT, TEXT("CLSID"), 0, KEY_SET_VALUE | KEY_READ, &hkeyCLSID);
if (NO_ERROR == dwRet)
{
DWORD dwIndex = 0;
TCHAR szSubkey[MAX_PATH];
while (ERROR_SUCCESS == RegEnumKey(hkeyCLSID, dwIndex++, szSubkey, SIZECHARS(szSubkey)))
{
TCHAR szPath[MAX_PATH];
DWORD cbPath = sizeof(szPath);
LPTSTR pszFile = PathFindFileName(pszDll);
// Does this entry match pszDll?
PathAppend(szSubkey, TEXT("InProcServer32"));
if (NO_ERROR == SHGetValue(hkeyCLSID, szSubkey, NULL, NULL, szPath, &cbPath) &&
0 == lstrcmpi(PathFindFileName(szPath), pszFile))
{
// Yes; change it according to dwFlags
fprintf(stdout, ".");
if (dwFlags & PFF_SYSTEM)
{
// Prepend %SystemRoot%\system32 on it
lstrcpy(szPath, TEXT("%SystemRoot%\\system32"));
PathAppend(szPath, pszDll);
SHSetValue(hkeyCLSID, szSubkey, NULL, REG_EXPAND_SZ, szPath, sizeof(szPath));
}
else
{
SHSetValue(hkeyCLSID, szSubkey, NULL, REG_SZ, pszDll, CbFromCch(lstrlen(pszDll) + 1));
}
}
}
fprintf(stdout, "\nFinished!\n");
RegCloseKey(hkeyCLSID);
}
else
fprintf(stderr, "Failed to open HKCR\\CLSID\n");
return nRet;
}
int __cdecl main(int argc, char * argv[])
{
return DoWork(argc, argv);
}