You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
285 lines
8.2 KiB
285 lines
8.2 KiB
/*++
|
|
|
|
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;
|
|
}
|