compressdlg.cpp
来自「一些初级的网络编程」· C++ 代码 · 共 1,352 行 · 第 1/3 页
CPP
1,352 行
dwSecStart += sizeof(IMAGE_SECTION_HEADER);
dwBackupSecStart += sizeof(IMAGE_SECTION_HEADER);
}
// Something strange in release mode ?!?!?!?
// need to track this down really, but for now, just make sure
// we reset the first sections PointerToRawData
{
dwSecStart = (DWORD)pNtHdr;
dwSecStart += 24;
dwSecStart += wSizeO;
dwBackupSecStart = (DWORD)pBackupNtHdr;
dwBackupSecStart += 24;
dwBackupSecStart += wBackupSizeO;
pSecHdr = (PIMAGE_SECTION_HEADER)dwSecStart;
pBackupSecHdr = (PIMAGE_SECTION_HEADER)dwBackupSecStart;
pSecHdr->PointerToRawData = pBackupSecHdr->PointerToRawData;
}
//m_ProgressCtrl.SetPos(100);
}
LPVOID CCompressDlg::Compress(LPVOID lpInputBuffer, DWORD dwInputSize, DWORD* dwOutputSize, PFNAPLIBCALLBACK pfnCallback)
{
// For aPlib
BYTE* pWorkmem = 0;
BYTE* pPacked = 0;
pWorkmem = (BYTE*)malloc(aP_workmem_size(dwInputSize));
pPacked = (BYTE*)malloc(aP_max_packed_size(dwInputSize));
*dwOutputSize = aP_pack(lpInputBuffer, pPacked, dwInputSize, pWorkmem, pfnCallback, this);
return pPacked;
}
LPVOID CCompressDlg::BuildNewResourceSection(LPVOID lpMapping, DWORD* dwOutputSize)
{
PIMAGE_DOS_HEADER pDosHdr = 0;
PIMAGE_NT_HEADERS pNtHdr = 0;
PIMAGE_SECTION_HEADER pSecHdr = 0;
DWORD dwSecStart = 0;
DWORD dwKatSup = 0;
LONG lJmp = 0;
WORD wNumSections = 0;
WORD wSizeO = 0;
int i = 0;
int j = 0;
int k = 0;
pDosHdr = (PIMAGE_DOS_HEADER) lpMapping;
lJmp = pDosHdr->e_lfanew;
dwKatSup = (DWORD)pDosHdr;
dwKatSup += lJmp;
pNtHdr = (PIMAGE_NT_HEADERS)dwKatSup;
wNumSections = pNtHdr->FileHeader.NumberOfSections;
wSizeO = pNtHdr->FileHeader.SizeOfOptionalHeader;
dwSecStart = (DWORD)pNtHdr;
dwSecStart += 24;
dwSecStart += wSizeO;
bool bResource = false;
PIMAGE_RESOURCE_DIRECTORY pRootDirectory = 0;
PIMAGE_RESOURCE_DIRECTORY pSubDirectory = 0;
PIMAGE_RESOURCE_DIRECTORY pSubSubDirectory = 0;
PIMAGE_RESOURCE_DIRECTORY_ENTRY pEntry = 0;
PIMAGE_RESOURCE_DIRECTORY_ENTRY pSubEntry = 0;
PIMAGE_RESOURCE_DIRECTORY_ENTRY pSubSubEntry = 0;
PIMAGE_RESOURCE_DATA_ENTRY pDataEntry = 0;
PIMAGE_RESOURCE_DIR_STRING_U pName = 0;
#pragma pack( push )
#pragma pack( 2 )
typedef struct
{
BYTE bWidth; // Width, in pixels, of the image
BYTE bHeight; // Height, in pixels, of the image
BYTE bColorCount; // Number of colors in image (0 if >=8bpp)
BYTE bReserved; // Reserved
WORD wPlanes; // Color Planes
WORD wBitCount; // Bits per pixel
DWORD dwBytesInRes; // how many bytes in this resource?
WORD nID; // the ID
} GRPICONDIRENTRY, *LPGRPICONDIRENTRY;
typedef struct
{
WORD idReserved; // Reserved (must be 0)
WORD idType; // Resource type (1 for icons)
WORD idCount; // How many images?
GRPICONDIRENTRY idEntries[1]; // The entries for each image
} GRPICONDIR, *LPGRPICONDIR;
#pragma pack( pop )
LPGRPICONDIR lpGroupIconDir = 0;
for(i = 0; i < wNumSections; i++)
{
pSecHdr = (PIMAGE_SECTION_HEADER)dwSecStart;
if(strcmp((char*)pSecHdr->Name, ".rsrc") == 0)
{
bResource = true;
break;
}
// move to next section header
dwSecStart += sizeof(IMAGE_SECTION_HEADER);
}
DWORD dwDirectorySize = 0;
DWORD dwIconSize = 0;
DWORD dwGroupIconSize = 0;
DWORD dwVersionSize = 0;
DWORD dwManifestSize = 0;
DWORD dwIconCount = 0;
DWORD dwGroupIconCount = 0;
if(bResource)
{
pRootDirectory = (PIMAGE_RESOURCE_DIRECTORY)((DWORD)lpMapping + pSecHdr->PointerToRawData);
int nDirectoryCount = pRootDirectory->NumberOfIdEntries + pRootDirectory->NumberOfNamedEntries;
pEntry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((DWORD)pRootDirectory + sizeof(IMAGE_RESOURCE_DIRECTORY));
// First pass - figure out number of icons in first icon group
for(i = 0; i < nDirectoryCount; i++)
{
if(pEntry->DataIsDirectory)
{
pSubDirectory = (PIMAGE_RESOURCE_DIRECTORY)((DWORD)pEntry->OffsetToDirectory + (DWORD)pRootDirectory);
int nSubDirectoryCount = pSubDirectory->NumberOfIdEntries + pSubDirectory->NumberOfNamedEntries;
pSubEntry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((DWORD)pSubDirectory + sizeof(IMAGE_RESOURCE_DIRECTORY));
for(j = 0; j < nSubDirectoryCount; j++)
{
if(pSubEntry->DataIsDirectory)
{
pSubSubDirectory = (PIMAGE_RESOURCE_DIRECTORY)((DWORD)pSubEntry->OffsetToDirectory + (DWORD)pRootDirectory);
int nSubSubDirectoryCount = pSubSubDirectory->NumberOfIdEntries + pSubSubDirectory->NumberOfNamedEntries;
pSubSubEntry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((DWORD)pSubSubDirectory + sizeof(IMAGE_RESOURCE_DIRECTORY));
for(k = 0; k < nSubSubDirectoryCount; k++)
{
if(!pSubSubEntry->DataIsDirectory)
{
if(!(pSubSubEntry->OffsetToData & 0x8000000))
{
pDataEntry = (PIMAGE_RESOURCE_DATA_ENTRY)((DWORD)pRootDirectory + pSubSubEntry->OffsetToData);
switch(pEntry->Name)
{
case RT_GROUP_ICON:
lpGroupIconDir = (LPGRPICONDIR)(RVAToOffset(pDataEntry->OffsetToData, lpMapping) + (DWORD)lpMapping);
gev.dwFirstGroupIconCount = lpGroupIconDir->idCount;
break;
}
}
}
if(lpGroupIconDir)
break;
pSubSubEntry++;
}
}
if(lpGroupIconDir)
break;
pSubEntry++;
}
}
if(lpGroupIconDir)
break;
pEntry++;
}
pRootDirectory = (PIMAGE_RESOURCE_DIRECTORY)((DWORD)lpMapping + pSecHdr->PointerToRawData);
nDirectoryCount = pRootDirectory->NumberOfIdEntries + pRootDirectory->NumberOfNamedEntries;
pEntry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((DWORD)pRootDirectory + sizeof(IMAGE_RESOURCE_DIRECTORY));
// Second pass
for(i = 0; i < nDirectoryCount; i++)
{
if(pEntry->DataIsDirectory)
{
pSubDirectory = (PIMAGE_RESOURCE_DIRECTORY)((DWORD)pEntry->OffsetToDirectory + (DWORD)pRootDirectory);
int nSubDirectoryCount = pSubDirectory->NumberOfIdEntries + pSubDirectory->NumberOfNamedEntries;
pSubEntry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((DWORD)pSubDirectory + sizeof(IMAGE_RESOURCE_DIRECTORY));
for(j = 0; j < nSubDirectoryCount; j++)
{
if(pSubEntry->DataIsDirectory)
{
pSubSubDirectory = (PIMAGE_RESOURCE_DIRECTORY)((DWORD)pSubEntry->OffsetToDirectory + (DWORD)pRootDirectory);
int nSubSubDirectoryCount = pSubSubDirectory->NumberOfIdEntries + pSubSubDirectory->NumberOfNamedEntries;
pSubSubEntry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((DWORD)pSubSubDirectory + sizeof(IMAGE_RESOURCE_DIRECTORY));
for(k = 0; k < nSubSubDirectoryCount; k++)
{
if(!pSubSubEntry->DataIsDirectory)
{
if(!(pSubSubEntry->OffsetToData & 0x8000000))
{
pDataEntry = (PIMAGE_RESOURCE_DATA_ENTRY)((DWORD)pRootDirectory + pSubSubEntry->OffsetToData);
switch(pEntry->Name)
{
case RT_ICON:
// Copy however many icons are in the first icon group
if(dwIconCount < lpGroupIconDir->idCount)
{
dwIconSize += pDataEntry->Size;
dwIconCount++;
}
break;
case RT_GROUP_ICON:
// Only copy the first icon group
if(dwGroupIconCount < 1)
{
dwGroupIconSize += pDataEntry->Size;
dwGroupIconCount++;
}
break;
case RT_VERSION:
dwVersionSize += pDataEntry->Size;
break;
case 24: // RT_MANIFEST
dwManifestSize += pDataEntry->Size;
break;
}
}
}
dwDirectorySize = pSubSubEntry->OffsetToData + sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY);
pSubSubEntry++;
}
}
pSubEntry++;
}
}
pEntry++;
}
// allocate size of original, will be more than enough for uncompressed resource
dwDirectorySize = ValidAlignment(dwDirectorySize, 0x200);
// Reset some counters
dwIconCount = 0;
dwGroupIconCount = 0;
if(dwDirectorySize > 0)
{
DWORD dwNewResourceSectionSize = dwDirectorySize + dwIconSize + dwGroupIconSize + dwVersionSize + dwManifestSize;
dwNewResourceSectionSize = ValidAlignment(dwNewResourceSectionSize, 0x200);
DWORD dwNewResourceSectionPosition = 0;
BYTE* lpbNewResourceSection = (BYTE*)malloc(dwNewResourceSectionSize);
memset(lpbNewResourceSection, 0, dwNewResourceSectionSize);
memcpy(lpbNewResourceSection, pRootDirectory, dwDirectorySize);
dwNewResourceSectionPosition += dwDirectorySize;
pRootDirectory = (PIMAGE_RESOURCE_DIRECTORY)((DWORD)lpbNewResourceSection);
nDirectoryCount = pRootDirectory->NumberOfIdEntries + pRootDirectory->NumberOfNamedEntries;
pEntry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((DWORD)pRootDirectory + sizeof(IMAGE_RESOURCE_DIRECTORY));
// Third pass
for(i = 0; i < nDirectoryCount; i++)
{
if(pEntry->DataIsDirectory)
{
pSubDirectory = (PIMAGE_RESOURCE_DIRECTORY)((DWORD)pEntry->OffsetToDirectory + (DWORD)pRootDirectory);
int nSubDirectoryCount = pSubDirectory->NumberOfIdEntries + pSubDirectory->NumberOfNamedEntries;
pSubEntry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((DWORD)pSubDirectory + sizeof(IMAGE_RESOURCE_DIRECTORY));
for(j = 0; j < nSubDirectoryCount; j++)
{
if(pSubEntry->DataIsDirectory)
{
pSubSubDirectory = (PIMAGE_RESOURCE_DIRECTORY)((DWORD)pSubEntry->OffsetToDirectory + (DWORD)pRootDirectory);
int nSubSubDirectoryCount = pSubSubDirectory->NumberOfIdEntries + pSubSubDirectory->NumberOfNamedEntries;
pSubSubEntry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)((DWORD)pSubSubDirectory + sizeof(IMAGE_RESOURCE_DIRECTORY));
for(k = 0; k < nSubSubDirectoryCount; k++)
{
if(pSubSubEntry->DataIsDirectory)
{
// recurse again!
//printf("Shouldn't normally get here, resource directory is already 3 levels deep!\n");
}
else
{
if(!(pSubSubEntry->OffsetToData & 0x8000000))
{
pDataEntry = (PIMAGE_RESOURCE_DATA_ENTRY)((DWORD)pRootDirectory + pSubSubEntry->OffsetToData);
DWORD dwFileOffset = 0;
switch(pEntry->Name)
{
case RT_ICON:
if(dwIconCount < lpGroupIconDir->idCount)
{
dwFileOffset = RVAToOffset(pDataEntry->OffsetToData, lpMapping);
memcpy((LPVOID)((DWORD)lpbNewResourceSection + dwNewResourceSectionPosition), (LPVOID)((DWORD)lpMapping + dwFileOffset), pDataEntry->Size);
// blank original to enable higher compression
memset((LPVOID)((DWORD)lpMapping + dwFileOffset), 0, pDataEntry->Size);
pDataEntry->OffsetToData = OffsetToRVA(pSecHdr->PointerToRawData + dwNewResourceSectionPosition, lpMapping);
dwNewResourceSectionPosition += pDataEntry->Size;
dwIconCount++;
}
break;
case RT_GROUP_ICON:
if(dwGroupIconCount < lpGroupIconDir->idCount)
{
dwFileOffset = RVAToOffset(pDataEntry->OffsetToData, lpMapping);
memcpy((LPVOID)((DWORD)lpbNewResourceSection + dwNewResourceSectionPosition), (LPVOID)((DWORD)lpMapping + dwFileOffset), pDataEntry->Size);
// blank original to enable higher compression
memset((LPVOID)((DWORD)lpMapping + dwFileOffset), 0, pDataEntry->Size);
pDataEntry->OffsetToData = OffsetToRVA(pSecHdr->PointerToRawData + dwNewResourceSectionPosition, lpMapping);
dwNewResourceSectionPosition += pDataEntry->Size;
dwGroupIconCount++;
}
break;
case RT_VERSION:
case 24: // RT_MANIFEST
dwFileOffset = RVAToOffset(pDataEntry->OffsetToData, lpMapping);
memcpy((LPVOID)((DWORD)lpbNewResourceSection + dwNewResourceSectionPosition), (LPVOID)((DWORD)lpMapping + dwFileOffset), pDataEntry->Size);
// blank original to enable higher compression
memset((LPVOID)((DWORD)lpMapping + dwFileOffset), 0, pDataEntry->Size);
pDataEntry->OffsetToData = OffsetToRVA(pSecHdr->PointerToRawData + dwNewResourceSectionPosition, lpMapping);
dwNewResourceSectionPosition += pDataEntry->Size;
break;
}
}
}
pSubSubEntry++;
}
}
pSubEntry++;
}
}
pEntry++;
}
*dwOutputSize = dwNewResourceSectionSize;
return lpbNewResourceSection;
}
}
*dwOutputSize = 0;
return 0;
}
int CCompressDlg::CallbackFunc(size_t length, size_t input, size_t output, void* cbparam)
{
CCompressDlg* pDlg = (CCompressDlg*)cbparam;
double fPercent = 0.0;
fPercent = ((double)(input + pDlg->m_ProgressOffset)/(double)(pDlg->m_ProgressFileSize))*100;
if(fPercent > 100)
fPercent = 100.0;
pDlg->m_ctrlCompressionProgress.SetPos((int)fPercent);
pDlg->m_CompressionProgress.Format("%.02f%%", fPercent);
pDlg->UpdateData(FALSE);
return 1;
}
void CCompressDlg::OnCompress()
{
UpdateData(TRUE);
m_ctrlCompressionProgress.SetPos(0);
m_ctrlCompessedSize.SetPos(0);
Encrypt((char*)m_SourceFile.GetBuffer(0));
}
BOOL CCompressDlg::OnInitDialog()
{
CTexturedDlg::OnInitDialog();
m_ctrlCompressionProgress.SetStep(1);
m_ctrlCompressionProgress.SetRange(0, 100);
m_ctrlCompressionProgress.SetPos(0);
m_CompressionProgress = "";
m_ctrlCompessedSize.SetStep(1);
m_ctrlCompessedSize.SetRange(0, 100);
m_ctrlCompessedSize.SetPos(0);
m_FileSize = "";
UpdateData(FALSE);
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?