UINT _ExtractFromExe(HANDLE hFile, int iconIndex, int cxIconSize, int cyIconSize, HICON *phicon, UINT flags) { int retval = 0; DWORD fileLen = GetFileSize(hFile, NULL); HANDLE hFileMap = INVALID_HANDLE_VALUE, pFile = NULL; IMAGE_DOS_HEADER* pDosHeader; void* pRes; DWORD cbSize = 0; NEWHEADER* pIconDir; int idIcon; LPBITMAPINFOHEADER pIcon; // UINT res = 0; hFileMap = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL); if (hFileMap == NULL) goto cleanup; pFile = MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 0); if (pFile == NULL) goto cleanup; pDosHeader = (IMAGE_DOS_HEADER*)(void*)pFile; if (pDosHeader->e_magic != IMAGE_DOS_SIGNATURE) goto cleanup; if (pDosHeader->e_lfanew <= 0) goto cleanup; if ((DWORD)(pDosHeader->e_lfanew) >= fileLen) goto cleanup; pRes = _GetResourceTable(pDosHeader); if (!pRes) goto cleanup; if (!phicon) { retval = _FindResourceCount(pRes, (int)RT_GROUP_ICON); goto cleanup; } pIconDir = (NEWHEADER*)_FindResource(pDosHeader, pRes, iconIndex, (int)RT_GROUP_ICON, &cbSize); if (!pIconDir) goto cleanup; if (pIconDir->Reserved || pIconDir->ResType != RES_ICON) goto cleanup; idIcon = LookupIconIdFromDirectoryEx((LPBYTE)pIconDir, TRUE, cxIconSize, cyIconSize, flags); pIcon = (LPBITMAPINFOHEADER)_FindResource(pDosHeader, pRes, -idIcon, (int)RT_ICON, &cbSize); if (!pIcon) goto cleanup; if (pIcon->biSize != sizeof(BITMAPINFOHEADER) && pIcon->biSize != sizeof(BITMAPCOREHEADER)) { _ASSERT(0); goto cleanup; } *phicon = CreateIconFromResourceEx((LPBYTE)pIcon, cbSize, TRUE, VER30, cxIconSize, cyIconSize, flags); retval = 1; cleanup: if (pFile) UnmapViewOfFile(pFile); if (hFileMap != INVALID_HANDLE_VALUE) CloseHandle(hFileMap); return retval; }
UINT ExtractIcons::_ExtractFromExe( HANDLE hFile, int iconIndex, int cxIconSize, int cyIconSize, HICON *phicon, UINT *piconid, UINT maxIcons, UINT flags ) { DWORD fileLen = GetFileSize( hFile, NULL ); SmartHANDLE hFileMap( CreateFileMapping( hFile, NULL, PAGE_READONLY, 0, 0, NULL ) ); if( hFileMap == NULL ) return 0; SmartFileMapping pFile( MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 0) ); if( pFile == NULL ) return 0; IMAGE_DOS_HEADER* pDosHeader = (IMAGE_DOS_HEADER*)(void*)pFile; if( pDosHeader->e_magic != IMAGE_DOS_SIGNATURE ) return 0; if( pDosHeader->e_lfanew <= 0 ) return 0; if( DWORD(pDosHeader->e_lfanew) >= fileLen ) return 0; void* pRes = _GetResourceTable( pDosHeader ); if( pRes == NULL) return 0; // cant find the resource DWORD cbSize = 0; if( phicon == NULL ) { // we want the count int count = _FindResourceCount( pRes, (INT_PTR)RT_GROUP_ICON ); return count; } UINT res = 0; while( res < maxIcons ) { // find the icon dir for this icon. NEWHEADER* pIconDir = (NEWHEADER*)_FindResource( pDosHeader, pRes, iconIndex, (INT_PTR)RT_GROUP_ICON, &cbSize ); if( pIconDir == NULL ) return res; if( pIconDir->Reserved != 0 || pIconDir->ResType != RES_ICON ) // 1 == iconType { _ASSERT( 0 ); return res; } int idIcon = LookupIconIdFromDirectoryEx( (LPBYTE)pIconDir, TRUE, cxIconSize, cyIconSize, flags ); void* pIcon = _FindResource( pDosHeader, pRes, -idIcon, (INT_PTR)RT_ICON, &cbSize ); if( pIcon == NULL ) return res; if( (((LPBITMAPINFOHEADER)pIcon)->biSize != sizeof(BITMAPINFOHEADER)) && (((LPBITMAPINFOHEADER)pIcon)->biSize != sizeof(BITMAPCOREHEADER)) ) { _ASSERT( 0 ); return res; } if( piconid ) piconid[res] = idIcon; phicon[res] = CreateIconFromResourceEx( (LPBYTE)pIcon, cbSize, TRUE, VER30, cxIconSize, cyIconSize, flags ); res++; iconIndex++; // next icon index } return res; }