|
|
#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; }
|