⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 crtsis.cpp

📁 Symbian操作系统手机上可执行程序的安装打包程序的源码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
// CRTSIS.CPP// Copyright (c) 1997-1999 Symbian Ltd. All rights reserved.//// Handles creation of a SIS file//// ===========================================================================// INCLUDES// ===========================================================================#include "utils.h"#include <windows.h>#include <assert.h>#include <tchar.h>#include <wchar.h>#include <time.h>#include <stdio.h>#include "crtsis.h"#include "parsepkg.h"//#ifndef DIGITAL_SIGNATURES//#define DIGITAL_SIGNATURES//#endif#ifdef DIGITAL_SIGNATURES#undef DIGITAL_SIGNATURES#endif#ifdef DIGITAL_SIGNATURES// implies you ''have'' to use wincrypt.lib #include <WinHash.h>#include <WinKey.h>#include <WinSHA1.h>#include <WinDSA.h>#include <WinEncrypt.h>#include <winparsepkcs7.h>#include <winB64Decrypt.h>#endif// ===========================================================================// CONSTANTS// ===========================================================================#define HASHLEN 256#define CIPHERTEXTLEN 2048#define Y2K_FIX 1900// CRC calulation lookup tableconst WORD crcTab[256] =	{0x0000,0x1021,0x2042,0x3063,0x4084,0x50a5,0x60c6,0x70e7,0x8108,0x9129,0xa14a,	0xb16b,0xc18c,0xd1ad,0xe1ce,0xf1ef,0x1231,0x0210,0x3273,0x2252,0x52b5,0x4294,	0x72f7,0x62d6,0x9339,0x8318,0xb37b,0xa35a,0xd3bd,0xc39c,0xf3ff,0xe3de,0x2462,	0x3443,0x0420,0x1401,0x64e6,0x74c7,0x44a4,0x5485,0xa56a,0xb54b,0x8528,0x9509,	0xe5ee,0xf5cf,0xc5ac,0xd58d,0x3653,0x2672,0x1611,0x0630,0x76d7,0x66f6,0x5695,	0x46b4,0xb75b,0xa77a,0x9719,0x8738,0xf7df,0xe7fe,0xd79d,0xc7bc,0x48c4,0x58e5,	0x6886,0x78a7,0x0840,0x1861,0x2802,0x3823,0xc9cc,0xd9ed,0xe98e,0xf9af,0x8948,	0x9969,0xa90a,0xb92b,0x5af5,0x4ad4,0x7ab7,0x6a96,0x1a71,0x0a50,0x3a33,0x2a12,	0xdbfd,0xcbdc,0xfbbf,0xeb9e,0x9b79,0x8b58,0xbb3b,0xab1a,0x6ca6,0x7c87,0x4ce4,	0x5cc5,0x2c22,0x3c03,0x0c60,0x1c41,0xedae,0xfd8f,0xcdec,0xddcd,0xad2a,0xbd0b,	0x8d68,0x9d49,0x7e97,0x6eb6,0x5ed5,0x4ef4,0x3e13,0x2e32,0x1e51,0x0e70,0xff9f,	0xefbe,0xdfdd,0xcffc,0xbf1b,0xaf3a,0x9f59,0x8f78,0x9188,0x81a9,0xb1ca,0xa1eb,	0xd10c,0xc12d,0xf14e,0xe16f,0x1080,0x00a1,0x30c2,0x20e3,0x5004,0x4025,0x7046,	0x6067,0x83b9,0x9398,0xa3fb,0xb3da,0xc33d,0xd31c,0xe37f,0xf35e,0x02b1,0x1290,	0x22f3,0x32d2,0x4235,0x5214,0x6277,0x7256,0xb5ea,0xa5cb,0x95a8,0x8589,0xf56e,	0xe54f,0xd52c,0xc50d,0x34e2,0x24c3,0x14a0,0x0481,0x7466,0x6447,0x5424,0x4405,	0xa7db,0xb7fa,0x8799,0x97b8,0xe75f,0xf77e,0xc71d,0xd73c,0x26d3,0x36f2,0x0691,	0x16b0,0x6657,0x7676,0x4615,0x5634,0xd94c,0xc96d,0xf90e,0xe92f,0x99c8,0x89e9,	0xb98a,0xa9ab,0x5844,0x4865,0x7806,0x6827,0x18c0,0x08e1,0x3882,0x28a3,0xcb7d,	0xdb5c,0xeb3f,0xfb1e,0x8bf9,0x9bd8,0xabbb,0xbb9a,0x4a75,0x5a54,0x6a37,0x7a16,	0x0af1,0x1ad0,0x2ab3,0x3a92,0xfd2e,0xed0f,0xdd6c,0xcd4d,0xbdaa,0xad8b,0x9de8,	0x8dc9,0x7c26,0x6c07,0x5c64,0x4c45,0x3ca2,0x2c83,0x1ce0,0x0cc1,0xef1f,0xff3e,	0xcf5d,0xdf7c,0xaf9b,0xbfba,0x8fd9,0x9ff8,0x6e17,0x7e36,0x4e55,0x5e74,0x2e93,	0x3eb2,0x0ed1,0x1ef0	};// ===========================================================================// CSISWriter// Holds SIS file info, as generated by the parser and builds the output SIS file.// All strings are held internally by this class as UNICODE (wide) strings.// ===========================================================================CSISWriter::CSISWriter():m_dwUID(0x00000000),m_wMajor(0),m_wMinor(0),m_dwBuild(0),m_wType(EInstSISApp),m_wFlags(0),m_wNumLangs(0),m_pLangStringBase(NULL),m_pLangBase(NULL),m_pPkgLineBase(NULL),m_pDependBase(NULL),m_pSignatureBase(NULL),m_pCapabilityBase(NULL),m_bCmdPassword(FALSE),m_pObserver(NULL)	{ ; }void CSISWriter::Release()// Dispose of components resources	{	// remove any temporary files	CleanupTemp();		// free up allocated structures	LANGSTRINGNODE *pLangStringNode = m_pLangStringBase;	while(m_pLangStringBase)		{		pLangStringNode = pLangStringNode->pNext;		delete m_pLangStringBase;		m_pLangStringBase = pLangStringNode;		}		LANGNODE *pLangNode = m_pLangBase;	while(m_pLangBase)		{		pLangNode = pLangNode->pNext;		delete m_pLangBase;		m_pLangBase = pLangNode;		}		PKGLINENODE *pPkgLineNode = m_pPkgLineBase;	while(m_pPkgLineBase)		{		pPkgLineNode = m_pPkgLineBase->pNext;		switch (m_pPkgLineBase->iPackageLineType)			{			case EInstPkgLineFile:			case EInstPkgLineLanguageFile:				delete m_pPkgLineBase->file;				break;			case EInstPkgLineOption:				LANGSTRINGNODE *pLangStringNode2;				pLangStringNode = m_pPkgLineBase->option->pLangStringBase;				while(pLangStringNode)					{					pLangStringNode2 = pLangStringNode->pNext;					delete pLangStringNode;					pLangStringNode = pLangStringNode2;					}				delete m_pPkgLineBase->option;				break;			case EInstPkgLineCondIf:			case EInstPkgLineCondElseIf:				ReleaseCondExpr(m_pPkgLineBase->cond);				break;			case EInstPkgLineCondElse:			case EInstPkgLineCondEndIf:				break;			}		delete m_pPkgLineBase;		m_pPkgLineBase = pPkgLineNode;		}		DEPENDNODE *pDependNode = m_pDependBase;	while(m_pDependBase)		{		pDependNode = pDependNode->pNext;				pLangStringNode = m_pDependBase->pLangStringBase;		while(m_pLangStringBase)			{			pLangStringNode = pLangStringNode->pNext;			delete m_pLangStringBase;			m_pLangStringBase = pLangStringNode;			}		delete m_pDependBase;		m_pDependBase = pDependNode;		}		if (m_pSignatureBase) delete m_pSignatureBase;		CAPABILITYNODE *pCapabilityNode = m_pCapabilityBase;	while(m_pCapabilityBase)		{		pCapabilityNode = pCapabilityNode->pNext;		delete m_pCapabilityBase;		m_pCapabilityBase = pCapabilityNode;		}		}void CSISWriter::ReleaseCondExpr(PKGLINECONDITION* expr)// recursively called to free up condition expression	{	if (expr)		{		switch (expr->exprType)			{			case EInstCondBinOpEq:			case EInstCondBinOpNe:			case EInstCondBinOpGt:			case EInstCondBinOpLt:			case EInstCondBinOpGe:			case EInstCondBinOpLe:			case EInstCondLogOpAnd:			case EInstCondLogOpOr:				ReleaseCondExpr(expr->b.pLhs);				ReleaseCondExpr(expr->b.pRhs);				break;			case EInstCondUnaryOpNot:				ReleaseCondExpr(expr->pExpr);				break;			case EInstCondFuncAppCap:				ReleaseCondExpr(expr->pArg[0]);				ReleaseCondExpr(expr->pArg[1]);				break;			case EInstCondFuncExists:			case EInstCondFuncDevCap:				ReleaseCondExpr(expr->pArg[0]);				break;			case EInstCondPrimTypeString:			case EInstCondPrimTypeVariable:			case EInstCondPrimTypeNumber:				delete expr->pPrim;				break;			default:				break;			}		delete expr;		}	}void CSISWriter::SetCmdPassword(LPCWSTR pszCmdPassword)	{	wcscpy(m_pszCmdPassword, pszCmdPassword);	m_bCmdPassword = TRUE;	}BOOL CSISWriter::GetCmdPassword(LPWSTR pszCmdPassword) const	{	wcscpy(pszCmdPassword, m_pszCmdPassword);		return m_bCmdPassword;	}void CSISWriter::WriteSIS(LPCWSTR pszTargetFile, BOOL fIsStub /*=FALSE*/)// Construct the output SIS file// Inputs   : hFile	   The file handle to write to//			  fIsStub  IS this a stub SIS file (stub SIS files have no CODE block)	{	if(m_wFlags & EInstIsUnicode)		{		CSISFileGeneratorT<unsigned short> gen(this);		gen.GenerateSISFile(pszTargetFile, fIsStub);		}	else		{		CSISFileGeneratorT<char> gen(this);		gen.GenerateSISFile(pszTargetFile, fIsStub);		}	}void CSISWriter::AddLanguageNode(LANGNODE *pLNode)// Adds a language node// Inputs   : pLNode   The node to add	{	pLNode->pNext = m_pLangBase;	m_pLangBase = pLNode;	m_wNumLangs++;	}void CSISWriter::AddLangStringNode(LANGSTRINGNODE *pLSNode)// Adds a language string node// Inputs   : pLSNode   The node to add	{	pLSNode->pNext = m_pLangStringBase;	m_pLangStringBase = pLSNode;	}void CSISWriter::AddPkgLineNode(PKGLINENODE *pNode)// Adds a PKG line node// Inputs   : pNode   The node to add	{	pNode->pNext = m_pPkgLineBase;	m_pPkgLineBase = pNode;	}void CSISWriter::AddDependencyNode(DEPENDNODE *pNode)// Does exactly what it says on the tin!// Inputs   : pNode   The node to add	{	pNode->pNext = m_pDependBase;	m_pDependBase = pNode;	}void CSISWriter::AddSignatureNode(SIGNATURENODE *pSig)// Sets the digital signature// Inputs   : pSig   The node to add	{	m_pSignatureBase = pSig;	}void CSISWriter::AddCapabilityNode(CAPABILITYNODE *pNode)// Does exactly what it says on the tin!// Inputs   : pNode   The node to add	{	pNode->pNext = m_pCapabilityBase;	m_pCapabilityBase = pNode;	}BOOL CSISWriter::AreLangStringInit()// Is there a language string node defined? (i.e. has the pkg language header line been parsed?)	{	return (m_pLangStringBase!=NULL);	}void CSISWriter::SetVersionInfo(DWORD dwUID, WORD wMajor, WORD wMinor, DWORD dwBuild, TSISType wType, WORD wFlags)// Inputs   : dwUID							Installee app's uid//			  dwMajor, dwMinor, dwBuild		The version numbers//		      wType							SIS file type//		      wFlags						Installation flags	{	m_dwUID		= dwUID;    	m_wMajor	= wMajor;  	m_wMinor	= wMinor;  	m_dwBuild	= dwBuild;	m_wType		= wType;	m_wFlags	= wFlags;  	}void CSISWriter::QueryVersionInfo (WORD *wMajor, WORD *wMinor, DWORD *dwBuild) const// Inputs   : dwMajor, dwMinor, dwBuild	The destinations for the version numbers	{	*wMajor   = m_wMajor;	*wMinor   = m_wMinor;	*dwBuild   = m_dwBuild;	}void CSISWriter::SetLangDependFileDestinations(LPCWSTR pszDest, LPCWSTR pszMimeType, DWORD dwType, DWORD dwOptions)// Purpose  : Patches the last 'numlang' files with a target path and flags (including the//			  OPTFILE_LANGUAGEDEPENDENT flag)// Inputs   : pszDest	The target path//          : pszMimeType The mime type (if relevant)//			  dwOptions Any specified flags	{	PKGLINENODE *pNode = m_pPkgLineBase;	WORD wNumLangs = 0;		while(pNode && (wNumLangs++ < m_wNumLangs))		{		wcscpy(pNode->file->pszDest, pszDest);		pNode->iPackageLineType = EInstPkgLineLanguageFile;		pNode->file->type = (TInstFileType)dwType;		switch (pNode->file->type)			{			case EInstFileTypeText:				pNode->file->options.iTextOption=(TInstFileTextOption)dwOptions;				break;			case EInstFileTypeRun:				pNode->file->options.iRunOption=(TInstFileRunOption)dwOptions;				break;			case EInstFileTypeMime:				pNode->file->options.iMimeOption=(TInstFileMimeOption)dwOptions;				wcscpy(pNode->file->pszMimeType, pszMimeType);				break;			default:				break;			}		pNode = pNode->pNext;		}	}void CSISWriter::SetLangDependCompDestinations(DWORD dwUID)// Purpose  : Sets the component id of the last 'numlang' file nodes, and sets their flags to//			  OPTFILE_LANGUAGEDEPENDENT | OPTFILE_COMPONENT;// Inputs   : dwUID  The components UID	{	PKGLINENODE *pNode = m_pPkgLineBase;	WORD wNumLangs = 0;		while(pNode && (wNumLangs++ < m_wNumLangs))		{		pNode->iPackageLineType = EInstPkgLineLanguageFile;		pNode->file->type = EInstFileTypeComponent;		pNode->file->options.iComponentUid = dwUID;		pNode = pNode->pNext;		}	}// ===========================================================================// CSISFileGeneratorBase// Handles most of the SIS file generation operation. Defers the charater// width specific stuff to a derived template class...// ===========================================================================CSISFileGeneratorBase::CSISFileGeneratorBase(const CSISWriter *pSISWriter):m_pSISWriter(pSISWriter)	{ ; }CSISFileGeneratorBase::~CSISFileGeneratorBase()	{ ; }void CSISFileGeneratorBase::GenerateSISFile(LPCWSTR pszTargetFile, BOOL fIsStub /* = FALSE */)// Purpose  : Construct// Inputs   : hFile	   The file handle to write to//			  fIsStub  IS this a stub SIS file (stub SIS files have no CODE block)// Returns  : Success or failure (actually TRUE or throws an EGeneratorException	{	m_hFile = ::MakeSISOpenFile(pszTargetFile, GENERIC_WRITE, CREATE_ALWAYS);	if(m_hFile == INVALID_HANDLE_VALUE) throw ErrCannotWriteFile;	m_stubFile=fIsStub;	// convert any text files to unicode if necessary	if (SizeOfChar()!=1 && !m_stubFile) CheckUnicodeTextFiles();		// Estimate the maximum amount of space an installation could require		EstimateInstallationSizeL();		// Compress files into temp directory	CompressFiles();		//Re-Write Certificate files	ParseCertificates();		// Calculate the offsets	CalculateOffsets();		m_wCheck = 0;	// reset checksum		WriteHeaderL();	WriteLanguageL();	WritePkgLinesL();	WriteDependL();	WriteCertificatesL();	WriteCapabilitiesL();	WriteStringsL();	if(!m_stubFile) WriteCodeL();	WriteCrcL();	::CloseHandle(m_hFile);	WriteSignatureL(pszTargetFile);	}void CSISFileGeneratorBase::CheckUnicodeTextFiles()// Converts any text files to UNICODE	{	Verbage(_T("Converting text files to unicode"));		PKGLINENODE *pNode = (PKGLINENODE *)m_pSISWriter->GetPkgLineBase();	BOOL converted=FALSE;		while(pNode)		{		if (pNode->iPackageLineType==EInstPkgLineFile || pNode->iPackageLineType==EInstPkgLineLanguageFile)			{			WORD wMaxLangs=1;			if (pNode->iPackageLineType==EInstPkgLineLanguageFile) wMaxLangs = m_pSISWriter->GetNoLanguages();			WORD wNumLang = 0;						while(pNode && (wNumLang < wMaxLangs))				{				if(pNode->file->type==EInstFileTypeText)					{	// have a text file					BOOL littleEndian;					try						{						if (!FileIsUnicode(pNode->file->pszSource,littleEndian))							{							LPWSTR pszTempSource=ConvertFileToUnicode(pNode->file->pszSource);							wcscpy(pNode->file->pszSource, pszTempSource);							converted=TRUE;							}						else if (!littleEndian)							{							LPWSTR pszTempSource=ConvertFileToLittleEndianUnicode(pNode->file->pszSource);							wcscpy(pNode->file->pszSource, pszTempSource);							converted=TRUE;							}						}					catch (TUtilsException excp)						{#ifdef _UNICODE						  m_pSISWriter->GetObserver()->DoErrMsg((const _TCHAR*)pNode->file->pszSource); // @todo#else						DWORD length=wcslen(pNode->file->pszSource);						LPSTR fName=MakeMBCSString(pNode->file->pszSource, CP_ACP, length);						m_pSISWriter->GetObserver()->DoErrMsg((const _TCHAR*)fName);						delete [] fName;#endif						throw excp;						}					HANDLE hInFile = ::MakeSISOpenFile(pNode->file->pszSource, GENERIC_READ, OPEN_EXISTING);					if(hInFile == INVALID_HANDLE_VALUE)						throw ErrCannotOpenFile;									if (converted) pNode->file->dwSize=::GetFileSize(hInFile, NULL);					::CloseHandle(hInFile);					}				pNode = pNode->pNext;				wNumLang++;							}			}		else			pNode = pNode->pNext;		}	}void CSISFileGeneratorBase::CalculateOffsets()// Calculates the offsets of the various component blocks from the head of the file	{	assert(m_pSISWriter);	// Calculate the language offset (The size of the HEADER block) -------------------------------	m_dwOffLang = sizeof(TInstInstallation);		// Calculate the PKG lines offset (The size of the LANGUAGE	block) --------------------------------	m_dwOffPkgLines = m_dwOffLang + (sizeof(TInstLang) * m_pSISWriter->GetNoLanguages());		// Calculate the dependency offset (The size of the PKG lines block) ------------------------------	m_dwOffDepend = m_dwOffPkgLines;	DWORD stringSizes=0;	const PKGLINENODE *pNode = m_pSISWriter->GetPkgLineBase(); 	while(pNode)		{		m_dwOffDepend += sizeof(TInstPackageLineType);		switch (pNode->iPackageLineType)			{			case EInstPkgLineFile:			case EInstPkgLineLanguageFile:				{				WORD wNumLangs = 1;				if (pNode->iPackageLineType==EInstPkgLineLanguageFile)					wNumLangs = m_pSISWriter->GetNoLanguages();								m_dwOffDepend += sizeof(TInstFile) +					((sizeof(unsigned long) + sizeof(FOFF) + sizeof(unsigned long)) * wNumLangs) +					sizeof(TInstString);				stringSizes += (wcslen(pNode->file->pszSource) + wcslen(pNode->file->pszDest)) * SizeOfChar() +					wcslen(pNode->file->pszMimeType);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -