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; }
int32 CALLBACK EnumResNameProc( HINSTANCE hModule, const char* lpszType, const char* lpszName, HICON* pIcon ) { HRSRC hRs; HGLOBAL hGl; void* pBuf; if( !( hRs = FindResource( hModule, lpszName, lpszType ) ) ) return true; if( !( hGl = LoadResource( hModule, hRs ) ) ) return true; if( !( pBuf = LockResource( hGl ) ) ) return true; lpszName = MAKEINTRESOURCE( LookupIconIdFromDirectoryEx( (BYTE*)pBuf, TRUE, 16, 16, LR_DEFAULTCOLOR ) ); if( !( hRs = FindResource( hModule, lpszName, RT_ICON ) ) ) return true; if( !( hGl = LoadResource( hModule, hRs ) ) ) return true; if( !( pBuf = LockResource( hGl ) ) ) return true; *pIcon = CreateIconFromResourceEx( (PBYTE)pBuf, SizeofResource( hModule, hRs ), TRUE, 0x00030000, 16, 16, LR_DEFAULTCOLOR ); return !( *pIcon ); }
INT_PTR CALLBACK _about_dlg_proc( HWND hwnd, UINT message, WPARAM wparam, LPARAM lparam ) { _ctl_init ctl_links[ ] = { { DC_HOMEPAGE, IDC_ABOUT_URL1, 0 }, { DC_FORUMPAGE, IDC_ABOUT_URL2, 0 } }; static HICON h_icon; switch ( message ) { case WM_DESTROY : { DestroyIcon(h_icon); return 0L; } break; case WM_CLOSE : { EndDialog(hwnd, 0); return 0L; } break; case WM_COMMAND : { int id = LOWORD(wparam); int code = HIWORD(wparam); int k; if ( code == EN_SETFOCUS ) { SendMessage( (HWND)lparam, EM_SETSEL, -1, 0 ); } if ( id == IDCANCEL || id == IDOK ) { EndDialog(hwnd, 0); } for ( k = 0; k < array_num(ctl_links); k++ ) { if ( id == ctl_links[k].id ) { __execute(ctl_links[k].display); } } } break; case WM_SHOWWINDOW : { SetFocus( GetDlgItem(hwnd, IDC_EDIT_NOTICE) ); SendMessage( GetDlgItem(hwnd, IDC_EDIT_NOTICE), EM_SETSEL, -1, 0 ); } break; case WM_INITDIALOG : { HWND h_notice = GetDlgItem(hwnd, IDC_EDIT_NOTICE); wchar_t s_display[MAX_PATH]; BYTE *res; int size, id_icon; int k = 0; res = _extract_rsrc( IDI_ICON_TRAY, RT_GROUP_ICON, &size ); id_icon = LookupIconIdFromDirectoryEx( res, TRUE, 48, 48, 0 ); res = _extract_rsrc( id_icon, RT_ICON, &size ); h_icon = CreateIconFromResourceEx( res, size, TRUE, 0x00030000, 48, 48, 0 ); SendMessage( GetDlgItem(hwnd, IDC_ICON_MAIN), STM_SETICON, (WPARAM)h_icon, 0 ); { HWND h_title = GetDlgItem( hwnd, IDC_ABOUT1 ); _snwprintf( s_display, sizeof_w(s_display), L"%s %S", DC_NAME, DC_FILE_VER ); SetWindowText( h_title, s_display ); SetWindowText( h_notice, L"This program is free software: you can redistribute " L"it under the terms of the GNU General Public License " L"version 3 as published by the Free Software Foundation.\r\n\r\n" L"Contacts:\r\n" L"[email protected] (PGP key ID 0xC48251EB4F8E4E6E)\r\n\r\n" L"Special thanks to:\r\n" L"Aleksey Bragin and ReactOS Foundation\r\n\r\n" L"Portions of this software:\r\n" L"Copyright \xa9 1998, 2001, 2002 Brian Palmer\r\n" L"Copyright \xa9 2003, Dr Brian Gladman, Worcester, UK\r\n" L"Copyright \xa9 2006, Rik Snel <*****@*****.**>\r\n" L"Copyright \xa9 Vincent Rijmen <*****@*****.**>\r\n" L"Copyright \xa9 Antoon Bosselaers <*****@*****.**>\r\n" L"Copyright \xa9 Paulo Barreto <*****@*****.**>\r\n" L"Copyright \xa9 Tom St Denis <*****@*****.**>\r\n" L"Copyright \xa9 Juergen Schmied and Jon Griffiths\r\n" L"Copyright \xa9 Lynn McGuire\r\n" L"Copyright \xa9 Matthew Skala <*****@*****.**>\r\n" L"Copyright \xa9 Werner Koch\r\n" L"Copyright \xa9 Dag Arne Osvik <*****@*****.**>\r\n" L"Copyright \xa9 Herbert Valerio Riedel <*****@*****.**>\r\n" L"Copyright \xa9 Wei Dai\r\n" L"Copyright \xa9 Ruben Jesus Garcia Hernandez <*****@*****.**>\r\n" L"Copyright \xa9 Serge Trusov <*****@*****.**>" ); SendMessage( h_title, WM_SETFONT, (WPARAM)__font_bold, 0 ); for ( k = 0; k < array_num(ctl_links); k++ ) { HWND h_ctl = GetDlgItem(hwnd, ctl_links[k].id); SetWindowLongPtr( h_ctl, GWL_USERDATA, (LONG_PTR)GetWindowLongPtr( h_ctl, GWL_WNDPROC ) ); SetWindowLongPtr( h_ctl, GWL_WNDPROC, (LONG_PTR)_link_proc ); SetWindowText( h_ctl, ctl_links[k].display ); SendMessage( h_ctl, WM_SETFONT, (WPARAM)__font_link, 0 ); { WINDOWINFO pwi; SIZE size; HDC h_dc = GetDC( h_ctl ); SelectObject( h_dc, __font_link ); GetTextExtentPoint32( h_dc, ctl_links[k].display, d32(wcslen(ctl_links[k].display)), &size ); GetWindowInfo( h_ctl, &pwi ); ScreenToClient( hwnd, pv(&pwi.rcClient) ); MoveWindow( h_ctl, pwi.rcClient.left, pwi.rcClient.top, size.cx, size.cy, TRUE ); ReleaseDC( h_ctl, h_dc ); } } { dc_conf conf; if ( dc_get_conf_flags(&conf) == ST_OK ) { wchar_t *s_using = L"Not supported"; wchar_t *s_inset = L"Not supported"; if ( conf.load_flags & DST_HW_CRYPTO ) { s_using = ( conf.conf_flags & CONF_HW_CRYPTO ? L"Enabled" : L"Disabled" ); if ( conf.load_flags & DST_INTEL_NI ) s_inset = L"Intel® AES Instructions Set (AES-NI)"; if ( conf.load_flags & DST_VIA_PADLOCK ) s_inset = L"The VIA PadLock Advanced Cryptography Engine (ACE)"; } _snwprintf( s_display, sizeof_w(s_display), L"Hardware Cryptography: %s\r\n" L"Instruction Set: %s", s_using, s_inset ); SetWindowText( GetDlgItem(hwnd, IDC_EDIT_CIPHER_INFO), s_display ); EnableWindow( GetDlgItem(hwnd, IDC_EDIT_CIPHER_INFO), conf.load_flags & DST_HW_CRYPTO ); } } } SendMessage( h_notice, EM_SCROLLCARET, 0, 0 ); SetForegroundWindow( hwnd ); return 1L; } break; default: { int rlt = _draw_proc( message, lparam ); if ( rlt != -1 ) { return rlt; } } } return 0L; }
/************************************************************************* * ICO_ExtractIconExW [internal] * * NOTES * nIcons = 0: returns number of Icons in file * * returns * invalid file: -1 * failure:0; * success: number of icons in file (nIcons = 0) or nr of icons retrieved */ static UINT ICO_ExtractIconExW( LPCWSTR lpszExeFileName, HICON * RetPtr, INT nIconIndex, UINT nIcons, UINT cxDesired, UINT cyDesired, UINT *pIconId, UINT flags) { UINT ret = 0; UINT cx1, cx2, cy1, cy2; LPBYTE pData; DWORD sig; HANDLE hFile; UINT16 iconDirCount = 0; //,iconCount = 0; LPBYTE peimage; HANDLE fmapping; DWORD fsizeh,fsizel; WCHAR szExePath[MAX_PATH]; DWORD dwSearchReturn; TRACE("%s, %d, %d %p 0x%08x\n", debugstr_w(lpszExeFileName), nIconIndex, nIcons, pIconId, flags); dwSearchReturn = SearchPathW(NULL, lpszExeFileName, NULL, sizeof(szExePath) / sizeof(szExePath[0]), szExePath, NULL); if ((dwSearchReturn == 0) || (dwSearchReturn > sizeof(szExePath) / sizeof(szExePath[0]))) { WARN("File %s not found or path too long\n", debugstr_w(lpszExeFileName)); return -1; } hFile = CreateFileW(szExePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0); if (hFile == INVALID_HANDLE_VALUE) return ret; fsizel = GetFileSize(hFile,&fsizeh); /* Map the file */ fmapping = CreateFileMappingW(hFile, NULL, PAGE_READONLY | SEC_COMMIT, 0, 0, NULL); CloseHandle(hFile); if (!fmapping) { WARN("CreateFileMapping error %ld\n", GetLastError() ); return 0xFFFFFFFF; } if (!(peimage = MapViewOfFile(fmapping, FILE_MAP_READ, 0, 0, 0))) { WARN("MapViewOfFile error %ld\n", GetLastError() ); CloseHandle(fmapping); return 0xFFFFFFFF; } CloseHandle(fmapping); cx1 = LOWORD(cxDesired); cx2 = HIWORD(cxDesired); cy1 = LOWORD(cyDesired); cy2 = HIWORD(cyDesired); if (pIconId) /* Invalidate first icon identifier */ *pIconId = 0xFFFFFFFF; if (!pIconId) /* if no icon identifier array present use the icon handle array as intermediate storage */ pIconId = (UINT*)RetPtr; sig = USER32_GetResourceTable(peimage, fsizel, &pData); /* ico file or NE exe/dll*/ #if 0 if (sig==IMAGE_OS2_SIGNATURE || sig==1) /* .ICO file */ { BYTE *pCIDir = 0; NE_TYPEINFO *pTInfo = (NE_TYPEINFO*)(pData + 2); NE_NAMEINFO *pIconStorage = NULL; NE_NAMEINFO *pIconDir = NULL; LPicoICONDIR lpiID = NULL; TRACE("-- OS2/icon Signature (0x%08lx)\n", sig); if (pData == (BYTE*)-1) { pCIDir = ICO_GetIconDirectory(peimage, &lpiID, &uSize); /* check for .ICO file */ if (pCIDir) { iconDirCount = 1; iconCount = lpiID->idCount; TRACE("-- icon found %p 0x%08lx 0x%08x 0x%08x\n", pCIDir, uSize, iconDirCount, iconCount); } } else while (pTInfo->type_id && !(pIconStorage && pIconDir)) { if (pTInfo->type_id == NE_RSCTYPE_GROUP_ICON) /* find icon directory and icon repository */ { iconDirCount = pTInfo->count; pIconDir = ((NE_NAMEINFO*)(pTInfo + 1)); TRACE("\tfound directory - %i icon families\n", iconDirCount); } if (pTInfo->type_id == NE_RSCTYPE_ICON) { iconCount = pTInfo->count; pIconStorage = ((NE_NAMEINFO*)(pTInfo + 1)); TRACE("\ttotal icons - %i\n", iconCount); } pTInfo = (NE_TYPEINFO *)((char*)(pTInfo+1)+pTInfo->count*sizeof(NE_NAMEINFO)); } if ((pIconStorage && pIconDir) || lpiID) /* load resources and create icons */ { if (nIcons == 0) { ret = iconDirCount; if (lpiID && pCIDir) /* *.ico file, deallocate heap pointer*/ HeapFree(GetProcessHeap(), 0, pCIDir); } else if (nIconIndex < iconDirCount) { UINT16 i, icon; if (nIcons > iconDirCount - nIconIndex) nIcons = iconDirCount - nIconIndex; for (i = 0; i < nIcons; i++) { /* .ICO files have only one icon directory */ if (lpiID == NULL) /* not *.ico */ pCIDir = USER32_LoadResource(peimage, pIconDir + i + nIconIndex, *(WORD*)pData, &uSize); pIconId[i] = LookupIconIdFromDirectoryEx(pCIDir, TRUE, (i & 1) ? cx2 : cx1, (i & 1) ? cy2 : cy1, flags); } if (lpiID && pCIDir) /* *.ico file, deallocate heap pointer*/ HeapFree(GetProcessHeap(), 0, pCIDir); for (icon = 0; icon < nIcons; icon++) { pCIDir = NULL; if (lpiID) pCIDir = ICO_LoadIcon(peimage, lpiID->idEntries + (int)pIconId[icon], &uSize); else for (i = 0; i < iconCount; i++) if (pIconStorage[i].id == ((int)pIconId[icon] | 0x8000) ) pCIDir = USER32_LoadResource(peimage, pIconStorage + i, *(WORD*)pData, &uSize); if (pCIDir) RetPtr[icon] = (HICON)CreateIconFromResourceEx(pCIDir, uSize, TRUE, 0x00030000, (icon & 1) ? cx2 : cx1, (icon & 1) ? cy2 : cy1, flags); else RetPtr[icon] = 0; } ret = icon; /* return number of retrieved icons */ } } } /* end ico file */ /* exe/dll */ else if( sig == IMAGE_NT_SIGNATURE ) #endif if( sig == IMAGE_NT_SIGNATURE ) { LPBYTE idata,igdata; PIMAGE_DOS_HEADER dheader; PIMAGE_NT_HEADERS pe_header; PIMAGE_SECTION_HEADER pe_sections; const IMAGE_RESOURCE_DIRECTORY *rootresdir,*iconresdir,*icongroupresdir; const IMAGE_RESOURCE_DATA_ENTRY *idataent,*igdataent; const IMAGE_RESOURCE_DIRECTORY_ENTRY *xresent; UINT i, j; dheader = (PIMAGE_DOS_HEADER)peimage; pe_header = (PIMAGE_NT_HEADERS)(peimage+dheader->e_lfanew); /* it is a pe header, USER32_GetResourceTable checked that */ pe_sections = (PIMAGE_SECTION_HEADER)(((char*)pe_header) + sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER) + pe_header->FileHeader.SizeOfOptionalHeader); rootresdir = NULL; /* search for the root resource directory */ for (i=0;i<pe_header->FileHeader.NumberOfSections;i++) { if (pe_sections[i].Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA) continue; if (fsizel < pe_sections[i].PointerToRawData+pe_sections[i].SizeOfRawData) { FIXME("File %s too short (section is at %ld bytes, real size is %ld)\n", debugstr_w(lpszExeFileName), pe_sections[i].PointerToRawData+pe_sections[i].SizeOfRawData, fsizel ); goto end; } /* FIXME: doesn't work when the resources are not in a separate section */ if (pe_sections[i].VirtualAddress == pe_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress) { rootresdir = (PIMAGE_RESOURCE_DIRECTORY)(peimage+pe_sections[i].PointerToRawData); break; } } if (!rootresdir) { WARN("haven't found section for resource directory.\n"); goto end; /* failure */ } /* search for the group icon directory */ if (!(icongroupresdir = find_entry_by_id(rootresdir, LOWORD(RT_GROUP_ICON), rootresdir))) { WARN("No Icongroupresourcedirectory!\n"); goto end; /* failure */ } iconDirCount = icongroupresdir->NumberOfNamedEntries + icongroupresdir->NumberOfIdEntries; /* only number of icons requested */ if( !pIconId ) { ret = iconDirCount; goto end; /* success */ } if( nIconIndex < 0 ) { /* search resource id */ int n = 0; int iId = abs(nIconIndex); const IMAGE_RESOURCE_DIRECTORY_ENTRY* xprdeTmp = (const IMAGE_RESOURCE_DIRECTORY_ENTRY*)(icongroupresdir+1); while(n<iconDirCount && xprdeTmp) { if(xprdeTmp->Id == iId) { nIconIndex = n; break; } n++; xprdeTmp++; } if (nIconIndex < 0) { WARN("resource id %d not found\n", iId); goto end; /* failure */ } } else { /* check nIconIndex to be in range */ if (nIconIndex >= iconDirCount) { WARN("nIconIndex %d is larger than iconDirCount %d\n",nIconIndex,iconDirCount); goto end; /* failure */ } } /* assure we don't get too much */ if( nIcons > iconDirCount - nIconIndex ) nIcons = iconDirCount - nIconIndex; /* starting from specified index */ xresent = (const IMAGE_RESOURCE_DIRECTORY_ENTRY*)(icongroupresdir+1) + nIconIndex; for (i=0; i < nIcons; i++,xresent++) { const IMAGE_RESOURCE_DIRECTORY *resdir; /* go down this resource entry, name */ resdir = (const IMAGE_RESOURCE_DIRECTORY*)((const char *)rootresdir+(xresent->OffsetToDirectory)); /* default language (0) */ resdir = find_entry_default(resdir,rootresdir); igdataent = (const IMAGE_RESOURCE_DATA_ENTRY*)resdir; /* lookup address in mapped image for virtual address */ igdata = NULL; for (j=0;j<pe_header->FileHeader.NumberOfSections;j++) { if (igdataent->OffsetToData < pe_sections[j].VirtualAddress) continue; if (igdataent->OffsetToData+igdataent->Size > pe_sections[j].VirtualAddress+pe_sections[j].SizeOfRawData) continue; if (igdataent->OffsetToData-pe_sections[j].VirtualAddress+pe_sections[j].PointerToRawData+igdataent->Size > fsizel) { FIXME("overflow in PE lookup (%s has len %ld, have offset %ld), short file?\n", debugstr_w(lpszExeFileName), fsizel, igdataent->OffsetToData - pe_sections[j].VirtualAddress + pe_sections[j].PointerToRawData + igdataent->Size); goto end; /* failure */ } igdata = peimage+(igdataent->OffsetToData-pe_sections[j].VirtualAddress+pe_sections[j].PointerToRawData); } if (!igdata) { FIXME("no matching real address for icongroup!\n"); goto end; /* failure */ } pIconId[i] = LookupIconIdFromDirectoryEx(igdata, TRUE, cx1, cy1, flags); if (cx2 && cy2) pIconId[++i] = LookupIconIdFromDirectoryEx(igdata, TRUE, cx2, cy2, flags); } if (!(iconresdir=find_entry_by_id(rootresdir,LOWORD(RT_ICON),rootresdir))) { WARN("No Iconresourcedirectory!\n"); goto end; /* failure */ } for (i=0; i<nIcons; i++) { const IMAGE_RESOURCE_DIRECTORY *xresdir; xresdir = find_entry_by_id(iconresdir, LOWORD(pIconId[i]), rootresdir); if (!xresdir) { WARN("icon entry %d not found\n", LOWORD(pIconId[i])); RetPtr[i]=0; continue; } xresdir = find_entry_default(xresdir, rootresdir); if (!xresdir) { WARN("icon entry %d not found\n", LOWORD(pIconId[i])); RetPtr[i]=0; continue; } idataent = (const IMAGE_RESOURCE_DATA_ENTRY*)xresdir; idata = NULL; /* map virtual to address in image */ for (j=0;j<pe_header->FileHeader.NumberOfSections;j++) { if (idataent->OffsetToData < pe_sections[j].VirtualAddress) continue; if (idataent->OffsetToData+idataent->Size > pe_sections[j].VirtualAddress+pe_sections[j].SizeOfRawData) continue; idata = peimage+(idataent->OffsetToData-pe_sections[j].VirtualAddress+pe_sections[j].PointerToRawData); } if (!idata) { WARN("no matching real address found for icondata!\n"); RetPtr[i]=0; continue; } RetPtr[i] = CreateIconFromResourceEx(idata, idataent->Size, TRUE, 0x00030000, cx1, cy1, flags); if (cx2 && cy2) RetPtr[++i] = CreateIconFromResourceEx(idata, idataent->Size, TRUE, 0x00030000, cx2, cy2, flags); } ret = i; /* return number of retrieved icons */ } /* if(sig == IMAGE_NT_SIGNATURE) */ end: UnmapViewOfFile(peimage); /* success */ return ret; }
bool windows_tray_notification::create_tray_icon() { // getting handle to a 32x32 icon, contained in "WESNOTH_ICON" icon group of wesnoth.exe resources const HMODULE wesnoth_exe = GetModuleHandle(NULL); if (wesnoth_exe == NULL) { return false; } const HRSRC group_icon_info = FindResource(wesnoth_exe, L"WESNOTH_ICON", RT_GROUP_ICON); if (group_icon_info == NULL) { return false; } HGLOBAL hGlobal = LoadResource(wesnoth_exe, group_icon_info); if (hGlobal == NULL) { return false; } const PBYTE group_icon_res = static_cast<PBYTE>(LockResource(hGlobal)); if (group_icon_res == NULL) { return false; } const int nID = LookupIconIdFromDirectoryEx(group_icon_res, TRUE, 32, 32, LR_DEFAULTCOLOR); if (nID == 0) { return false; } const HRSRC icon_info = FindResource(wesnoth_exe, MAKEINTRESOURCE(nID), MAKEINTRESOURCE(3)); if (icon_info == NULL) { return false; } hGlobal = LoadResource(wesnoth_exe, icon_info); if (hGlobal == NULL) { return false; } const PBYTE icon_res = static_cast<PBYTE>(LockResource(hGlobal)); if (icon_res == NULL) { return false; } const HICON icon = CreateIconFromResource(icon_res, SizeofResource(wesnoth_exe, icon_info), TRUE, 0x00030000); if (icon == NULL) { return false; } const HWND window = get_window_hanlde(); if (window == NULL) { return false; } // filling notification structure nid = new NOTIFYICONDATA; memset(nid, 0, sizeof(&nid)); nid->cbSize = NOTIFYICONDATA_V2_SIZE; nid->hWnd = window; nid->uFlags = NIF_ICON | NIF_TIP | NIF_MESSAGE; nid->dwInfoFlags = NIIF_USER; nid->uVersion = NOTIFYICON_VERSION; nid->uCallbackMessage = WM_TRAYNOTIFY; nid->uID = ICON_ID; nid->hIcon = icon; #if _WIN32_WINNT >= 0x600 nid->hBalloonIcon = icon; #endif lstrcpy(nid->szTip, L"The Battle For Wesnoth"); // creating icon notification return Shell_NotifyIcon(NIM_ADD, nid) != FALSE; }
/************************************************************************* * ICO_ExtractIconExW [internal] * * NOTES * nIcons = 0: returns number of Icons in file * * returns * invalid file: -1 * failure:0; * success: number of icons in file (nIcons = 0) or nr of icons retrieved */ static UINT ICO_ExtractIconExW( LPCWSTR lpszExeFileName, HICON * RetPtr, INT nIconIndex, UINT nIcons, UINT cxDesired, UINT cyDesired, UINT *pIconId, UINT flags) { UINT ret = 0; UINT cx1, cx2, cy1, cy2; LPBYTE pData; DWORD sig; HANDLE hFile; UINT16 iconDirCount = 0, iconCount = 0; LPBYTE peimage; HANDLE fmapping; DWORD fsizeh,fsizel; WCHAR szExePath[MAX_PATH]; DWORD dwSearchReturn; TRACE("%s, %d, %d %p 0x%08x\n", debugstr_w(lpszExeFileName), nIconIndex, nIcons, pIconId, flags); dwSearchReturn = SearchPathW(NULL, lpszExeFileName, NULL, sizeof(szExePath) / sizeof(szExePath[0]), szExePath, NULL); if ((dwSearchReturn == 0) || (dwSearchReturn > sizeof(szExePath) / sizeof(szExePath[0]))) { WARN("File %s not found or path too long\n", debugstr_w(lpszExeFileName)); return -1; } hFile = CreateFileW(szExePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0); if (hFile == INVALID_HANDLE_VALUE) return ret; fsizel = GetFileSize(hFile,&fsizeh); /* Map the file */ fmapping = CreateFileMappingW(hFile, NULL, PAGE_READONLY | SEC_COMMIT, 0, 0, NULL); CloseHandle(hFile); if (!fmapping) { WARN("CreateFileMapping error %ld\n", GetLastError() ); return 0xFFFFFFFF; } if (!(peimage = MapViewOfFile(fmapping, FILE_MAP_READ, 0, 0, 0))) { WARN("MapViewOfFile error %ld\n", GetLastError() ); CloseHandle(fmapping); return 0xFFFFFFFF; } CloseHandle(fmapping); cx1 = LOWORD(cxDesired); cx2 = HIWORD(cxDesired); cy1 = LOWORD(cyDesired); cy2 = HIWORD(cyDesired); if (pIconId) /* Invalidate first icon identifier */ *pIconId = 0xFFFFFFFF; if (!pIconId) /* if no icon identifier array present use the icon handle array as intermediate storage */ pIconId = (UINT*)RetPtr; sig = USER32_GetResourceTable(peimage, fsizel, &pData); #ifdef WINE /* ico file or NE exe/dll*/ if (sig==IMAGE_OS2_SIGNATURE || sig==1) /* .ICO file */ { BYTE *pCIDir = 0; NE_TYPEINFO *pTInfo = (NE_TYPEINFO*)(pData + 2); NE_NAMEINFO *pIconStorage = NULL; NE_NAMEINFO *pIconDir = NULL; LPicoICONDIR lpiID = NULL; ULONG uSize = 0; TRACE("-- OS2/icon Signature (0x%08x)\n", sig); if (pData == (BYTE*)-1) { pCIDir = ICO_GetIconDirectory(peimage, &lpiID, &uSize); /* check for .ICO file */ if (pCIDir) { iconDirCount = 1; iconCount = lpiID->idCount; TRACE("-- icon found %p 0x%08x 0x%08x 0x%08x\n", pCIDir, uSize, iconDirCount, iconCount); } } else while (pTInfo->type_id && !(pIconStorage && pIconDir)) { if (pTInfo->type_id == NE_RSCTYPE_GROUP_ICON) /* find icon directory and icon repository */ { iconDirCount = pTInfo->count; pIconDir = ((NE_NAMEINFO*)(pTInfo + 1)); TRACE("\tfound directory - %i icon families\n", iconDirCount); } if (pTInfo->type_id == NE_RSCTYPE_ICON) { iconCount = pTInfo->count; pIconStorage = ((NE_NAMEINFO*)(pTInfo + 1)); TRACE("\ttotal icons - %i\n", iconCount); } pTInfo = (NE_TYPEINFO *)((char*)(pTInfo+1)+pTInfo->count*sizeof(NE_NAMEINFO)); } if ((pIconStorage && pIconDir) || lpiID) /* load resources and create icons */ { if (nIcons == 0) { ret = iconDirCount; if (lpiID) /* *.ico file, deallocate heap pointer*/ HeapFree(GetProcessHeap(), 0, pCIDir); } else if (nIconIndex < iconDirCount) { UINT16 i, icon; if (nIcons > iconDirCount - nIconIndex) nIcons = iconDirCount - nIconIndex; for (i = 0; i < nIcons; i++) { /* .ICO files have only one icon directory */ if (lpiID == NULL) /* not *.ico */ pCIDir = USER32_LoadResource(peimage, pIconDir + i + nIconIndex, *(WORD*)pData, &uSize); pIconId[i] = LookupIconIdFromDirectoryEx(pCIDir, TRUE, cx1, cy1, flags); if (cx2 && cy2) pIconId[++i] = LookupIconIdFromDirectoryEx(pCIDir, TRUE, cx2, cy2, flags); } if (lpiID) /* *.ico file, deallocate heap pointer*/ HeapFree(GetProcessHeap(), 0, pCIDir); for (icon = 0; icon < nIcons; icon++) { pCIDir = NULL; if (lpiID) pCIDir = ICO_LoadIcon(peimage, lpiID->idEntries + (int)pIconId[icon], &uSize); else for (i = 0; i < iconCount; i++) if (pIconStorage[i].id == ((int)pIconId[icon] | 0x8000) ) pCIDir = USER32_LoadResource(peimage, pIconStorage + i, *(WORD*)pData, &uSize); if (pCIDir) { RetPtr[icon] = CreateIconFromResourceEx(pCIDir, uSize, TRUE, 0x00030000, cx1, cy1, flags); if (cx2 && cy2) RetPtr[++icon] = CreateIconFromResourceEx(pCIDir, uSize, TRUE, 0x00030000, cx2, cy2, flags); } else RetPtr[icon] = 0; } ret = icon; /* return number of retrieved icons */ } } } #else if (sig == 1 || sig == 2) /* .ICO or .CUR file */ { TRACE("-- icon Signature (0x%08x)\n", sig); if (pData == (BYTE*)-1) { INT cx[2] = {cx1, cx2}, cy[2] = {cy1, cy2}; INT index; for(index = 0; index < 2; index++) { DWORD dataOffset; LPBYTE imageData; POINT hotSpot; LPICONIMAGE entry; dataOffset = get_best_icon_file_offset(peimage, fsizel, cx[index], cy[index], sig == 1, flags, sig == 1 ? NULL : &hotSpot); if (dataOffset) { HICON icon; WORD *cursorData = NULL; imageData = peimage + dataOffset; entry = (LPICONIMAGE)(imageData); if(sig == 2) { /* we need to prepend the bitmap data with hot spots for CreateIconFromResourceEx */ cursorData = HeapAlloc(GetProcessHeap(), 0, entry->icHeader.biSizeImage + 2 * sizeof(WORD)); if(!cursorData) continue; cursorData[0] = hotSpot.x; cursorData[1] = hotSpot.y; memcpy(cursorData + 2, imageData, entry->icHeader.biSizeImage); imageData = (LPBYTE)cursorData; } icon = CreateIconFromResourceEx(imageData, entry->icHeader.biSizeImage, sig == 1, 0x00030000, cx[index], cy[index], flags); if (icon) { RetPtr[index] = icon; iconCount = 1; } if(cursorData != NULL) HeapFree(GetProcessHeap(), 0, cursorData); } } } ret = iconCount; /* return number of retrieved icons */ } #endif /* end ico file */ /* exe/dll */ else if( sig == IMAGE_NT_SIGNATURE ) { BYTE *idata, *igdata; const IMAGE_RESOURCE_DIRECTORY *rootresdir, *iconresdir, *icongroupresdir; const IMAGE_RESOURCE_DATA_ENTRY *idataent, *igdataent; const IMAGE_RESOURCE_DIRECTORY_ENTRY *xresent; ULONG size; UINT i; rootresdir = RtlImageDirectoryEntryToData((HMODULE)peimage, FALSE, IMAGE_DIRECTORY_ENTRY_RESOURCE, &size); if (!rootresdir) { WARN("haven't found section for resource directory.\n"); goto end; } /* search for the group icon directory */ if (!(icongroupresdir = find_entry_by_id(rootresdir, LOWORD(RT_GROUP_ICON), rootresdir))) { WARN("No Icongroupresourcedirectory!\n"); goto end; /* failure */ } iconDirCount = icongroupresdir->NumberOfNamedEntries + icongroupresdir->NumberOfIdEntries; /* only number of icons requested */ if( !pIconId ) { ret = iconDirCount; goto end; /* success */ } if( nIconIndex < 0 ) { /* search resource id */ int n = 0; int iId = abs(nIconIndex); const IMAGE_RESOURCE_DIRECTORY_ENTRY* xprdeTmp = (const IMAGE_RESOURCE_DIRECTORY_ENTRY*)(icongroupresdir+1); while(n<iconDirCount && xprdeTmp) { if(xprdeTmp->Id == iId) { nIconIndex = n; break; } n++; xprdeTmp++; } if (nIconIndex < 0) { WARN("resource id %d not found\n", iId); goto end; /* failure */ } } else { /* check nIconIndex to be in range */ if (nIconIndex >= iconDirCount) { WARN("nIconIndex %d is larger than iconDirCount %d\n",nIconIndex,iconDirCount); goto end; /* failure */ } } /* assure we don't get too much */ if( nIcons > iconDirCount - nIconIndex ) nIcons = iconDirCount - nIconIndex; /* starting from specified index */ xresent = (const IMAGE_RESOURCE_DIRECTORY_ENTRY*)(icongroupresdir+1) + nIconIndex; for (i=0; i < nIcons; i++,xresent++) { const IMAGE_RESOURCE_DIRECTORY *resdir; /* go down this resource entry, name */ resdir = (const IMAGE_RESOURCE_DIRECTORY *)((const char *)rootresdir + xresent->OffsetToDirectory); /* default language (0) */ resdir = find_entry_default(resdir,rootresdir); igdataent = (const IMAGE_RESOURCE_DATA_ENTRY*)resdir; /* lookup address in mapped image for virtual address */ igdata = RtlImageRvaToVa(RtlImageNtHeader((HMODULE)peimage), (HMODULE)peimage, igdataent->OffsetToData, NULL); if (!igdata) { FIXME("no matching real address for icongroup!\n"); goto end; /* failure */ } pIconId[i] = LookupIconIdFromDirectoryEx(igdata, TRUE, cx1, cy1, flags); if (cx2 && cy2) pIconId[++i] = LookupIconIdFromDirectoryEx(igdata, TRUE, cx2, cy2, flags); } if (!(iconresdir=find_entry_by_id(rootresdir,LOWORD(RT_ICON),rootresdir))) { WARN("No Iconresourcedirectory!\n"); goto end; /* failure */ } for (i=0; i<nIcons; i++) { const IMAGE_RESOURCE_DIRECTORY *xresdir; xresdir = find_entry_by_id(iconresdir, LOWORD(pIconId[i]), rootresdir); if( !xresdir ) { WARN("icon entry %d not found\n", LOWORD(pIconId[i])); RetPtr[i]=0; continue; } xresdir = find_entry_default(xresdir, rootresdir); idataent = (const IMAGE_RESOURCE_DATA_ENTRY*)xresdir; idata = RtlImageRvaToVa(RtlImageNtHeader((HMODULE)peimage), (HMODULE)peimage, idataent->OffsetToData, NULL); if (!idata) { WARN("no matching real address found for icondata!\n"); RetPtr[i]=0; continue; } RetPtr[i] = CreateIconFromResourceEx(idata, idataent->Size, TRUE, 0x00030000, cx1, cy1, flags); if (cx2 && cy2) RetPtr[++i] = CreateIconFromResourceEx(idata, idataent->Size, TRUE, 0x00030000, cx2, cy2, flags); } ret = i; /* return number of retrieved icons */ } /* if(sig == IMAGE_NT_SIGNATURE) */ end: UnmapViewOfFile(peimage); /* success */ return ret; }
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; }