Jump to content


This is a ready-only archive of the InstallSite Forum. You cannot post any new content here. / Dies ist ein Archiv des InstallSite Forums. Hier können keine neuen Beiträge veröffentlicht werden.
Photo

Custom ICE in C++ Reading Database


1 reply to this topic

nga

nga
  • Members
  • 1 posts

Posted 11 January 2006 - 14:34

I am relatively new to MSI and also just started (self) learning C++. I have been writing custom ICE in VBScript succesfully and wanted to see if I could achieve similar in C++.

Attempting to write a custom ICE cub file that will validate an msi (+msts) (I am validating via Orca). I have managed to open an msi external to the cub and read tables and can read the properties from th cub database within the ICE CA, also sending messages out for errors warnings and info. Code is put together from what I have managed to find in terms of decent examples.

I thought that when orca validated it merged the databases together, so hoped the database object would return something I can read.

My latest attempt is to read the tmp files that are being created during the validation hoping they are the merged msi so I can validate against that.

Any hints on where I am going wrong would be appreciated. Here's some of the code from the DLL (it a bit messy as I have been going roud in circles trying various things...


; MyCustomAction.def
;
; defines the exported functions which will be available to the MSI engine

LIBRARY "MyCustomAction"
DESCRIPTION 'Custom Action DLL created for CodeProject.com'

EXPORTS
SampleFunction
SampleFunction2
SampleFunction3
ReadDatabase
ReadDatabaseMe

#include "stdafx.h"
#include "MSI_Logging.h"

#include "msiQuery.h"

include <windows.h>
#include <stdio.h>
#include <tchar.h>

BOOL APIENTRY DllMain( HANDLE hInstall,
DWORD ul_reason_for_call,
LPVOID lpReserved )

{
return TRUE;
}


