|
|
//+--------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1994 - 1998.
//
// File: script.cpp
//
// Contents: Functions for working with Darwin files, both packages,
// transforms and scripts.
//
// Classes:
//
// Functions: BuildScriptAndGetActInfo
//
// History: 1-14-1998 stevebl Created
//
//---------------------------------------------------------------------------
#include "precomp.hxx"
//+--------------------------------------------------------------------------
//
// Function: RegDeleteTree
//
// Synopsis: deletes a registry key and all of its children
//
// Arguments: [hKey] - handle to the key's parent
// [szSubKey] - name of the key to be deleted
//
// Returns: ERROR_SUCCESS
//
// History: 1-14-1998 stevebl Moved from old project
//
//---------------------------------------------------------------------------
LONG RegDeleteTree(HKEY hKey, TCHAR * szSubKey) { HKEY hKeyNew; LONG lResult = RegOpenKey(hKey, szSubKey, &hKeyNew); if (lResult != ERROR_SUCCESS) { return lResult; } TCHAR szName[256]; szName[0] = 0; while (ERROR_SUCCESS == RegEnumKey(hKeyNew, 0, szName, 256)) { RegDeleteTree(hKeyNew, szName); } RegCloseKey(hKeyNew); return RegDeleteKey(hKey, szSubKey); }
extern "C" HRESULT GenerateScript( PACKAGEDETAIL* pd, WCHAR* wszScriptPath ) { return BuildScriptAndGetActInfo( *pd, FALSE, FALSE, wszScriptPath ); }
//+--------------------------------------------------------------------------
//
// Function: BuildScriptAndGetActInfo
//
// Synopsis: Builds the script file and fills in the ACTINFO structure
// member in the PACKAGEDETAIL structure.
//
// Arguments: [szScriptRoot] - [in] the subdirectory that the script file
// should be place in.
// [pd] - [in/out] package detail structure - see
// notes for complete list of fields that
// should be filled in and the list of fields
// that are set on return
//
// Returns: S_OK - success
// <other> - error
//
// Modifies: all fields under pd.pActInfo (only on success)
// also modifies pd.pInstallInfo->cScriptLen
//
// History: 1-14-1998 stevebl Created
//
// Notes: On input:
// pd.cSources must be >= 1.
// pd.pszSourceList[] contains the MSI package and the list of
// (if any) transforms to be applied.
// pd.pPlatformInfo should be completely filled in (only one
// locale).
// pd.pInstallInfo->pszScriptFile contains the name of the
// script file to be generated.
//
// On output:
// The script file will be generated under the appropriate name
// and in the appropriate directory.
// pd.pActInfo will be completely filled in.
//
//---------------------------------------------------------------------------
HRESULT BuildScriptAndGetActInfo(PACKAGEDETAIL & pd, BOOL bFileExtensionsOnly, BOOL bGenerateClasses /* =TRUE */, WCHAR* wszScriptPath /* = NULL */ ) { DebugMsg((DM_VERBOSE, TEXT("BuldScriptAndGetActInfo called with bFileExtensionsOnly == %u"), bFileExtensionsOnly)); CHourglass hourglass; HRESULT hr; UINT uMsiStatus; LONG error; int i; WCHAR* szScriptPath = pd.pInstallInfo->pszScriptPath;
if ( wszScriptPath ) { szScriptPath = wszScriptPath; }
CString szTransformList = L"";
CClassCollection Classes( &pd );
if (pd.cSources > 1) { CString szSource = pd.pszSourceList[0]; int nChars = 1 + szSource.ReverseFind(L'\\'); BOOL fTransformsAtSource = TRUE; for (i = 1; i < pd.cSources && TRUE == fTransformsAtSource; i++) { if (0 == wcsncmp(szSource, pd.pszSourceList[i], nChars)) { // make sure there isn't a sub-path
int n = nChars; while (0 != pd.pszSourceList[i][n] && TRUE == fTransformsAtSource) { if (pd.pszSourceList[i][n] == L'\\') { fTransformsAtSource = FALSE; } n++; } } else { fTransformsAtSource = FALSE; } } if (fTransformsAtSource) { szTransformList = L"@"; } else { szTransformList = L"|"; nChars = 0; } for (i = 1; i < pd.cSources; i++) { if (i > 1) { szTransformList += L";"; } szTransformList += &pd.pszSourceList[i][nChars]; } }
// disable MSI ui
MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL);
// build the script file
TCHAR szTempPath[MAX_PATH]; TCHAR szTempFileName[MAX_PATH]; if (0 != GetTempPath(sizeof(szTempPath) / sizeof(szTempPath[0]), szTempPath)) { if (0 == GetTempFileName(szTempPath, TEXT("ADE"), 0, szTempFileName)) { goto Failure; }
DWORD dwPlatform;
if ( CAppData::Is64Bit( &pd ) ) { dwPlatform = CAppData::Get64BitMsiArchFlags( &pd ); } else { dwPlatform = MSIARCHITECTUREFLAGS_X86; }
uMsiStatus = MsiAdvertiseProductEx( pd.pszSourceList[0], szTempFileName, szTransformList, LANGIDFROMLCID(pd.pPlatformInfo->prgLocale[0]), dwPlatform, 0);
if (uMsiStatus) { DeleteFile(szTempFileName); DebugMsg((DM_WARNING, TEXT("MsiAdvertiseProduct failed with %u"), uMsiStatus)); LogADEEvent(EVENTLOG_ERROR_TYPE, EVENT_ADE_GENERATESCRIPT_ERROR, HRESULT_FROM_WIN32(uMsiStatus), pd.pszSourceList[0]); // an error occurred
return HRESULT_FROM_WIN32((long)uMsiStatus); }
// fill in the ActInfo
if ( bGenerateClasses ) { hr = Classes.GetClasses( bFileExtensionsOnly ); } else { hr = S_OK; }
if ( SUCCEEDED( hr ) ) { if (!CopyFile(szTempFileName, szScriptPath, FALSE)) { hr = HRESULT_FROM_WIN32(GetLastError()); DeleteFile(szTempFileName); return hr; }
DeleteFile(szTempFileName); } } else { Failure: hr = HRESULT_FROM_WIN32(GetLastError()); }
return hr; }
|