|
|
/*++
Copyright (c) 2000 Microsoft Corporation
Module Name:
common.cpp
Abstract:
Common Function calls for msm generation
Author:
Xiaoyu Wu(xiaoyuw) 01-Aug-2001
--*/ #include "msmgen.h"
#include "msidefs.h"
#include "objbase.h"
#include "fusionhandle.h"
#include "coguid.h"
inline BOOL IsDotOrDotDot(PCWSTR str) { return ((str[0] == L'.') && ((str[1] == L'\0') || ((str[1] == L'.') && (str[2] == L'\0')))); }
//
// simple function, check the ext of the filename
//
BOOL IsIDTFile(PCWSTR pwzStr) { PWSTR p = wcsrchr(pwzStr, L'.'); if ( p ) { if ( _wcsicmp(p, IDT_EXT) == 0) // idt files
return TRUE; } return FALSE; }
//
//Function:
//
// get moduleID from the msm file, if not present, generate a new one and write related entried into the Database
//
HRESULT SetModuleID() { HRESULT hr = S_OK; WCHAR tmp[MAX_PATH]; LPOLESTR tmpstr = NULL; DWORD cch = NUMBER_OF(tmp); UINT datatype; PMSIHANDLE hSummaryInfo = NULL; IF_NOTSUCCESS_SET_HRERR_EXIT(MsiGetSummaryInformation(g_MsmInfo.m_hdb, NULL, 3, &hSummaryInfo)); IF_NOTSUCCESS_SET_HRERR_EXIT(MsiSummaryInfoGetPropertyW(hSummaryInfo, PID_REVNUMBER, &datatype, 0,0, tmp, &cch));
//
// because msm has existed before, it should has a module ID, otherwise, it should generate a new one
//
if (cch == 0) { if (IsEqualGUID(g_MsmInfo.m_guidModuleID, GUID_NULL)) //otherwise, user has input a guid
{ IFFAILED_EXIT(::CoCreateGuid(&g_MsmInfo.m_guidModuleID)); } IFFAILED_EXIT(StringFromCLSID(g_MsmInfo.m_guidModuleID, &tmpstr)); IF_NOTSUCCESS_SET_HRERR_EXIT(MsiSummaryInfoSetProperty(hSummaryInfo, PID_REVNUMBER, VT_LPSTR, 0,0, tmpstr)); IF_NOTSUCCESS_SET_HRERR_EXIT(MsiSummaryInfoSetProperty(hSummaryInfo, PID_PAGECOUNT, VT_I4, 150, 0, 0)); } else { //
// get ModuleID from msm and save it into the global structure
//
IFFAILED_EXIT(CLSIDFromString(LPOLESTR(tmp), &g_MsmInfo.m_guidModuleID)); } IFFAILED_EXIT(GetMsiGUIDStrFromGUID(MSIGUIDSTR_WITH_PREPEND_DOT, g_MsmInfo.m_guidModuleID, g_MsmInfo.m_sbModuleGuidStr));
Exit: MsiSummaryInfoPersist(hSummaryInfo); CoTaskMemFree(tmpstr); return hr; }
//
// Purpose:
// make sure the tables we want to use is avaiable, if not, import the tables
// Input Param:
// Fully qulified msm filename
//
HRESULT OpenMsmFileForMsmGen(PCWSTR msmfile) { HRESULT hr = S_OK; BOOL fUsingExistedMsm = FALSE;
if (g_MsmInfo.m_hdb == NULL) { if (g_MsmInfo.m_enumGenMode == MSMGEN_OPR_NEW) { ASSERT_NTC(g_MsmInfo.m_sbMsmTemplateFile.IsEmpty() == FALSE); IFFALSE_EXIT(CopyFileW(g_MsmInfo.m_sbMsmTemplateFile, msmfile, FALSE)); IFFALSE_EXIT(SetFileAttributesW(msmfile, FILE_ATTRIBUTE_NORMAL)); } else // get it from the msm file, which must has a moduleID
{ //
// make sure that the file exist
//
if (GetFileAttributesW(msmfile) == (DWORD)-1) SET_HRERR_AND_EXIT(ERROR_INVALID_PARAMETER); }
//
// open database for revise
//
IF_NOTSUCCESS_SET_HRERR_EXIT(MsiOpenDatabaseW(msmfile, (LPCWSTR)(MSIDBOPEN_DIRECT), &g_MsmInfo.m_hdb)); }
Exit: return hr; }
HRESULT ImportTableIfNonPresent(MSIHANDLE * pdbHandle, PCWSTR sbMsmTablePath, PCWSTR idt) { CSmallStringBuffer sbTableName; HRESULT hr = S_OK;
IFFAILED_EXIT(sbTableName.Win32Assign(idt, wcslen(idt))); IFFALSE_EXIT(sbTableName.Win32RemoveLastPathElement());
//
// check whether the table exist in the Database
//
MSICONDITION err = MsiDatabaseIsTablePersistent(g_MsmInfo.m_hdb, sbTableName); if (( err == MSICONDITION_ERROR) || (err == MSICONDITION_FALSE)) { SETFAIL_AND_EXIT; } else if (err == MSICONDITION_NONE) // non-exist
{ //import the table
IFFAILED_EXIT(MsiDatabaseImportW(*pdbHandle, sbMsmTablePath, idt)); }
Exit: return hr; } //
// Fucntion:
// - make sure the msm has all tables msmgen needed
//
HRESULT PrepareMsm() {
if (g_MsmInfo.m_enumGenMode == MSMGEN_OPR_NEW) return S_OK; else { HRESULT hr = S_OK; PMSIHANDLE phdb = NULL; CStringBuffer sb; IFFALSE_EXIT(sb.Win32Assign(g_MsmInfo.m_sbMsmTemplateFile)); IF_NOTSUCCESS_SET_HRERR_EXIT(MsiOpenDatabaseW(sb, (LPCWSTR)MSIDBOPEN_READONLY, &phdb)); IF_NOTSUCCESS_SET_HRERR_EXIT(MsiDatabaseMergeW(g_MsmInfo.m_hdb, phdb, NULL)); Exit: return hr; } }
//
// make msi-specified guid string ready : uppercase and replace "-" with "_"
//
HRESULT GetMsiGUIDStrFromGUID(DWORD dwFlags, GUID & guid, CSmallStringBuffer & str) { HRESULT hr = S_OK; LPOLESTR tmpstr = NULL; WCHAR tmpbuf[MAX_PATH];
IFFAILED_EXIT(StringFromCLSID(guid, &tmpstr)); wcscpy(tmpbuf, tmpstr); for (DWORD i=0; i < wcslen(tmpbuf); i++) { if (tmpbuf[i] == L'-') tmpbuf[i] = L'_'; else tmpbuf[i]= towupper(tmpbuf[i]); }
if (dwFlags & MSIGUIDSTR_WITH_PREPEND_DOT) { tmpbuf[0] = L'.'; IFFALSE_EXIT(str.Win32Assign(tmpbuf, wcslen(tmpbuf) - 1 )); // has prepend "."
}else IFFALSE_EXIT(str.Win32Assign(tmpbuf + 1 , wcslen(tmpbuf) - 2 )); // get rid of "{" and "}"
Exit: return hr; }
//
// this function has to be called after the assembly name is known because we need query ComponentTable for MSMGEN_OPR_REGEN
// use the input one, other get it from the componentTables
//
// the input keyPath could be NULL for policy assembly or assembly-without-data files
//
HRESULT SetComponentId(PCWSTR componentIdentifier, PCWSTR keyPath) { HRESULT hr = S_OK; BOOL fExist = FALSE; CStringBuffer str; LPOLESTR tmpstr = NULL; //
// prepare component ID if not input-specified
//
if ((g_MsmInfo.m_enumGenMode == MSMGEN_OPR_ADD) || (g_MsmInfo.m_enumGenMode == MSMGEN_OPR_NEW)) { if (curAsmInfo.m_sbComponentID.IsEmpty()) { goto generate_new_componentID_and_insert; } else { goto insert_into_table; } } else if (g_MsmInfo.m_enumGenMode == MSMGEN_OPR_REGEN) { MSIHANDLE * hRecord = NULL; IFFAILED_EXIT(ExecuteQuerySQL(L"Component", L"Component", componentIdentifier, fExist, NULL));
if (fExist == FALSE) { if (curAsmInfo.m_sbComponentID.IsEmpty()) { // SET_HRERR_AND_EXIT(ERROR_INTERNAL_ERROR);
goto generate_new_componentID_and_insert; } else { goto insert_into_table; } } else { if (! curAsmInfo.m_sbComponentID.IsEmpty() ) { // change the componentID, using the user-input one
IFFAILED_EXIT(ExecuteUpdateSQL(L"Component", L"Component", componentIdentifier, L"ComponentId", curAsmInfo.m_sbComponentID)); }
hr = S_OK; goto Exit; } }
generate_new_componentID_and_insert:
GUID tmpguid; IFFAILED_EXIT(::CoCreateGuid(&tmpguid)); IFFAILED_EXIT(StringFromCLSID(tmpguid, &tmpstr)); IFFALSE_EXIT(curAsmInfo.m_sbComponentID.Win32Assign(tmpstr, wcslen(tmpstr)));
insert_into_table: IFFALSE_EXIT(str.Win32Assign(SYSTEM_FOLDER, NUMBER_OF(SYSTEM_FOLDER)-1)); IFFALSE_EXIT(str.Win32Append(g_MsmInfo.m_sbModuleGuidStr));
IFFAILED_EXIT(ExecuteInsertTableSQL( OPT_COMPONENT, NUMBER_OF_PARAM_TO_INSERT_TABLE_COMPONENT, MAKE_PCWSTR(curAsmInfo.m_sbComponentIdentifier), MAKE_PCWSTR(curAsmInfo.m_sbComponentID), MAKE_PCWSTR(str), MAKE_PCWSTR(keyPath))); Exit: CoTaskMemFree(tmpstr); return hr; }
|