UINT __stdcall ReadDatabaseMe ( MSIHANDLE hInstall )
{

char szIceName[255];
sprintf(szIceName, "ICEC++01");

PumpMessage( hInstall, szIceName, UI_MSI_MESSAGE_TYPE_ERROR, "Description", "HelpURL", "TableName", "ColumnName", "PrimaryKeys");

// This function opens up the current MSI database and reads in the column values from a table

TCHAR szFilePath[MAX_PATH] = {'0'};
char *sFilePath;
DWORD dwLen = MAX_PATH;
MsiGetProperty(hInstall, "OriginalDatabase", szFilePath, &dwLen); // get the file path and name of this database

TCHAR szProductCode[MAX_PATH] = {'0'};
MsiGetProperty(hInstall, "ProductCode", szProductCode, &dwLen); // get the product code
PumpMessage(hInstall, szIceName, UI_MSI_MESSAGE_TYPE_INFORMATION, szProductCode, "", "", "", "");

MSIHANDLE hDb;
hDb = MsiGetActiveDatabase(hInstall);
if (hDb == 0)
{
PumpMessage(hInstall, szIceName, UI_MSI_MESSAGE_TYPE_INFORMATION, "Not got Acvtive Database", "", "", "", "");
}else{
PumpMessage(hInstall, szIceName, UI_MSI_MESSAGE_TYPE_INFORMATION, "Got Active Database", "", "", "", "");
MsiGetProperty(hDb, "ProductName", szProductCode, &dwLen);
PumpMessage(hInstall, szIceName, UI_MSI_MESSAGE_TYPE_INFORMATION, szProductCode, "", "", "", "");
}

/*
MSIHANDLE hPackage;
if (::MsiOpenPackage("#0001", &hPackage) != ERROR_SUCCESS)
{
PumpMessage(hInstall, szIceName, UI_MSI_MESSAGE_TYPE_INFORMATION, "Cannot open package.", "", "", "", "");
}else{
PumpMessage(hInstall, szIceName, UI_MSI_MESSAGE_TYPE_INFORMATION, "Opened package.", "", "", "", "");
}

*/

TCHAR szFilePathParsed[520] = {'0'};


//C:\Documents and Settings\Administrator\Local Settings\Temp


int iCheck; // used to check each character in source string
int y = 0; // used to build final string
int z; // used to find end point
int j; // used to find last backslash
for(int x=0; x<MAX_PATH; x++)
{
iCheck = szFilePath[x]; // find the internal number stored at memory location for char

if(iCheck == 0)
{
z = x;
x = MAX_PATH;
goto endloop;
}

//if(szFilePath[x] == 92)
if(iCheck == 92) // check for backslash then replace with double backslash
{
j = x;
szFilePathParsed[y] = 92;
y++;
szFilePathParsed[y] = 92;
}else{
szFilePathParsed[y] = szFilePath[x];
}
y++;
endloop:;
}
szFilePathParsed[y] = 0;

PumpMessage(hInstall, szIceName, UI_MSI_MESSAGE_TYPE_INFORMATION, szFilePathParsed, "", "", "", "");


TCHAR szFileNameParsed[520] = {'0'};
int p = 0;
for(int x=j+1; x<z+1; x++)
{
szFileNameParsed[p] = szFilePath[x];
p++;
}
PumpMessage(hInstall, szIceName, UI_MSI_MESSAGE_TYPE_INFORMATION, szFileNameParsed, "", "", "", "");

////sFilePath = "C:\\Documents and Settings\\Administrator\\Desktop\\C++\\example.msi";

TCHAR sProductCode[MAX_PATH] = {'0'};
MsiGetProperty(hInstall, "ProductCode", sProductCode, &dwLen);

MSIHANDLE hDatabase, hView, hRecord, hProduct; //define handles to database, view and record

////if(::MsiOpenProduct(sProductCode, &hProduct) != ERROR_SUCCESS)
////{
//// PumpMessage( hInstall, szIceName, UI_MSI_MESSAGE_TYPE_INFORMATION, "Cannot Open Product.", "", "", "", "");
////return FALSE;
////}
////PumpMessage( hInstall, szIceName, UI_MSI_MESSAGE_TYPE_INFORMATION, "Opened Product.", "", "", "", "");

char szFilePathFinal[560];
sprintf(szFilePathFinal, "C:\\\\Documents and Settings\\\\Administrator\\\\Local Settings\\\\Temp\\\\%s", szFileNameParsed);
PumpMessage(hInstall, szIceName, UI_MSI_MESSAGE_TYPE_INFORMATION, szFilePathFinal, "", "", "", "");
/*
if (::MsiOpenDatabase(szFilePathFinal, MSIDBOPEN_READONLY, &hDatabase) != ERROR_SUCCESS) // now open this database to read the tables
{
PumpMessage( hInstall, szIceName, UI_MSI_MESSAGE_TYPE_INFORMATION, "Cannot Open database.", "", "", "", "");
return FALSE;
}
*/
//LogString(hInstall, "Opened database.");
PumpMessage( hInstall, szIceName, UI_MSI_MESSAGE_TYPE_INFORMATION, "Opened database.", "", "", "", "");

char szSelect[256];
char *sTableName;
sTableName = "CustomAction"; //define table to read
wsprintf(szSelect, "SELECT * FROM %s", sTableName); //define query
//if (MsiDatabaseOpenView(hDatabase, szSelect, &hView) != ERROR_SUCCESS)
if (MsiDatabaseOpenView(hInstall, szSelect, &hView) != ERROR_SUCCESS)
{
PumpMessage( hInstall, szIceName, UI_MSI_MESSAGE_TYPE_INFORMATION, "Cannot open view.", "", "", "", "");
return FALSE;
}

PumpMessage( hInstall, szIceName, UI_MSI_MESSAGE_TYPE_INFORMATION, "Opened view.", "", "", "", "");

if (MsiViewExecute(hView, NULL) != ERROR_SUCCESS)
{
PumpMessage(hInstall, szIceName, UI_MSI_MESSAGE_TYPE_INFORMATION, "Cannot execute view.", "", "", "", "");
return FALSE;
}
PumpMessage(hInstall, szIceName, UI_MSI_MESSAGE_TYPE_INFORMATION, "Executed view.", "", "", "", "");


>>>>>>>>>>>.etc.

}




Glytzhkof

Glytzhkof
  • Moderators
  • 1,447 posts

Posted 24 November 2008 - 21:28

Hi, did you ever get this working? And what samples did you find out there? There seems to be little information available on this topic.
Regards
-Stein Åsmul