windows-nt/Source/XPSP1/NT/sdktools/cabs/symbolcd/symsetup/commandline.c
2020-09-26 16:20:57 +08:00

223 lines
8.3 KiB
C

#include "CommandLine.h"
#include <malloc.h>
BOOL WINAPI MakeSureDirectoryPathExistsW(LPCWSTR DirPath);
DWORD WINAPI CheckCommandLineOptions(INT ArgC, LPWSTR* ArgVW) {
DWORD dwReturnFlags = 0;
INT i;
WCHAR* cp;
WCHAR wszInstallPath[MAX_PATH+1];
for (i = 1; i < ArgC && wcschr(L"/-",ArgVW[i][0]) != NULL; ++i) {
for (cp = &ArgVW[i][1]; *cp != L'\0'; ++cp) {
switch (towupper(*cp)) {
case L'U': {
HKEY hKey;
LONG lStatus = 0;
LONG lCreatedOrOpened = 0;
SET_FLAG(dwReturnFlags, FLAG_UNATTENDED_INSTALL);
// next param isn't a flag (or NULL), so it *must* be the path to install to
if ( (i+1 < ArgC) && wcschr(L"/-",ArgVW[i+1][0]) == NULL ) {
i++; // account for the parameter removed
SET_FLAG(dwReturnFlags, FLAG_UNATTENDED_PATH_PROVIDED);
StringCchCopyW(wszInstallPath, MAX_PATH+1, ArgVW[i]);
// make sure path ends in '\'
if (wszInstallPath[wcslen(wszInstallPath)]!=L'\\')
StringCchCatW(wszInstallPath,MAX_PATH+1,L"\\");
// make sure the directory exists!
if (! MakeSureDirectoryPathExistsW(wszInstallPath) ) {
SET_FLAG(dwReturnFlags, FLAG_FATAL_ERROR);
} else {
// Either create the regkey (if it doesn't exist) or open it (if it
// does exist). lCreatedOrOpened can be tested against
// REG_CREATED_NEW_KEY or REG_OPENED_EXISTING_KEY to determine which
// occurred.
lStatus = RegCreateKeyExW(SYMBOLS_REGKEY_ROOT,
SYMBOLS_REGKEY_PATH,
0,
NULL,
REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS,
NULL,
&hKey,
&lCreatedOrOpened);
if (lStatus != ERROR_SUCCESS) {
SET_FLAG(dwReturnFlags, FLAG_FATAL_ERROR);
} else {
// Write the value of the path to SYMBOLS_REGKEY
lStatus = RegSetValueExW( hKey, SYMBOLS_REGKEY, 0, REG_SZ, (BYTE*)wszInstallPath, ((wcslen(wszInstallPath) + 1) * sizeof(WCHAR)));
if (lStatus != ERROR_SUCCESS) {
SET_FLAG(dwReturnFlags, FLAG_FATAL_ERROR);
}
// close the regkey
lStatus = RegCloseKey( hKey );
if (lStatus != ERROR_SUCCESS) {
SET_FLAG(dwReturnFlags, FLAG_ERROR);
}
}
} // else ...
// couldn't set the path requests, so use what's
// already in the registry.
} // else ...
// no path provided, so don't set anything- setupapi will
// nicely use the existing key or default to the value
// specified in the INF
// StringCchCopyW(wszInstallPath, MAX_PATH+1, DEFAULT_INSTALL_PATH);
}
break;
case L'Q':
SET_FLAG(dwReturnFlags, FLAG_TOTALLY_QUIET);
break;
case L'?': // explicit fall through
case L'H': // explicit fall through
default:
SET_FLAG(dwReturnFlags, FLAG_USAGE);
break;
}
}
}
if ( IS_FLAG_SET(dwReturnFlags, FLAG_USAGE) ) {
WCHAR UsageBuffer[1024];
StringCchPrintfW(UsageBuffer,
sizeof(UsageBuffer)/sizeof(WCHAR),
L"Usage: %s [ /u [<path>] [/q] ]\n\n"
L"/u [<path>] \n"
L" Unattended install. If <path> is specified install\n"
L" symbols to <path>. If no path is specified, symbols\n"
L" are installed to the default location.\n"
L" NOTE: USING UNATTENDED INSTALL MEANS YOU\n"
L" HAVE READ AND AGREED TO THE END USER LICENSE\n"
L" AGREEMENT FOR THIS PRODUCT.\n"
L"/q\n"
L" Valid only when using unattended install. Prevents\n"
L" error messages from being display if unattended\n"
L" install fails.\n"
L"/?\n"
L" Show this dialog box.\n\n"
L"If no options are specified, the interactive installation\n"
L" is started.",
ArgVW[0]);
MessageBoxW( NULL,
UsageBuffer,
L"Microsoft Windows Symbols",
0 );
}
return(dwReturnFlags);
}
// Modified from MakeSureDirectoryPathExists from dbghelp.h
// The same caveats apply. (see MSDN)
BOOL WINAPI MakeSureDirectoryPathExistsW(LPCWSTR DirPath) {
LPWSTR p, DirCopy;
DWORD dw;
// Make a copy of the string for editing.
__try {
DirCopy = (LPWSTR)malloc((wcslen(DirPath) + 1) * sizeof(WCHAR));
if (!DirCopy) {
return FALSE;
}
StringCchCopyW(DirCopy, wcslen(DirPath)+1, DirPath);
p = DirCopy;
// If the second character in the path is "\", then this is a UNC
// path, and we should skip forward until we reach the 2nd \ in the path.
if ((*p == L'\\') && (*(p+1) == L'\\')) {
p++; // Skip over the first \ in the name.
p++; // Skip over the second \ in the name.
// Skip until we hit the first "\" (\\Server\).
while (*p && *p != L'\\') {
p = CharNextW(p);
}
// Advance over it.
if (*p) {
p++;
}
// Skip until we hit the second "\" (\\Server\Share\).
while (*p && *p != L'\\') {
p = CharNextW(p);
}
// Advance over it also.
if (*p) {
p++;
}
} else
// Not a UNC. See if it's <drive>:
if (*(p+1) == L':' ) {
p++;
p++;
// If it exists, skip over the root specifier
if (*p && (*p == L'\\')) {
p++;
}
}
while( *p ) {
if ( *p == '\\' ) {
*p = '\0';
dw = GetFileAttributesW(DirCopy);
// Nothing exists with this name. Try to make the directory name and error if unable to.
if ( dw == 0xffffffff ) {
if ( !CreateDirectoryW(DirCopy,NULL) ) {
if( GetLastError() != ERROR_ALREADY_EXISTS ) {
free(DirCopy);
return FALSE;
}
}
} else {
if ( (dw & FILE_ATTRIBUTE_DIRECTORY) != FILE_ATTRIBUTE_DIRECTORY ) {
// Something exists with this name, but it's not a directory... Error
free(DirCopy);
return FALSE;
}
}
*p = L'\\';
}
p = CharNextW(p);
}
} __except (EXCEPTION_EXECUTE_HANDLER) {
SetLastError( GetExceptionCode() );
free(DirCopy);
return(FALSE);
}
free(DirCopy);
return TRUE;
}