📄 crtsis.cpp
字号:
case EInstCondBinOpGt: case EInstCondBinOpLt: case EInstCondBinOpGe: case EInstCondBinOpLe: case EInstCondLogOpAnd: case EInstCondLogOpOr: WriteCondExprL(expr->b.pLhs); WriteCondExprL(expr->b.pRhs); break; case EInstCondUnaryOpNot: WriteCondExprL(expr->pExpr); break; case EInstCondFuncAppCap: WriteCondExprL(expr->pArg[0]); WriteCondExprL(expr->pArg[1]); break; case EInstCondFuncDevCap: case EInstCondFuncExists: WriteCondExprL(expr->pArg[0]); break; case EInstCondPrimTypeString: { prim.iString.iCount = wcslen(expr->pPrim->pszString) * SizeOfChar(); prim.iString.iStringPtr = m_dwCurrString; m_dwCurrString += prim.iString.iCount; if(!WriteFile(m_hFile, (LPVOID)&prim, sizeof(TInstCondPrim), &dwNumBytes, NULL)) throw ErrFailedToWriteConditionBlock; // CRC Crc((void *)&prim, sizeof(TInstCondPrim)); } break; case EInstCondPrimTypeVariable: case EInstCondPrimTypeNumber: { prim.iNumber=expr->pPrim->dwNumber; if(!WriteFile(m_hFile, (LPVOID)&prim, sizeof(TInstCondPrim), &dwNumBytes, NULL)) throw ErrFailedToWriteConditionBlock; // CRC Crc((void *)&prim, sizeof(TInstCondPrim)); } break; default: break; } } }void CSISFileGeneratorBase::WriteDependL()// To write the SIS file's DEPENDENCY block { Verbage( _T("Writing dependencies")); const DEPENDNODE *pDNode = m_pSISWriter->GetDependencyBase(); while(pDNode) { TInstDependency idDepend; idDepend.iUid = pDNode->dwUID; idDepend.iVersion.iMajor = pDNode->wMajor; idDepend.iVersion.iMinor = pDNode->wMinor; idDepend.iVersion.iBuild = pDNode->dwBuild; DWORD dwNumBytes; if(!WriteFile(m_hFile, (LPVOID)&idDepend, sizeof(TInstDependency), &dwNumBytes, NULL)) throw ErrFailedToWriteDependencyBlock; // CRC Crc((void *)&idDepend, sizeof(idDepend)); // Now write out the names LANGSTRINGNODE *pLSNode = pDNode->pLangStringBase; while(pLSNode) { DWORD dwLength = wcslen(pLSNode->pszString) * SizeOfChar(); DWORD dwNumBytes; if(!::WriteFile(m_hFile, (LPVOID)&dwLength, sizeof(DWORD), &dwNumBytes, NULL)) throw ErrFailedToWriteDependencyBlock; // CRC Crc((void *)&dwLength, sizeof(DWORD)); pLSNode = pLSNode->pNext; } pLSNode = pDNode->pLangStringBase; while(pLSNode) { DWORD dwNumBytes; if(!::WriteFile(m_hFile, (LPVOID)&m_dwCurrString, sizeof(DWORD), &dwNumBytes, NULL)) throw ErrFailedToWriteDependencyBlock; // CRC Crc((void *)&m_dwCurrString, sizeof(DWORD)); m_dwCurrString += wcslen(pLSNode->pszString) * SizeOfChar(); pLSNode = pLSNode->pNext; } pDNode = pDNode->pNext; } }void CSISFileGeneratorBase::WriteCertificatesL()// To write the SIS file's CERTIFICATES block {#ifdef DIGITAL_SIGNATURES //get digital sig info (public key/private key and password) const SIGNATURENODE* pSignature = m_pSISWriter->GetSignatureBase(); if (pSignature) { HANDLE hInFile; DWORD dwFileSize; DWORD dwNumBytes; BYTE *pBuf; //pck7 file was re-written to a chain file, so read it instead if (m_bWriteChain) { //open certificate chain hInFile = ::MakeSISOpenFile(pSignature->pszChainFile, GENERIC_READ, OPEN_EXISTING); if(hInFile == INVALID_HANDLE_VALUE) throw ErrCannotOpenFile; } //no conversions in pPKCS7 object so write certificate verbatim else { //open public key file (pre-converted from Base64) hInFile = ::MakeSISOpenFile(pSignature->pszB64File, GENERIC_READ, OPEN_EXISTING); if(hInFile == INVALID_HANDLE_VALUE) throw ErrCannotOpenFile; } dwFileSize = ::GetFileSize(hInFile, NULL); if (dwFileSize==0xFFFFFFFF) throw ErrCannotOpenFile; TInstCertBlock CertBlock; //get system time struct tm *newtime; long ltime; time( <ime ); /* Obtain GMT */ newtime = gmtime( <ime ); //copy RTC to our internal structure CertBlock.iTimeStamp.iSecond = (TInt16) newtime->tm_sec; CertBlock.iTimeStamp.iMinute = (TInt16) newtime->tm_min; CertBlock.iTimeStamp.iHour = (TInt16) newtime->tm_hour; //date is stored with year 1900 as baseline if (newtime->tm_year >= 100) { newtime->tm_year += Y2K_FIX; } CertBlock.iTimeStamp.iYear = (TInt16) newtime->tm_year; CertBlock.iTimeStamp.iMonth = (TInt16) newtime->tm_mon; CertBlock.iTimeStamp.iDay = (TInt16) newtime->tm_mday; CertBlock.iNumCerts = pSignature->iNumCerts; pBuf = new BYTE[dwFileSize + sizeof (TInstCertBlock)]; if (!pBuf) throw ErrNotEnoughMemory; memcpy(pBuf, (LPVOID)&CertBlock, sizeof (TInstCertBlock)); BYTE* pBuf2 = &pBuf[sizeof (TInstCertBlock)]; if(!::ReadFile(hInFile, (LPVOID)pBuf2, dwFileSize, &dwNumBytes, NULL)) throw ErrCannotReadFile; if(!::WriteFile(m_hFile, (LPVOID)pBuf, dwFileSize + sizeof (TInstCertBlock), &dwNumBytes, NULL)) throw ErrFailedToWriteCertificatesBlock; // CRC Crc((void *)pBuf, dwNumBytes); delete [] pBuf; ::CloseHandle(hInFile); }#endif }void CSISFileGeneratorBase::WriteCapabilitiesL()// To write the SIS file's CAPABILITIES block { Verbage( _T("Writing capabilities")); const CAPABILITYNODE *pCNode = m_pSISWriter->GetCapabilityBase(); while(pCNode) { TInstCapability idCapability; idCapability.iKey = pCNode->iKey; idCapability.iValue = pCNode->iValue; DWORD dwNumBytes; if(!WriteFile(m_hFile, (LPVOID)&idCapability, sizeof(TInstCapability), &dwNumBytes, NULL)) throw ErrFailedToWriteCapabilitiesBlock; // CRC Crc((void *)&idCapability, sizeof(TInstCapability)); pCNode = pCNode->pNext; } }void CSISFileGeneratorBase::WriteStringsL()// To write the SIS file's STRINGS block { Verbage(_T("Writing strings")); // Write the installation name string descriptors -------------------------------------------- const LANGSTRINGNODE *pLSNode = m_pSISWriter->GetLangStringBase(); DWORD dwCount = m_pSISWriter->GetNoLanguages(); DWORD* pdwLength = new DWORD [dwCount]; DWORD* pdwPos = new DWORD [dwCount]; DWORD i = 0; if (!pdwLength || !pdwPos) throw ErrNotEnoughMemory; while(pLSNode) { pdwLength[i] = wcslen(pLSNode->pszString) * SizeOfChar(); pdwPos[i] = m_dwCurrString; pLSNode = pLSNode->pNext; m_dwCurrString += pdwLength[i++]; assert(i <= dwCount); } DWORD dwNumBytes; if(!::WriteFile(m_hFile, (LPVOID)pdwLength, dwCount * sizeof(DWORD), &dwNumBytes, NULL)) throw ErrFailedToWriteStringsBlock; Crc((void *)pdwLength, sizeof(DWORD) * dwCount); if(!::WriteFile(m_hFile, (LPVOID)pdwPos, dwCount * sizeof(DWORD), &dwNumBytes, NULL)) throw ErrFailedToWriteStringsBlock; Crc((void *)pdwPos, sizeof(DWORD) * dwCount); // Put PKG lines strings ---------------------------------------------------------------- const PKGLINENODE *pNode = m_pSISWriter->GetPkgLineBase(); while(pNode) { switch (pNode->iPackageLineType) { case EInstPkgLineFile: case EInstPkgLineLanguageFile: { WriteString(pNode->file->pszSource, m_hFile); WriteString(pNode->file->pszDest, m_hFile); // Check for multiple language forms... WORD wMaxLangs = 0; if (pNode->iPackageLineType==EInstPkgLineLanguageFile) wMaxLangs = m_pSISWriter->GetNoLanguages(); WORD wNumLang = 0; while (pNode && (wNumLang < wMaxLangs-1)) { pNode = pNode->pNext; wNumLang++; } } // write mime type WriteString8(pNode->file->pszMimeType, m_hFile); break; case EInstPkgLineOption: { pLSNode = pNode->option->pLangStringBase; while(pLSNode) { WriteString(pLSNode->pszString, m_hFile); pLSNode=pLSNode->pNext; } } break; case EInstPkgLineCondIf: case EInstPkgLineCondElseIf: WriteCondExprStrL(pNode->cond); break; case EInstPkgLineCondElse: case EInstPkgLineCondEndIf: break; } pNode = pNode->pNext; } // Write the dependency names ----------------------------------------------------------------- const DEPENDNODE *pDNode = m_pSISWriter->GetDependencyBase(); while(pDNode) { // Now write out the names pLSNode = pDNode->pLangStringBase; while(pLSNode) { WriteString(pLSNode->pszString, m_hFile); pLSNode = pLSNode->pNext; } pDNode = pDNode->pNext; } // Now write out the installation names ------------------------------------------------------- pLSNode = m_pSISWriter->GetLangStringBase(); while(pLSNode) { WriteString(pLSNode->pszString, m_hFile); pLSNode = pLSNode->pNext; } } void CSISFileGeneratorBase::WriteCondExprStrL(const PKGLINECONDITION* expr){ if (expr) { switch (expr->exprType) { case EInstCondBinOpEq: case EInstCondBinOpNe: case EInstCondBinOpGt: case EInstCondBinOpLt: case EInstCondBinOpGe: case EInstCondBinOpLe: case EInstCondLogOpAnd: case EInstCondLogOpOr: WriteCondExprStrL(expr->b.pLhs); WriteCondExprStrL(expr->b.pRhs); break; case EInstCondUnaryOpNot: WriteCondExprStrL(expr->pExpr); break; case EInstCondFuncAppCap: WriteCondExprStrL(expr->pArg[0]); WriteCondExprStrL(expr->pArg[1]); break; case EInstCondFuncDevCap: case EInstCondFuncExists: WriteCondExprStrL(expr->pArg[0]); break; case EInstCondPrimTypeString: WriteString(expr->pPrim->pszString, m_hFile); break; case EInstCondPrimTypeVariable: case EInstCondPrimTypeNumber: break; default: break; } }} // To write the SIS file's CODE blockvoid CSISFileGeneratorBase::WriteCodeL(){ Verbage(_T("Writing code")); const PKGLINENODE *pNode = m_pSISWriter->GetPkgLineBase(); while(pNode) { if((pNode->iPackageLineType == EInstPkgLineFile || pNode->iPackageLineType == EInstPkgLineLanguageFile) && pNode->file->type != EInstFileTypeNull) { HANDLE hInFile = ::MakeSISOpenFile(pNode->file->pszSource, GENERIC_READ, OPEN_EXISTING); if(hInFile == INVALID_HANDLE_VALUE) throw ErrCannotOpenFile; BYTE *pBuf = new BYTE[pNode->file->dwSize]; if (!pBuf) throw ErrNotEnoughMemory; DWORD dwNumBytes; if(!::ReadFile(hInFile, (LPVOID)pBuf, pNode->file->dwSize, &dwNumBytes, NULL)) throw ErrCannotReadFile; if(!::WriteFile(m_hFile, (LPVOID)pBuf, pNode->file->dwSize, &dwNumBytes, NULL)) throw ErrCannotWriteFile; // CRC Crc((void *)pBuf, pNode->file->dwSize); delete [] pBuf; ::CloseHandle(hInFile); _wunlink(pNode->file->pszSource); } pNode = pNode->pNext; }} // To write the CRC section void CSISFileGeneratorBase::WriteCrcL(){ Verbage(_T("Writing crc")); if(::SetFilePointer(m_hFile, sizeof(TInstUID) + sizeof(DWORD), NULL, FILE_BEGIN) == 0xFFFFFFFF) throw ErrFailedToWriteCRC; DWORD dwNumBytes; if(!::WriteFile(m_hFile, (LPVOID)&m_wCheck, sizeof(WORD), &dwNumBytes, NULL)) throw ErrFailedToWriteCRC;} void CSISFileGeneratorBase::WriteSignatureL(LPCWSTR pszTargetFile) {#ifdef DIGITAL_SIGNATURES Verbage(_T("Writing digital signature")); //get private key to encrypt hash for digital signature const SIGNATURENODE* pSignature = m_pSISWriter->GetSignatureBase(); if (pSignature) { // convert private key file name into MBCS for Encrypt() method DWORD length=wcslen(pSignature->pszPrivateKey); LPSTR fName=MakeMBCSString(pSignature->pszPrivateKey, CP_ACP, length); // convert password into MBCS for Encrypt() method WCHAR pszCmdPassword[MAX_PATH]; // Command Line Decryption Password LPSTR pszPassword = ""; //test for command line Decryption Password if (m_pSISWriter->GetCmdPassword(pszCmdPassword)) { length=wcslen(pszCmdPassword); pszPassword=MakeMBCSString(pszCmdPassword, CP_ACP, length); /* #ifdef _DEBUG printf("***DEBUG CODE*** Password is %s\n", pszPassword); #endif */ } else { length=wcslen(pSignature->pszPassword); pszPassword=MakeMBCSString(pSignature->pszPassword, CP_ACP, length); } CPrivateKey* pKey = new CPrivateKey; if (!pKey) throw ErrNotEnoughMemory; pKey->LoadKey(fName, pszPassword); if (pKey->Loaded() == FALSE) { throw ErrCannotOpenFile; } // compute hash across SIS file CHash* pHash = NULL; pHash = new CSHA1; if (!pHash) throw ErrNotEnoughMemory; char hash[HASHLEN]; // convert SIS file name into MBCS for HashFile() method DWORD lengthsis=wcslen(pszTargetFile); LPSTR fSISName=MakeMBCSString(pszTargetFile, CP_ACP, lengthsis); // hash will contain the computed hash for the SIS file DWORD TargetLen = pHash->HashFile(fSISName, hash); delete [] fSISName; delete pHash; //now we need to DSA the SHA-1 signature if (pKey->KeyType() == EDSAPrivateKey) { pHash = new CDSA; if (!pHash) throw ErrNotEnoughMemory; pHash->SetKey(pKey->GetKeyPtr()); // hash will contain the computed SHA-1 signed by DSA pHash->HashFile("", hash); } // encrypt hash to create digital signature CEncrypt* crypto = new CEncrypt; if (!crypto) throw ErrNotEnoughMemory; char ciphertext[CIPHERTEXTLEN]; int KeyLen; TKeyCipher ciphertype; //cipher text will contain the encrypted hash (we only do this for RSA) if (pKey->KeyType() == ERSAPrivateKey) { char string2char[20]; pHash->HexStringToBytes(hash, string2char); if (!crypto->Encrypt(string2char, (unsigned char*)ciphertext, fName, pszPassword, &KeyLen, &ciphertype)) throw ErrCannotOpenFile; } delete [] pszPassword; delete [] fName; delete crypto; // now read in unsigned SIS file & write out new SIS file with appended signature HANDLE hSISFile = ::MakeSISOpenFile(pszTargetFile, GENERIC_READ, OPEN_EXISTING); if(hSISFile == INVALID_HANDLE_VALUE) throw ErrCannotOpenFile; // double check file size is as expected if (TargetLen != ::GetFileSize(hSISFile, NULL)) throw ErrFailedToWriteSignatureBlock; if (pKey->KeyType() == EDSAPrivateKey) { KeyLen = pKey->KeyLength(); } unsigned char* pFileBuf = new unsigned char[TargetLen + KeyLen]; if (!pFileBuf) throw ErrNotEnoughMemory; DWORD dwNumBytes; if(!::ReadFile(hSISFile, (LPVOID)pFileBuf, TargetLen, &dwNumBytes, NULL)) throw ErrCannotReadFile; ::CloseHandle(hSISFile);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -