UINT _ExtractIconEx(LPCTSTR lpszFile, int iconIndex, int cxIcon, int cyIcon, HICON *phicon, UINT flags) { HANDLE hFile; WORD magic[6]; DWORD read = 0; UINT res = 0; if (cxIcon == GetSystemMetrics(SM_CXICON) && cyIcon == GetSystemMetrics(SM_CYICON)) res = ExtractIconEx(lpszFile, iconIndex, phicon, NULL, 1); else if (cxIcon == GetSystemMetrics(SM_CXSMICON) && cyIcon == GetSystemMetrics(SM_CYSMICON)) res = ExtractIconEx(lpszFile, iconIndex, NULL, phicon, 1); else if (cxIcon == 0 || cyIcon == 0) res = ExtractIconEx(lpszFile, iconIndex, NULL, phicon, 1); // check if the api succeded, if not try our method too if (res) return res; hFile = CreateFile(lpszFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); if (hFile == INVALID_HANDLE_VALUE) return 0; // failed to read file signature if (!ReadFile(hFile, &magic, sizeof(magic), &read, NULL) || (read != sizeof(magic))) { CloseHandle(hFile); return 0; } switch (magic[0]) { case IMAGE_DOS_SIGNATURE: res = _ExtractFromExe(hFile, iconIndex, cxIcon, cyIcon, phicon, flags); break; case MAGIC_ANI1: // ani cursors are RIFF file of type 'ACON' if (magic[1] == MAGIC_ANI2 && magic[4] == MAGIC_ANI3 && magic[5] == MAGIC_ANI4) res = _ExtractFromICO(lpszFile, iconIndex, cxIcon, cyIcon, phicon, flags); break; case MAGIC_ICON: if ((magic[1] == MAGIC_ICO1 || magic[1] == MAGIC_CUR) && magic[2] >= 1) res = _ExtractFromICO(lpszFile, iconIndex, cxIcon, cyIcon, phicon, flags); break; } CloseHandle(hFile); return res; }
UINT ExtractIcons::_ExtractIcons( LPCTSTR pFileName, int iconIndex, int cxIcon, int cyIcon, HICON* phicon, UINT* piconid, UINT maxIcons, UINT flags ) { SmartHANDLE hFile( INVALID_HANDLE_VALUE ); if( phicon != NULL ) *phicon = NULL; if( piconid != NULL ) *piconid = (UINT)-1; TCHAR fileName[MAX_PATH]; lstrcpy( fileName, pFileName ); // check for special extensions, and fail quick switch( _HasExtension( fileName ) ) { case COM_FILE: case BAT_FILE: case CMD_FILE: case PIF_FILE: case LNK_FILE: return 0; default: break; } _ExpandEnvironmentStrings( fileName ); TCHAR expFileName[MAX_PATH]; lstrcpy( expFileName, fileName ); if( SearchPath( NULL, expFileName, NULL, MAX_PATH, fileName, NULL ) == 0 ) return 0; // error... hFile = CreateFile( fileName, GENERIC_READ|FILE_WRITE_ATTRIBUTES, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); if( hFile == INVALID_HANDLE_VALUE ) { hFile = CreateFile( fileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); if( hFile == INVALID_HANDLE_VALUE ) return 0; } else { // Restore the Access Date FILETIME ftAccess; if( GetFileTime( hFile, NULL, &ftAccess, NULL ) ) SetFileTime( hFile, NULL, &ftAccess, NULL ); } WORD magic[6]; DWORD read = 0; if( ! ReadFile( hFile,&magic, sizeof(magic), &read, NULL ) ) return 0; if( read != sizeof(magic) ) return 0; UINT res = 0; switch( magic[0] ) { case IMAGE_DOS_SIGNATURE: res = _ExtractFromExe( hFile, iconIndex, cxIcon, cyIcon, phicon, piconid, maxIcons, flags ); break; case MAGIC_ANI1: // ani cursors are RIFF file of type 'ACON' if( magic[1] == MAGIC_ANI2 && magic[4] == MAGIC_ANI3 && magic[5] == MAGIC_ANI4 ) res = _ExtractFromICO( fileName, iconIndex, cxIcon, cyIcon, phicon, flags ); break; case MAGIC_BMP: res = _ExtractFromBMP( fileName, iconIndex, cxIcon, cyIcon, phicon, flags ); break; case MAGIC_ICON: // icons and cursors format: // reserved : always zero // resourceType : 1 for icons 2 cor cursor. // countIcons : images count // we want countIcons >= 1 if( (magic[1] == MAGIC_ICON || magic[1] == MAGIC_CUR ) && magic[2] >= 1 ) { res = _ExtractFromICO( fileName, iconIndex, cxIcon, cyIcon, phicon, flags ); } break; } return res; }