|
|
// Copyright (c) 1998-1999 Microsoft Corporation
/******************************************************************************
* * ACREGL.C * * Application Compatibility Registry Lookup Helper Program * * *******************************************************************************/
#include "precomp.h"
#pragma hdrstop
// #include <winreg.h>
#define MAXLEN 512
// Options
// The strip char option will strip the rightmost n instances
// of the specified character from the output. If the count
// is omitted, then a single instance is removed.
//
// Example: STRIPCHAR\3 will change
// C:\WINNT40\Profiles\All Users\Start Menu to
// C:\WINNT40
#define OPTION_STRIP_CHAR L"STRIPCHAR"
// The strip path option strips off the path.
//
// Example: STRIPPATH will change
// C:\WINNT40\Profiles\All Users\Start Menu to
// Start Menu
#define OPTION_STRIP_PATH L"STRIPPATH"
// The get path option gets the common paths
//
// Example: GETPATHS will return
//
#define OPTION_GET_PATHS L"GETPATHS"
// Define the strings used for setting the user/common paths
#define COMMON_STARTUP L"COMMON_STARTUP"
#define COMMON_START_MENU L"COMMON_START_MENU"
#define COMMON_PROGRAMS L"COMMON_PROGRAMS"
#define USER_START_MENU L"USER_START_MENU"
#define USER_STARTUP L"USER_STARTUP"
#define USER_PROGRAMS L"USER_PROGRAMS"
#define MY_DOCUMENTS L"MY_DOCUMENTS"
#define TEMPLATES L"TEMPLATES"
#define APP_DATA L"APP_DATA"
// Option Block.
// Scan Options will populate
// this struct.
typedef struct { WCHAR stripChar; // Character to strip.
int stripNthChar; // Strip nth occurrence from the right.
int stripPath; // Strip path.
int getPaths; // Get the common paths
} OptionBlock;
//
// Strip quotes from argument if they exist, convert to unicode, and expand
// environment variables.
//
int ParseArg(CHAR *inarg, WCHAR *outarg) { WCHAR T[MAXLEN+1], wcin[MAXLEN+1]; int retval;
// Convert to Ansi
OEM2ANSIA(inarg, (USHORT)strlen(inarg)); wsprintf(wcin, L"%S", inarg);
if (wcin[0] == L'"') { wcscpy(T, &wcin[1]); if (T[wcslen(T)-1] == L'"') T[wcslen(T)-1] = UNICODE_NULL; else return(-1); // Mismatched quotes
} else wcscpy(T, wcin);
retval = ExpandEnvironmentStrings(T, outarg, MAXLEN); if ((retval == 0) || (retval > MAXLEN)) return(-1); return(retval); }
//
// See comment above OPTION_STRIP_CHAR definition.
//
void StripChar(WCHAR *s, WCHAR c, int num) { if(s) { WCHAR *p = s + wcslen(s) + 1;
while ((num != 0) && (p != s)) { p--; if (*p == c) num--; }
*p = 0; } }
//
// Strips the path from the
// specified string.
//
void StripPath(WCHAR *s) {
WCHAR *p = wcsrchr(s, L'\\');
if (p != 0) wcscpy(s, p+1);
}
//
// Populates option block.
//
int ScanOptions(WCHAR *optionString, OptionBlock* options) { WCHAR *curOption; WCHAR temp[MAXLEN+1];
// Clear out option block.
memset(options, 0, sizeof(OptionBlock));
// Trivial Reject.
if (*optionString == 0) return 0;
// Uppercase a copy of the option string.
wcscpy(temp, optionString); _wcsupr(temp);
// Look for strip char option.
curOption = wcsstr(temp, OPTION_STRIP_CHAR);
if (curOption != 0) { // Change current option so it points into the original
// option, not the uppercased copy.
curOption = (WCHAR*)((INT_PTR)optionString + ((INT_PTR)curOption - (INT_PTR)temp));
// Get parameters after strip specifier.
// If there are not any then error.
curOption += (sizeof(OPTION_STRIP_CHAR)/sizeof(WCHAR)) - 1; if (*curOption == UNICODE_NULL || *curOption == L' ') return 1;
// Get the character to strip.
options->stripChar = *curOption++;
// Get the number of occurrrences.
// If not specified then assume 1.
if (*curOption == UNICODE_NULL || *curOption == L' ') options->stripNthChar = 1; else options->stripNthChar = _wtoi(curOption); }
// Look for leaf option.
curOption = wcsstr(temp, OPTION_STRIP_PATH); if (curOption != UNICODE_NULL) options->stripPath = 1;
// Look get paths option
curOption = wcsstr(temp, OPTION_GET_PATHS); if (curOption != UNICODE_NULL) options->getPaths = 1;
return 0;
}
//
// Outputs the common directories into the temp file
// Input: file (input) pointer to open handle for the batch file
// Returns: 0 - success
// 1 - failure
//
int GetPaths(FILE *file) { WCHAR szPath[MAX_PATH+1];
if( !GetWindowsDirectory(szPath, MAX_PATH) ){ return (1); }
if (SHGetFolderPath(NULL, CSIDL_COMMON_STARTMENU, NULL, 0, szPath) == S_OK) { fwprintf(file, L"SET %s=%s\n", COMMON_START_MENU, szPath); } else { return(1); }
if (SHGetFolderPath(NULL, CSIDL_COMMON_STARTUP, NULL, 0, szPath) == S_OK) { fwprintf(file, L"SET %s=%s\n", COMMON_STARTUP, szPath); } else { return(1); }
if (SHGetFolderPath(NULL, CSIDL_COMMON_PROGRAMS, NULL, 0, szPath) == S_OK) { fwprintf(file, L"SET %s=%s\n", COMMON_PROGRAMS, szPath); } else { return(1); }
if (SHGetFolderPath(NULL, CSIDL_STARTMENU, NULL, 0, szPath) == S_OK) { fwprintf(file, L"SET %s=%s\n", USER_START_MENU, szPath); } else { return(1); }
if (SHGetFolderPath(NULL, CSIDL_STARTUP, NULL, 0, szPath) == S_OK) { fwprintf(file, L"SET %s=%s\n", USER_STARTUP, szPath); } else { return(1); }
if (SHGetFolderPath(NULL, CSIDL_PROGRAMS, NULL, 0, szPath) == S_OK) { fwprintf(file, L"SET %s=%s\n", USER_PROGRAMS, szPath); } else { return(1); }
// MY_DOCUMENTS should only be the last component of the path
if (SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, 0, szPath) == S_OK) { StripPath(szPath); fwprintf(file, L"SET %s=%s\n", MY_DOCUMENTS, szPath); } else { return(1); }
// TEMPLATES should only be the last component of the path
if (SHGetFolderPath(NULL, CSIDL_TEMPLATES, NULL, 0, szPath) == S_OK) { StripPath(szPath); fwprintf(file, L"SET %s=%s\n", TEMPLATES, szPath); } else { return(1); }
// APP_DATA should only be the last component of the path
if (SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, 0, szPath) == S_OK) { StripPath(szPath); fwprintf(file, L"SET %s=%s\n", APP_DATA, szPath); } else { return(1); }
return(0); }
int __cdecl main(INT argc, CHAR **argv) { FILE *OutFP; WCHAR OutFN[MAXLEN+1]; WCHAR EVName[MAXLEN+1]; WCHAR KeyName[MAXLEN+1]; WCHAR ValName[MAXLEN+1]; WCHAR Temp[MAXLEN+1]; WCHAR Opts[MAXLEN+1]; struct HKEY__ *Hive; DWORD RetType, RetSize; HKEY TargetKey; LONG Ret; OptionBlock options; int rc=0;
//
// Process the command line arguments. We expect:
//
// acregl FileName EnvVarName KeyName ValueName Options
//
// The program uses exit code 0 to indicate success or
// exit code 1 for failure.
//
if (argc != 6) return(1);
setlocale(LC_ALL, ".OCP");
if (ParseArg(argv[1], OutFN) <= 0) return(1); if (ParseArg(argv[2], EVName) <= 0) return(1); if (ParseArg(argv[3], Temp) <= 0) return(1); if (_wcsnicmp(L"HKLM\\", Temp, 5) == 0) Hive = HKEY_LOCAL_MACHINE; else if (_wcsnicmp(L"HKCU\\", Temp, 5) == 0) Hive = HKEY_CURRENT_USER; else return(1); wcscpy(KeyName,&Temp[5]);
if (ParseArg(argv[4], ValName) < 0) // Ok if 0 is returned
return(1); if (ParseArg(argv[5], Opts) <= 0) return(1);
if (ScanOptions(Opts, &options) != 0) return 1;
// wprintf(L"OutFN <%ws>\n",OutFN);
// wprintf(L"EVName <%ws>\n",EVName);
// wprintf(L"KeyName <%ws>, Hive 0x%x\n",KeyName, Hive);
// wprintf(L"ValName <%ws>\n",ValName);
// wprintf(L"Opts <%ws>\n",Opts);
// If the GETPATHS option isn't specified, open the reg keys
if (options.getPaths == 0) {
//
// Read the specified key and value from the registry. The ANSI
// registry functions are used because the command line arguments
// are in ANSI and when we write the data out it also needs to be
// in ANSI.
//
Ret = RegOpenKeyEx(Hive, KeyName, 0, KEY_READ, &TargetKey); if (Ret != ERROR_SUCCESS) return(1); RetSize = MAXLEN; Ret = RegQueryValueEx(TargetKey, ValName, 0, &RetType, (LPBYTE) &Temp, &RetSize); if (Ret != ERROR_SUCCESS) return(1); //Now we need to procedd DWORDs too
if(RetType == REG_DWORD) { DWORD dwTmp = (DWORD)(*Temp); _itow((int)dwTmp,Temp,10); } RegCloseKey(TargetKey); }
//
// Process Options
//
//
// Write a SET statement to the specified file. The file can be
// executed from a script which will set the indicated environment
// variable. This is a round-about method, but there appears to be
// no easy method for setting environment variables in the parent's
// environment.
//
// wprintf(L"SET %s=%s\n",EVName,Temp);
OutFP = _wfopen(OutFN, L"w"); if (OutFP == NULL) return(1);
if (options.stripNthChar != 0) StripChar(Temp, options.stripChar, options.stripNthChar);
if (options.stripPath != 0) StripPath(Temp);
if (options.getPaths != 0) { if (GetPaths(OutFP)) { rc = 1; } } else { fwprintf(OutFP, L"SET %s=%s\n", EVName, Temp); }
fclose(OutFP);
return(rc); }
|