📄 crtsis.cpp
字号:
while(pNode && (wNumLangs > 1)) { pNode = pNode->pNext; wNumLangs--; } } break; case EInstPkgLineOption: { m_dwOffDepend += sizeof(TInstOptions); const LANGSTRINGNODE* pLSNode = pNode->option->pLangStringBase; while(pLSNode) { m_dwOffDepend += sizeof(TInt32)+sizeof(FOFF); stringSizes += wcslen(pLSNode->pszString) * SizeOfChar(); pLSNode = pLSNode->pNext; } m_dwOffDepend += sizeof(TUint32)*KInstallMaxOptionsInts; } break; case EInstPkgLineCondIf: case EInstPkgLineCondElseIf: m_dwOffDepend += sizeof(TInt32) + CalcConditionExprSize(pNode->cond, &stringSizes); break; case EInstPkgLineCondElse: case EInstPkgLineCondEndIf: break; } pNode = pNode->pNext; } // Calculate the certificate block offset (the size of The DEPENDENCY block) ----------------------------- m_dwOffCertificates = m_dwOffDepend; const DEPENDNODE *pDNode = m_pSISWriter->GetDependencyBase(); while(pDNode) { m_dwOffCertificates += sizeof(TInstDependency) + ((sizeof(DWORD) + sizeof(FOFF)) * m_pSISWriter->GetNoLanguages()); pDNode = pDNode->pNext; } // Calculate capabilities offsets (the size of the certificates block) DWORD size=0;#ifdef DIGITAL_SIGNATURES const SIGNATURENODE* pSignature = m_pSISWriter->GetSignatureBase(); HANDLE hInFile; if (pSignature) { if (m_bWriteChain) { hInFile = ::MakeSISOpenFile(pSignature->pszChainFile, GENERIC_READ, OPEN_EXISTING); if (hInFile == INVALID_HANDLE_VALUE) throw ErrCannotOpenFile; } else { //write certificate verbatim hInFile = ::MakeSISOpenFile(pSignature->pszB64File, GENERIC_READ, OPEN_EXISTING); if (hInFile == INVALID_HANDLE_VALUE) throw ErrCannotOpenFile; } size=::GetFileSize(hInFile, NULL) + sizeof (TInstCertBlock); ::CloseHandle(hInFile); if (size==0xFFFFFFFF) throw ErrCannotOpenFile; }#endif m_dwOffCapabilities = m_dwOffCertificates+size; // Calculate the string block offset (the size of the CAPABILITIES block) ----------------------------- m_dwOffString = m_dwOffCapabilities; const CAPABILITYNODE* pCNode = m_pSISWriter->GetCapabilityBase(); while(pCNode) { m_dwOffString += sizeof(TInstCapability); pCNode = pCNode->pNext; } // Calculate the code offset (the size of the STRING block) ----------------------------------- // 1. The Language Strings m_dwOffCode = m_dwOffString; m_dwOffCode += (sizeof(DWORD) + sizeof(FOFF)) * m_pSISWriter->GetNoLanguages(); const LANGSTRINGNODE *pLSNode = m_pSISWriter->GetLangStringBase(); while(pLSNode) { m_dwOffCode += wcslen(pLSNode->pszString) * SizeOfChar(); pLSNode = pLSNode->pNext; } // 2. Allow for any package line strings m_dwOffCode += stringSizes; // 3. Any File dependencies pDNode = m_pSISWriter->GetDependencyBase(); while(pDNode) { pLSNode = pDNode->pLangStringBase; while(pLSNode) { m_dwOffCode += wcslen(pLSNode->pszString) * SizeOfChar(); pLSNode = pLSNode->pNext; } pDNode = pDNode->pNext; } // Calculate the signature offset (the size of the CODE block) ----------------------------------- m_dwOffSignature=m_dwOffCode; pNode = m_pSISWriter->GetPkgLineBase(); while(pNode) { if((pNode->iPackageLineType == EInstPkgLineFile || pNode->iPackageLineType == EInstPkgLineLanguageFile) && pNode->file->type != EInstFileTypeNull) { m_dwOffSignature+=pNode->file->dwSize; } pNode = pNode->pNext; } } DWORD CSISFileGeneratorBase::CalcConditionExprSize(const PKGLINECONDITION* expr, DWORD* stringSizes) { DWORD size=0; if (expr) { size=sizeof(TInstCondExpr); switch (expr->exprType) { case EInstCondBinOpEq: case EInstCondBinOpNe: case EInstCondBinOpGt: case EInstCondBinOpLt: case EInstCondBinOpGe: case EInstCondBinOpLe: case EInstCondLogOpAnd: case EInstCondLogOpOr: size+=CalcConditionExprSize(expr->b.pLhs,stringSizes)+CalcConditionExprSize(expr->b.pRhs,stringSizes); break; case EInstCondUnaryOpNot: size+=CalcConditionExprSize(expr->pExpr,stringSizes); break; case EInstCondFuncAppCap: size+=CalcConditionExprSize(expr->pArg[0],stringSizes); size+=CalcConditionExprSize(expr->pArg[1],stringSizes); break; case EInstCondFuncDevCap: case EInstCondFuncExists: size+=CalcConditionExprSize(expr->pArg[0],stringSizes); break; case EInstCondPrimTypeString: *stringSizes+=wcslen(expr->pPrim->pszString) * SizeOfChar(); case EInstCondPrimTypeVariable: case EInstCondPrimTypeNumber: size+=sizeof(TInstCondPrim); break; default: break; } } return size; } void CSISFileGeneratorBase::WriteHeaderL() // Purpose : Writes the SIS file HEADER block // Inputs : fIsStub - TRUE if writing a stub file{ Verbage(_T("Writing installation header")); TInstInstallation iiHead; // Clear the header memset((void *)&iiHead, '\0', sizeof(TInstInstallation)); // Set the UID iiHead.iThisUID.iUid[0] = m_pSISWriter->GetUID(); if(m_pSISWriter->GetFlags() & EInstIsUnicode) iiHead.iThisUID.iUid[1] = KUidInstallAppUid1U; else iiHead.iThisUID.iUid[1] = KUidInstallAppUid1; // Narrow output iiHead.iThisUID.iUid[2] = KUidInstallAppValue; // Write the UID Checksum DWORD dwCheck = 0; UIDCheck(((char *)&iiHead.iThisUID.iUid[0]) + 1); dwCheck = (DWORD)(m_wCheck) << 16; m_wCheck = 0; UIDCheck((char *)&iiHead.iThisUID.iUid[0]); dwCheck |= m_wCheck; iiHead.iUidChecksum = dwCheck; // CRC m_wCheck = 0; Crc((void *)&iiHead, sizeof (TInstUID)); Crc((void *)&iiHead.iUidChecksum, sizeof (DWORD)); // Set the version iiHead.iInstVersion = KInstallerVersion; // Set the type & flags iiHead.iType = (TInt16)m_pSISWriter->GetType(); iiHead.iFlags = m_pSISWriter->GetFlags(); // Set this version WORD wMajor, wMinor; DWORD dwBuild; m_pSISWriter->QueryVersionInfo(&wMajor, &wMinor, &dwBuild); iiHead.iCompVersion.iMajor = (WORD)wMajor; iiHead.iCompVersion.iMinor = (WORD)wMinor; iiHead.iCompVersion.iBuild = dwBuild; // Set the languages iiHead.iNumLanguages = m_pSISWriter->GetNoLanguages(); iiHead.iLanguageBlock = m_dwOffLang; // Set the PKG lines const PKGLINENODE *pNode = m_pSISWriter->GetPkgLineBase(); while(pNode) { iiHead.iNumPkgLines++; if (pNode->iPackageLineType==EInstPkgLineFile || pNode->iPackageLineType==EInstPkgLineLanguageFile) { if (pNode->file->pszDest[0]) { if (iiHead.iInstallDrive==0) iiHead.iInstallDrive=pNode->file->pszDest[0]; else if (iiHead.iInstallDrive!=pNode->file->pszDest[0]) iiHead.iInstallDrive = '!'; } if (pNode->iPackageLineType==EInstPkgLineLanguageFile) { WORD wMaxLangs = m_pSISWriter->GetNoLanguages(); WORD wNumLang = 0; while(pNode && (wNumLang < wMaxLangs-1)) { pNode = pNode->pNext; wNumLang++; } } } pNode = pNode->pNext; } iiHead.iPackageLinesBlock = m_dwOffPkgLines; // Set the dependencies const DEPENDNODE *pDNode = m_pSISWriter->GetDependencyBase(); while(pDNode) { iiHead.iNumDependencies++; pDNode = pDNode->pNext; } iiHead.iDependenciesBlock = m_dwOffDepend; // set the certificates block offset#ifdef DIGITAL_SIGNATURES if (m_pSISWriter->GetSignatureBase()) iiHead.iCertificatesBlock = m_dwOffCertificates;#endif // Set the capabilities const CAPABILITYNODE *pCNode = m_pSISWriter->GetCapabilityBase(); while(pCNode) { iiHead.iNumCapabilities++; pCNode = pCNode->pNext; } iiHead.iCapabilitiesBlock = m_dwOffCapabilities; // Set the Names iiHead.iNames = m_dwOffString; m_dwCurrString = m_dwOffString + ((sizeof(DWORD) + sizeof(FOFF)) * m_pSISWriter->GetNoLanguages()); // Check if we are writing a stub file if(m_stubFile) { iiHead.iInstallDrive = (WORD)'z'; iiHead.iNumPkgLinesDone = iiHead.iNumPkgLines; iiHead.iLangChosen = 0; } // set maximum size required to install iiHead.iMaximumSpaceNeeded = m_dwMaximumSpaceNeeded; // Set the digital signature offset#ifdef DIGITAL_SIGNATURES if (m_pSISWriter->GetSignatureBase()) iiHead.iSignatureBlock = m_dwOffSignature;#endif // Write the buffer DWORD dwNumBytes; if(!::WriteFile(m_hFile, (LPVOID)&iiHead, sizeof(TInstInstallation), &dwNumBytes, NULL)) throw ErrFailedToWriteHeader; m_dwCurrCode = m_dwOffCode; // CRC Crc((void *)(&iiHead.iNumLanguages), sizeof (TInstInstallation) - sizeof(TInstUID) - sizeof(DWORD) - sizeof(WORD)); }void CSISFileGeneratorBase::WriteLanguageL()// To write the SIS file's LANGUAGES block { Verbage(_T("Writing languages")); DWORD dwLangCount = m_pSISWriter->GetNoLanguages(); const LANGNODE *pLNode = m_pSISWriter->GetLanguageBase(); WORD *pLang = new WORD[dwLangCount]; if (!pLang) throw ErrNotEnoughMemory; WORD wCount = 0; while(pLNode) { pLang[wCount++] = pLNode->wLang; pLNode = pLNode->pNext; } DWORD dwNumBytes; if(!::WriteFile(m_hFile, (LPVOID)pLang, sizeof(WORD) * dwLangCount, &dwNumBytes, NULL)) throw ErrFailedToWriteLanguages; Crc((void *)pLang, sizeof(WORD) * dwLangCount); delete [] pLang; }void CSISFileGeneratorBase::WritePkgLinesL()// To write the SIS pkg lines block { Verbage(_T("Writing PKG lines block")); DWORD dwNumBytes; const PKGLINENODE *pNode = m_pSISWriter->GetPkgLineBase(); while(pNode) { // write type if(!::WriteFile(m_hFile, (LPVOID)&pNode->iPackageLineType, sizeof(TInstPackageLineType), &dwNumBytes, NULL)) throw ErrFailedToWriteFilesBlock; Crc((void *)&pNode->iPackageLineType, sizeof(TInstPackageLineType)); // write specific PKG node data switch (pNode->iPackageLineType) { case EInstPkgLineFile: case EInstPkgLineLanguageFile: WriteFileNodeL(pNode); if (pNode->iPackageLineType==EInstPkgLineLanguageFile) { WORD wMaxLangs = m_pSISWriter->GetNoLanguages(); WORD wNumLang = 0; while(pNode && (wNumLang < wMaxLangs-1)) { pNode = pNode->pNext; wNumLang++; } } break; case EInstPkgLineOption: WriteOptionsNodeL(pNode); break; case EInstPkgLineCondIf: case EInstPkgLineCondElseIf: { DWORD stringSizes; DWORD size=CalcConditionExprSize(pNode->cond, &stringSizes); if(!::WriteFile(m_hFile, (LPVOID)&size, sizeof(DWORD), &dwNumBytes, NULL)) throw ErrFailedToWriteFilesBlock; Crc((void *)&size, sizeof(DWORD)); WriteConditionNodeL(pNode); } break; case EInstPkgLineCondElse: case EInstPkgLineCondEndIf: break; } pNode = pNode->pNext; } }void CSISFileGeneratorBase::WriteFileNodeL(const PKGLINENODE* pNode)// To write the SIS files FILES block { const PKGLINEFILE* pFNode=pNode->file; DWORD dwNumBytes; TInstFile ifFile; memset((void *)&ifFile, '\0', sizeof(TInstFile)); ConfigureFileNode(pFNode, &ifFile); if(!::WriteFile(m_hFile, (LPVOID)&ifFile, sizeof(ifFile), &dwNumBytes, NULL)) throw ErrFailedToWriteFilesBlock; // CRC Crc((void *)&ifFile, sizeof(ifFile)); // Set the file lengths and offsets const PKGLINENODE *pTempNode = pNode; WORD wMaxLangs = 1; if (pNode->iPackageLineType==EInstPkgLineLanguageFile) wMaxLangs = m_pSISWriter->GetNoLanguages(); // write file lengths (compressed lengths if enabled) WORD wNumLang = 0; while(pNode && (wNumLang < wMaxLangs)) { if (!::WriteFile(m_hFile, (LPVOID)&pNode->file->dwSize, sizeof(DWORD), &dwNumBytes, NULL)) throw ErrFailedToWriteFilesBlock; // CRC Crc((void *)&pNode->file->dwSize, sizeof(DWORD)); pNode = pNode->pNext; wNumLang++; } // write file offsets pNode = pTempNode; wNumLang = 0; while(pNode && (wNumLang < wMaxLangs)) { if(!::WriteFile(m_hFile, (LPVOID)&m_dwCurrCode, sizeof(DWORD), &dwNumBytes, NULL)) throw ErrFailedToWriteFilesBlock; // CRC Crc((void *)&m_dwCurrCode, sizeof(DWORD)); m_dwCurrCode += pNode->file->dwSize; pNode = pNode->pNext; wNumLang++; } // write uncompressed file lengths pNode = pTempNode; wNumLang = 0; while(pNode && (wNumLang < wMaxLangs)) { if (!::WriteFile(m_hFile, (LPVOID)&pNode->file->dwUncompressedSize, sizeof(DWORD), &dwNumBytes, NULL)) throw ErrFailedToWriteFilesBlock; Crc((void *)&pNode->file->dwUncompressedSize, sizeof(DWORD)); pNode = pNode->pNext; wNumLang++; } // write mime type if appropriate TInstString mimeType; mimeType.iCount=wcslen(pFNode->pszMimeType); // NOTE: 8 bit string! mimeType.iStringPtr=m_dwCurrString; m_dwCurrString += mimeType.iCount; if (!::WriteFile(m_hFile, (LPVOID)&mimeType, sizeof(TInstString), &dwNumBytes, NULL)) throw ErrFailedToWriteFilesBlock; Crc((void *)&mimeType, sizeof(TInstString)); }void CSISFileGeneratorBase::ConfigureFileNode(const PKGLINEFILE *pNode, TInstFile *pifFile)// Purpose : Converts a FILENODE to a InstFile structure// Inputs : pNode The filenaode to converts// pifFile A pointer to the target InstFile structure { pifFile->iFileType = pNode->type; pifFile->iOption = pNode->options; // Set the source pifFile->iSource.iCount = wcslen(pNode->pszSource) * SizeOfChar(); pifFile->iSource.iStringPtr = m_dwCurrString; m_dwCurrString += pifFile->iSource.iCount; // Set the dest pifFile->iDestination.iCount = wcslen(pNode->pszDest) * SizeOfChar(); pifFile->iDestination.iStringPtr = m_dwCurrString; m_dwCurrString += pifFile->iDestination.iCount; }void CSISFileGeneratorBase::WriteOptionsNodeL(const PKGLINENODE* pNode)// To write an options PKG line { DWORD i,j; DWORD dwNumBytes; DWORD dwLength; const PKGLINEOPTIONS* pONode=pNode->option; DWORD dwNumOptions=pONode->dwNumOptions; if (!::WriteFile(m_hFile, (LPVOID)&dwNumOptions, sizeof(DWORD), &dwNumBytes, NULL)) throw ErrFailedToWriteOptionsBlock; // CRC Crc((void *)&dwNumOptions, sizeof(DWORD)); const LANGSTRINGNODE *pLSNode = pONode->pLangStringBase; for (i=0;i<dwNumOptions;i++) { const LANGSTRINGNODE *pLSNode2 = pLSNode; for(j=0;j<m_pSISWriter->GetNoLanguages();j++) { dwLength = wcslen(pLSNode->pszString) * SizeOfChar(); if(!::WriteFile(m_hFile, (LPVOID)&dwLength, sizeof(DWORD), &dwNumBytes, NULL)) throw ErrFailedToWriteOptionsBlock; // CRC Crc((void *)&dwLength, sizeof(DWORD)); pLSNode = pLSNode->pNext; } pLSNode = pLSNode2; for(j=0;j<m_pSISWriter->GetNoLanguages();j++) { if(!::WriteFile(m_hFile, (LPVOID)&m_dwCurrString, sizeof(DWORD), &dwNumBytes, NULL)) throw ErrFailedToWriteOptionsBlock; // CRC Crc((void *)&m_dwCurrString, sizeof(DWORD)); m_dwCurrString += wcslen(pLSNode->pszString) * SizeOfChar(); pLSNode = pLSNode->pNext; } } // write out option selection values DWORD dwSelected=0xFFFFFFFF; for (i=0;i<KInstallMaxOptionsInts;i++) { if(!::WriteFile(m_hFile, (LPVOID)&dwSelected, sizeof(DWORD), &dwNumBytes, NULL)) throw ErrFailedToWriteOptionsBlock; // CRC Crc((void *)&dwSelected, sizeof(DWORD)); } }void CSISFileGeneratorBase::WriteConditionNodeL(const PKGLINENODE* pNode)// To write a condition PKG line { const PKGLINECONDITION* pCNode=pNode->cond; // write out recursive condition expression(s) WriteCondExprL(pCNode); }void CSISFileGeneratorBase::WriteCondExprL(const PKGLINECONDITION* expr) { TInstCondExpr iceExpr; TInstCondPrim prim; DWORD dwNumBytes; if (expr) { iceExpr.iExprType=expr->exprType; if(!WriteFile(m_hFile, (LPVOID)&iceExpr, sizeof(TInstCondExpr), &dwNumBytes, NULL)) throw ErrFailedToWriteConditionBlock; // CRC Crc((void *)&iceExpr, sizeof(TInstCondExpr)); switch (expr->exprType) { case EInstCondBinOpEq: case EInstCondBinOpNe:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -