Пытаюсь добратся до списка иконок в экзешники. Код (Text): HMODULE lib=LoadLibraryW(OpenDialog1->FileName.c_str()); if(lib==NULL){ShowMessage("PE load fail");} HRSRC res; AnsiString str; TStream *sm; for(int i=0;i<100;i++) { str="#"+AnsiString(i); res=FindResource(lib,str.c_str(),RT_ICON); if(res!=NULL) { /*SetLastError(0); HGLOBAL dat=LoadResource(lib,res); void *resmem=LockResource(dat); //Form1->Memo1->Lines->Add(GetLastError()); HANDLE f=CreateFileA("test.ico",GENERIC_WRITE,FILE_SHARE_WRITE,0,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0); DWORD w=0; WriteFile(f,resmem,SizeofResource(lib,res),&w,0); CloseHandle(f); //sm->ReadBuffer(resmem,SizeofResource(lib,res)); break; */ Form1->Memo1->Lines->Add(str+"sz:"+AnsiString(SizeofResource(lib,res)).c_str()); } } Вроде бы по началу все ОК.Результаты того что возвращяет FindResource,совпадает с тем что отображает reshacker.Но прочитать содержимое по указателю от FindResource невыходит.GetLastError() возвращяет ERROR_ACCESS_DENIED.Почему нельзя считать содержимое иконки,по её имени?
Чего то я непонял...Мой инглишь не совсем ок.Что значит "lock"? Использование ф-ции LockResource,или выдергивание данных по указателю FindResource.Но в последнем случае мне не понятно,какого тогда надо это FindResource ???
Иконки редко имеют имена, обычно номер. Пробовали загружать по номерам? Код (Text): res = FindResource(lib, (LPCWSTR) i, (LPCWSTR)RT_ICON); С таким изменением ваш код у меня работает. Кстати, в ресурсах не хранятся заголовки иконок, поэтому писать вот так: Код (Text): HANDLE f=CreateFileA("test.ico",GENERIC_WRITE,FILE_SHARE_WRITE,0,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,0); DWORD w = 0; WriteFile(f, resmem, SizeofResource(lib,res), &w, 0); не корректно. вы не увидите значок. заголовки иконок хранятся отдельно, в ресурсе RT_GROUP_ICON, (и имеют почти идентичную структуру что и в файле ICO)
Загружаем RT_ICON_GROUP, и парсим его, читая иконки на которые он ссылкается, делаем в хидере маленьний фикс, и по порядку дописываем RT_ICON Код (Text): int ResourceKit::ExtractMainIcon(char *IconPath, bool SaveToFile, byte **DataPointer, DWORD *DataSizePointer) { int i; WORD IconNum; DWORD GROUP_ICON_Pointer,IconSize; struct struct_RT_GROUP_ICON *Icons; struct IcoStruct *NewIcons; byte *VirtualIcon; GetResourceInfo(RT_GROUP_ICON, NULL, 0); /* Если в файле нет RT_GROUP_ICON */ if(GetResourceInfo_Result.RvaOffset == 0) return RK_FAIL; GROUP_ICON_Pointer = RVA2RAW(GetResourceInfo_Result.RvaOffset); IconNum = *(PWORD) &VirtualFile[GROUP_ICON_Pointer+4]; Icons = (struct struct_RT_GROUP_ICON*) calloc(IconNum, sizeof(struct struct_RT_GROUP_ICON)); NewIcons = (struct IcoStruct*) calloc(IconNum, sizeof(struct IcoStruct)); for(i=0;i<IconNum;i++) { memcpy(&Icons[i],&VirtualFile[GROUP_ICON_Pointer+6+sizeof(struct struct_RT_GROUP_ICON)*i], sizeof(struct struct_RT_GROUP_ICON)); memcpy(&NewIcons[i], &Icons[i], sizeof(struct IcoStruct)); NewIcons[i].ImageOffset = 0; } IconSize = 6+sizeof(IcoStruct)*IconNum; // DWORD константа, WORD кол-во иконок VirtualIcon = (byte*) malloc(IconSize); *(PWORD) &VirtualIcon[0] = 0x0000; *(PWORD) &VirtualIcon[2] = 0x0001; *(PWORD) &VirtualIcon[4] = IconNum; for(i=0;i<IconNum;i++) { memcpy(&VirtualIcon[6+sizeof(struct IcoStruct)*i], &NewIcons[i], sizeof(struct IcoStruct)); GetResourceInfo(RT_ICON, NULL, Icons[i].RT_ICON_ORD-1); IconSize += GetResourceInfo_Result.RawSize; VirtualIcon = (byte*) realloc(VirtualIcon, IconSize); memcpy(&VirtualIcon[IconSize - GetResourceInfo_Result.RawSize], &VirtualFile[RVA2RAW(GetResourceInfo_Result.RvaOffset)], GetResourceInfo_Result.RawSize); *(PDWORD) &VirtualIcon[6+sizeof(IcoStruct)*(i+1)-4] = IconSize - GetResourceInfo_Result.RawSize; } /* Сохраняем в файл ICO файл, или передаем указатель на массив в памяти */ if(SaveToFile) { SaveMemoryToFile(IconPath, VirtualIcon, IconSize); free(Icons); free(NewIcons); free(VirtualIcon); } else { *DataPointer = VirtualIcon; *DataSizePointer = IconSize; } return RK_SUCCESS; }
И я примером поделюсь (создание файла иконки, без использования RT_GROUP_ICON. такой способ не вполне правильный (правильный способ приведён выше), но юзабельный) Код (Text): QByteArray icon_data; QByteArray icon_bmp; uint bmp_width = 0; uint bmp_height = 0; uint bmp_planes = 0; uint bmp_colors = 0; uint bmp_bpp = 0; // my_object - хранит данные ресурса RT_ICON icon_bmp = my_object->readAll(); bmp_width = my_object->readDword(0x04); bmp_height = my_object->readDword(0x08); bmp_planes = my_object->readWord(0x0C); bmp_bpp = my_object->readWord(0x0E); bmp_colors = my_object->readDword(0x20); struct { ushort sign; ushort type; ushort count; } icon_header; icon_header.sign = 0; icon_header.type = 1; icon_header.count = 1; struct { uchar width; uchar height; uchar colors; uchar reserved; ushort planes; ushort bpp; uint size; uint offset; } icon_item; icon_item.width = bmp_width; icon_item.height = bmp_height >> 1; icon_item.colors = bmp_colors; icon_item.reserved = 0; icon_item.planes = bmp_planes; icon_item.bpp = bmp_bpp; icon_item.size = icon_bmp.size(); icon_item.offset = 0x16; icon_data.append((char*)&icon_header, 0x06); icon_data.append((char*)&icon_item, 0x10); icon_data.append(icon_bmp, icon_item.size); // Далее записываем icon_data в файл, и видим иконку. профит.