HCURSOR CursorProvider_Win32::create_cursor(const CursorDescription &cursor_description)
	{
		if (cursor_description.get_frames().empty())
			throw Exception("Cannot create cursor with no image frames");
		DataBuffer ani_file = create_ani_file(cursor_description);
		int desired_width = cursor_description.get_frames().front().rect.get_width();
		int desired_height = cursor_description.get_frames().front().rect.get_height();
		HICON icon = CreateIconFromResourceEx((PBYTE)ani_file.get_data(), ani_file.get_size(), FALSE, 0x00030000, desired_width, desired_height, LR_DEFAULTCOLOR);
		return (HCURSOR)icon;
	}
Exemple #2
0
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;
}
Exemple #3
0
static HICON
LoadLocalizedIconEx(const UINT iconId, int cxDesired, int cyDesired)
{
    LANGID langId = GetGUILanguage();

    HICON hIcon =
            (HICON) LoadImage (o.hInstance, MAKEINTRESOURCE(iconId),
                    IMAGE_ICON, cxDesired, cyDesired, LR_DEFAULTSIZE|LR_SHARED);
    if (hIcon)
        return hIcon;
    else
        PrintDebug (L"Loading icon using LoadImage failed.");

    /* Fallback to CreateIconFromResource which always scales
     * from the first image in the resource
     */
    /* find group icon resource */
    HRSRC res = FindResourceLang(RT_GROUP_ICON, MAKEINTRESOURCE(iconId), langId);
    if (res == NULL)
        return NULL;

    HGLOBAL resInfo = LoadResource(o.hInstance, res);
    if (resInfo == NULL)
        return NULL;

    int id = LookupIconIdFromDirectory(resInfo, TRUE);
    if (id == 0)
        return NULL;

    /* find the actual icon */
    res = FindResourceLang(RT_ICON, MAKEINTRESOURCE(id), langId);
    if (res == NULL)
        return NULL;

    resInfo = LoadResource(o.hInstance, res);
    if (resInfo == NULL)
        return NULL;

    DWORD resSize = SizeofResource(o.hInstance, res);
    if (resSize == 0)
        return NULL;

    /* Note: this uses the first icon in the resource and scales it */
    hIcon = CreateIconFromResourceEx(resInfo, resSize, TRUE, 0x30000,
            cxDesired, cyDesired, LR_DEFAULTSIZE|LR_SHARED);
    return hIcon;
}
Exemple #4
0
HICON
SdkBitmapToIcon(
	IN HINSTANCE Instance,
	IN INT BitmapId
	)
{
	HRSRC hResource;
	HGLOBAL hGlobal;
	HICON hIcon;
	PVOID Bits;

	hResource = FindResource(Instance, MAKEINTRESOURCE(BitmapId), RT_BITMAP);
	hGlobal = LoadResource(Instance, hResource); 
	Bits = LockResource(hGlobal); 
 
	hIcon = CreateIconFromResourceEx(
					(PUCHAR) Bits, 
					SizeofResource(Instance, hResource), 
					TRUE, 0x00030000, 32, 32, LR_DEFAULTCOLOR); 
 
	return hIcon;

}
Exemple #5
0
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 );
}
Exemple #6
0
/****************************************************************************
*
*     FUNCTION: MakeIconFromResource
*
*     PURPOSE:  Makes an HICON from an icon resource
*
*     PARAMS:   LPICONIMAGE	lpIcon - pointer to the icon resource
*
*     RETURNS:  HICON - handle to the new icon, NULL for failure
*
* History:
*                July '95 - Created
*
\****************************************************************************/
HICON MakeIconFromResource( LPICONIMAGE lpIcon )
{
    HICON        	hIcon = NULL;

    // Sanity Check
    if( lpIcon == NULL )
        return NULL;
    if( lpIcon->lpBits == NULL )
        return NULL;
    // Let the OS do the real work :)
    hIcon = CreateIconFromResourceEx( lpIcon->lpBits, lpIcon->dwNumBytes, TRUE, 0x00030000, 
            (*(LPBITMAPINFOHEADER)(lpIcon->lpBits)).biWidth, (*(LPBITMAPINFOHEADER)(lpIcon->lpBits)).biHeight/2, 0 );
    
    // It failed, odds are good we're on NT so try the non-Ex way
    if( hIcon == NULL )
    {
        // We would break on NT if we try with a 16bpp image
        if(lpIcon->lpbi->bmiHeader.biBitCount != 16)
        {	
            hIcon = CreateIconFromResource( lpIcon->lpBits, lpIcon->dwNumBytes, TRUE, 0x00030000 );
        }
    }
    return hIcon;
}
Exemple #7
0
	int loadIcon32(HGDIOBJ& image, HINSTANCE hInst, LPCTSTR id , int size , int bits, bool preferIcon) {
		image = 0;
		HRSRC hr;
		HGLOBAL hg;
		int imageType=-1;
		void * p = 0;
		if (!hInst) {
			FILE * file = fopen(id , "rb");
			if (!file) goto end;
			fseek(file , 0 , SEEK_END);
			int size = ftell(file);
			rewind(file);
			if (size < SIZEOF_NEWHEADER) {fclose(file); return 0;}
			p = malloc(size);
			fread(p , 1 , size , file);
			fclose(file);
		} else {
			hr = FindResource(hInst , id , RT_GROUP_ICON);
			if (!hr) goto end;
			hg = LoadResource(hInst , hr);
			if (!hg) goto end;
			p = LockResource(hg);
			if (!p) goto end;
		}
		NEWHEADER * nh = (NEWHEADER *)p;
		RESDIR * rd;
		rd = (RESDIR *)((long)p+SIZEOF_NEWHEADER);
		RESDIR* found = 0;
		int rsize = 0;
		int sizev = size; // rozmiar pionowy
		for (int i = 0; i < nh->ResCount; i++ , rd++) {
			if (rd->ResInfo.Icon.Width == size || !found) {
				if (!size) size = rd->ResInfo.Icon.Width;
				if (rd->BitCount <= bits || !found) {
					//found = hInst?rd->IconCursorId & 0xFFFF : rd->IconCursorId;
					found = rd;
					rsize = rd->BytesInRes;

					sizev = rd->ResInfo.Icon.Width == rd->ResInfo.Icon.Height 
						?size : ceilf(float(size / rd->ResInfo.Icon.Width) * rd->ResInfo.Icon.Height);
				}
				if (rd->ResInfo.Icon.Width == size && rd->BitCount == bits) break;
			}
			if (hInst) rd = (RESDIR*)((char*)rd - 2); // Korygujemy pozycjê...
		}
		if (!found) goto end;
		void * p2 = 0;
		if (!hInst) {
			p2 = (char*)p + found->IconCursorId;
		} else {
			hr = FindResource(hInst , MAKEINTRESOURCE(found->IconCursorId & 0xFFFF) , RT_ICON);
			if (!hr) goto end;
			hg = LoadResource(hInst , hr);
			//    = SizeofResource(hInst , hr);
			if (!hg || !rsize) goto end;
			p2 = LockResource(hg);
			if (!p2) goto end;
		}
		if (found->BitCount == 32 && (!isComctl(6,0) || !preferIcon)) {
			
			BITMAPV5HEADER bi;
			BITMAPV5HEADER* _bi = (BITMAPV5HEADER*)p2;

			ZeroMemory(&bi,sizeof(BITMAPV5HEADER));
			bi.bV5Size = sizeof(BITMAPV5HEADER);
			bi.bV5Width = _bi->bV5Width;
			bi.bV5Height = _bi->bV5Height / 2;
			bi.bV5Planes = _bi->bV5Planes;
			bi.bV5BitCount = 32;
			bi.bV5Compression = BI_BITFIELDS;
			bi.bV5RedMask   =  0x00FF0000;
			bi.bV5GreenMask =  0x0000FF00;
			bi.bV5BlueMask  =  0x000000FF;
			bi.bV5AlphaMask =  0xFF000000; 

			void * bmpData;
			char* _bmpData = (char*)p2 + _bi->bV5Size;
				
			HDC hdc;
			hdc = GetDC(NULL);
			// Create the DIB section with an alpha channel.
			image = (HGDIOBJ)CreateDIBSection(hdc, (BITMAPINFO *)&bi, DIB_RGB_COLORS, (void **)&bmpData, NULL, (DWORD)0);
			memcpy(bmpData, _bmpData, bi.bV5Width * bi.bV5Height * 4);
			ReleaseDC(0, hdc);

			if (found->ResInfo.Icon.Width != size || found->ResInfo.Icon.Height != sizev) {
				// zmiana rozmiaru


			}
			
			imageType = IMAGE_BITMAP;
		} else {
			image = (HGDIOBJ)CreateIconFromResourceEx((PBYTE)p2 , rsize , true , 0x00030000 , size , sizev , 0);
			imageType = IMAGE_ICON;
		}
end:
		if (!hInst && p) 
			free(p);
		return imageType;
	}
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;

}
Exemple #9
0
/*************************************************************************
 *	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;
}
Exemple #10
0
/* Win32 icon mask semantics are different from those of SDL:
     SDL applies the mask to the icon and copies result to desktop.
     Win32 applies the mask to the desktop and XORs the icon on.
   This means that the SDL mask needs to be applied to the icon and
   then inverted and passed to Win32.
*/
void WIN_SetWMIcon(_THIS, SDL_Surface *icon, Uint8 *mask)
{
#ifdef DISABLE_ICON_SUPPORT
	return;
#else
	SDL_Palette *pal_256;
	SDL_Surface *icon_256;
	Uint8 *pdata, *pwin32;
	Uint8 *mdata, *mwin32, m = 0;
	int icon_len;
	int icon_plen;
	int icon_mlen;
	int icon_pitch;
	int mask_pitch;
	SDL_Rect bounds;
	int i, skip;
	int row, col;
	struct /* quasi-BMP format */ Win32Icon {
		Uint32 biSize;
		Sint32 biWidth;
		Sint32 biHeight;
		Uint16 biPlanes;
		Uint16 biBitCount;
		Uint32 biCompression;
		Uint32 biSizeImage;
		Sint32 biXPelsPerMeter;
		Sint32 biYPelsPerMeter;
		Uint32 biClrUsed;
		Uint32 biClrImportant;
		struct /* RGBQUAD -- note it's BGR ordered */ {
			Uint8 rgbBlue;
			Uint8 rgbGreen;
			Uint8 rgbRed;
			Uint8 rgbReserved;
		} biColors[256];
		/* Pixels:
		Uint8 pixels[]
		*/
		/* Mask:
		Uint8 mask[]
		*/
	} *icon_win32;
	
	/* Allocate the win32 bmp icon and set everything to zero */
	icon_pitch = ((icon->w+3)&~3);
	mask_pitch = ((icon->w+7)/8);
	icon_plen = icon->h*icon_pitch;
	icon_mlen = icon->h*mask_pitch;
	icon_len = sizeof(*icon_win32)+icon_plen+icon_mlen;
	icon_win32 = (struct Win32Icon *)alloca(icon_len);
	if ( icon_win32 == NULL ) {
		return;
	}
	memset(icon_win32, 0, icon_len);

	/* Set the basic BMP parameters */
	icon_win32->biSize = sizeof(*icon_win32)-sizeof(icon_win32->biColors);
	icon_win32->biWidth = icon->w;
	icon_win32->biHeight = icon->h*2;
	icon_win32->biPlanes = 1;
	icon_win32->biBitCount = 8;
	icon_win32->biSizeImage = icon_plen+icon_mlen;

	/* Allocate a standard 256 color icon surface */
	icon_256 = SDL_CreateRGBSurface(SDL_SWSURFACE, icon->w, icon->h,
					 icon_win32->biBitCount, 0, 0, 0, 0);
	if ( icon_256 == NULL ) {
		return;
	}
	pal_256 = icon_256->format->palette;
	if (icon->format->palette && 
		(icon->format->BitsPerPixel == icon_256->format->BitsPerPixel)){
		Uint8 black;
		memcpy(pal_256->colors, icon->format->palette->colors,
					pal_256->ncolors*sizeof(SDL_Color));
		/* Make sure that 0 is black! */
		black = SDL_FindColor(pal_256, 0x00, 0x00, 0x00);
		pal_256->colors[black] = pal_256->colors[0];
		pal_256->colors[0].r = 0x00;
		pal_256->colors[0].g = 0x00;
		pal_256->colors[0].b = 0x00;
	} else {
		SDL_DitherColors(pal_256->colors,
					icon_256->format->BitsPerPixel);
	}

	/* Now copy color data to the icon BMP */
	for ( i=0; i<(1<<icon_win32->biBitCount); ++i ) {
		icon_win32->biColors[i].rgbRed = pal_256->colors[i].r;
		icon_win32->biColors[i].rgbGreen = pal_256->colors[i].g;
		icon_win32->biColors[i].rgbBlue = pal_256->colors[i].b;
	}

	/* Convert icon to a standard surface format.  This may not always
	   be necessary, as Windows supports a variety of BMP formats, but
	   it greatly simplifies our code.
	*/ 
        bounds.x = 0;
        bounds.y = 0;
        bounds.w = icon->w;
        bounds.h = icon->h;
        if ( SDL_LowerBlit(icon, &bounds, icon_256, &bounds) < 0 ) {
		SDL_FreeSurface(icon_256);
                return;
	}

	/* Copy pixels upside-down to icon BMP, masked with the icon mask */
	if ( SDL_MUSTLOCK(icon_256) || (icon_256->pitch != icon_pitch) ) {
		SDL_FreeSurface(icon_256);
		SDL_SetError("Warning: Unexpected icon_256 characteristics");
		return;
	}
	pdata = (Uint8 *)icon_256->pixels;
	mdata = mask;
	pwin32 = (Uint8 *)icon_win32+sizeof(*icon_win32)+icon_plen-icon_pitch;
	skip = icon_pitch - icon->w;
	for ( row=0; row<icon->h; ++row ) {
		for ( col=0; col<icon->w; ++col ) {
			if ( (col%8) == 0 ) {
				m = *mdata++;
			}
			if ( (m&0x80) != 0x00 ) {
				*pwin32 = *pdata;
			}
			m <<= 1;
			++pdata;
			++pwin32;
		}
		pdata  += skip;
		pwin32 += skip;
		pwin32 -= 2*icon_pitch;
	}
	SDL_FreeSurface(icon_256);

	/* Copy mask inverted and upside-down to icon BMP */
	mdata = mask;
	mwin32 = (Uint8 *)icon_win32
			+sizeof(*icon_win32)+icon_plen+icon_mlen-mask_pitch;
	for ( row=0; row<icon->h; ++row ) {
		for ( col=0; col<mask_pitch; ++col ) {
			*mwin32++ = ~*mdata++;
		}
		mwin32 -= 2*mask_pitch;
	}

	/* Finally, create the icon handle and set the window icon */
	screen_icn = CreateIconFromResourceEx((Uint8 *)icon_win32, icon_len,
			TRUE, 0x00030000, icon->w, icon->h, LR_DEFAULTCOLOR);
	if ( screen_icn == NULL ) {
		SDL_SetError("Couldn't create Win32 icon handle");
	} else {
		SetClassLong(SDL_Window, GCL_HICON, (LONG)screen_icn);
	}
#endif /* DISABLE_ICON_SUPPORT */
}
Exemple #11
0
/***********************************************************************
 *              create_app_icon_images
 */
CFArrayRef create_app_icon_images(void)
{
    HRSRC res_info;
    HGLOBAL res_data;
    GRPICONDIR *icon_dir;
    CFMutableArrayRef images = NULL;
    int i;

    TRACE("()\n");

    res_info = NULL;
    EnumResourceNamesW(NULL, (LPCWSTR)RT_GROUP_ICON, get_first_resource, (LONG_PTR)&res_info);
    if (!res_info)
    {
        WARN("found no RT_GROUP_ICON resource\n");
        return NULL;
    }

    if (!(res_data = LoadResource(NULL, res_info)))
    {
        WARN("failed to load RT_GROUP_ICON resource\n");
        return NULL;
    }

    if (!(icon_dir = LockResource(res_data)))
    {
        WARN("failed to lock RT_GROUP_ICON resource\n");
        goto cleanup;
    }

    images = CFArrayCreateMutable(NULL, icon_dir->idCount, &kCFTypeArrayCallBacks);
    if (!images)
    {
        WARN("failed to create images array\n");
        goto cleanup;
    }

    for (i = 0; i < icon_dir->idCount; i++)
    {
        int width = icon_dir->idEntries[i].bWidth;
        int height = icon_dir->idEntries[i].bHeight;
        BOOL found_better_bpp = FALSE;
        int j;
        LPCWSTR name;
        HGLOBAL icon_res_data;
        BYTE *icon_bits;

        if (!width) width = 256;
        if (!height) height = 256;

        /* If there's another icon at the same size but with better
           color depth, skip this one.  We end up making CGImages that
           are all 32 bits per pixel, so Cocoa doesn't get the original
           color depth info to pick the best representation itself. */
        for (j = 0; j < icon_dir->idCount; j++)
        {
            int jwidth = icon_dir->idEntries[j].bWidth;
            int jheight = icon_dir->idEntries[j].bHeight;

            if (!jwidth) jwidth = 256;
            if (!jheight) jheight = 256;

            if (j != i && jwidth == width && jheight == height &&
                icon_dir->idEntries[j].wBitCount > icon_dir->idEntries[i].wBitCount)
            {
                found_better_bpp = TRUE;
                break;
            }
        }

        if (found_better_bpp) continue;

        name = MAKEINTRESOURCEW(icon_dir->idEntries[i].nID);
        res_info = FindResourceW(NULL, name, (LPCWSTR)RT_ICON);
        if (!res_info)
        {
            WARN("failed to find RT_ICON resource %d with ID %hd\n", i, icon_dir->idEntries[i].nID);
            continue;
        }

        icon_res_data = LoadResource(NULL, res_info);
        if (!icon_res_data)
        {
            WARN("failed to load icon %d with ID %hd\n", i, icon_dir->idEntries[i].nID);
            continue;
        }

        icon_bits = LockResource(icon_res_data);
        if (icon_bits)
        {
            static const BYTE png_magic[] = { 0x89, 0x50, 0x4e, 0x47 };
            CGImageRef cgimage = NULL;

            if (!memcmp(icon_bits, png_magic, sizeof(png_magic)))
            {
                CFDataRef data = CFDataCreate(NULL, (UInt8*)icon_bits, icon_dir->idEntries[i].dwBytesInRes);
                if (data)
                {
                    CGDataProviderRef provider = CGDataProviderCreateWithCFData(data);
                    CFRelease(data);
                    if (provider)
                    {
                        cgimage = CGImageCreateWithPNGDataProvider(provider, NULL, FALSE,
                                                                   kCGRenderingIntentDefault);
                        CGDataProviderRelease(provider);
                    }
                }
            }

            if (!cgimage)
            {
                HICON icon;
                icon = CreateIconFromResourceEx(icon_bits, icon_dir->idEntries[i].dwBytesInRes,
                                                TRUE, 0x00030000, width, height, 0);
                if (icon)
                {
                    cgimage = create_cgimage_from_icon(icon, width, height);
                    DestroyIcon(icon);
                }
                else
                    WARN("failed to create icon %d from resource with ID %hd\n", i, icon_dir->idEntries[i].nID);
            }

            if (cgimage)
            {
                CFArrayAppendValue(images, cgimage);
                CGImageRelease(cgimage);
            }
        }
        else
            WARN("failed to lock RT_ICON resource %d with ID %hd\n", i, icon_dir->idEntries[i].nID);

        FreeResource(icon_res_data);
    }

cleanup:
    if (images && !CFArrayGetCount(images))
    {
        CFRelease(images);
        images = NULL;
    }
    FreeResource(res_data);

    return images;
}
Exemple #12
0
/*************************************************************************
 *	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;
}
Exemple #13
0
HICON IconFromSurface( const RageSurface *pSrcImg )
{
    RageSurface *pImg;

    {
        /* Round the width up to a multiple of 8, convert to 32-bit BGR, and reduce
         * to one-bit alpha. */
        int iWidth = pSrcImg->w;
        iWidth = (iWidth+7) & ~7;

        pImg = CreateSurface( iWidth, pSrcImg->h, 32,
                              0x00FF0000,
                              0x0000FF00,
                              0x000000FF,
                              0x80000000 );
        RageSurfaceUtils::Blit( pSrcImg, pImg );
    }

    RageSurfaceUtils::FlipVertically( pImg );

    int iSize = sizeof(BITMAPINFOHEADER);
    int iSizeImage = 0;
    iSizeImage += pImg->h * pImg->pitch; /* image */
    iSizeImage += (pImg->h * pImg->w) / 8; /* mask */

    BITMAPINFOHEADER *pBitmap = (BITMAPINFOHEADER *) malloc( iSize + iSizeImage );
    memset( pBitmap, 0, iSize + iSizeImage );

    pBitmap->biSize  = sizeof(BITMAPINFOHEADER);
    pBitmap->biWidth = pImg->w;
    pBitmap->biHeight = pImg->h * 2;
    pBitmap->biPlanes = 1;
    pBitmap->biBitCount = 32;
    pBitmap->biCompression = BI_RGB;
    pBitmap->biSizeImage = pImg->h * pImg->pitch;

    uint8_t *pImage = ((uint8_t *) pBitmap) + iSize;
    uint8_t *pMask = pImage + pImg->h * pImg->pitch;

    memcpy( pImage, pImg->pixels, pImg->h * pImg->pitch );

    int iMaskPitch = pImg->w/8;
    for( int y = 0; y < pImg->h; ++y )
    {
        int bit = 0x80;
        uint32_t *pRow = (uint32_t *) (pImage + y*pImg->pitch);
        uint8_t *pMaskRow = pMask + y*iMaskPitch;
        for( int x = 0; x < pImg->w; ++x )
        {
            if( !(pRow[x] & pImg->fmt.Mask[3]) )
            {
                /* Transparent; set this mask bit. */
                *pMaskRow |= bit;
                pRow[x] = 0;
            }

            bit >>= 1;
            if( bit == 0 )
            {
                bit = 0x80;
                ++pMaskRow;
            }
        }
    }

    HICON icon = CreateIconFromResourceEx( (BYTE *) pBitmap, iSize + iSizeImage, TRUE, 0x00030000, pImg->w, pImg->h, LR_DEFAULTCOLOR );

    delete pImg;
    pImg = NULL;
    free( pBitmap );

    if( icon == NULL )
    {
        LOG->Trace( "%s", werr_ssprintf( GetLastError(), "CreateIconFromResourceEx" ).c_str() );
        return NULL;
    }

    return icon;
}
void CHwWinCursor::Finish()
{
	if (frames.size()<1)
		return;

	hotx = (hotSpot==CMouseCursor::TopLeft) ? 0 : (short)xmaxsize/2;
	hoty = (hotSpot==CMouseCursor::TopLeft) ? 0 : (short)ymaxsize/2;

	//note: windows only except 16x16,32x32,64x64,etc. (and some more not 2^n ones)
	int squaresize =  next_power_of_2( std::max(xmaxsize,ymaxsize) );

	//resize images
	for (std::vector<ImageData>::iterator it=icons.begin(); it<icons.end(); it++)
		resizeImage(&*it,squaresize,squaresize);

	const int riffsize  = 32 + sizeof(AnihStructure) + (frames.size()+2) * 2 * sizeof(DWORD);
	const int iconssize = icons.size() * (2*sizeof(DWORD) + 3*sizeof(WORD) +
					       sizeof(CursorDirectoryHeader) +
					       sizeof(CursorInfoHeader) +
					       squaresize*squaresize*4 +
					       squaresize*squaresize/8);
	const int totalsize = riffsize + iconssize;
	unsigned char* mem = new unsigned char[ totalsize ];

	unsigned char* curmem = mem;
	DWORD* dwmem;

	//write RIFF header
		strcpy((char*)curmem,"RIFF");	curmem+=4;
		dwmem = (DWORD*)&curmem[0];
		dwmem[0] = totalsize-8;		curmem+=4; //filesize
		strcpy((char*)curmem,"ACON");	curmem+=4;

	//Anih header
		strcpy((char*)curmem,"anih");
		curmem += 4;
		curmem[0] = 36;
		curmem[1] = curmem[2] = curmem[3] = 0;
		curmem += 4;

		AnihStructure anih;
		memset(&anih,0,sizeof(AnihStructure));
		anih.size   = 36;		//anih structure size
		anih.images = image_count;		//number of images
		anih.frames = framerates.size();	//number of frames
		anih.flags  = 0x3L;		//using seq structure and .cur format for saving bmp data
		memcpy(curmem, &anih, sizeof(AnihStructure));
		curmem += sizeof(AnihStructure);

	//LIST + icons
		strcpy((char*)curmem,"LIST");	curmem+=4;
		dwmem = (DWORD*)&curmem[0];
		dwmem[0] = iconssize+4;		curmem+=4;
		strcpy((char*)curmem,"fram");	curmem+=4;

		for (std::vector<ImageData>::iterator it=icons.begin(); it<icons.end(); it++) {
			buildIco(curmem,*it);
			curmem += 2*sizeof(DWORD) + 3*sizeof(WORD)+sizeof(CursorDirectoryHeader)+sizeof(CursorInfoHeader)+squaresize*squaresize*4+squaresize*squaresize/8;
		}

	//SEQ header
		strcpy((char*)curmem,"seq ");
		curmem += 4;
		DWORD* seq = (DWORD*)&curmem[0];
		seq[0] = frames.size()*sizeof(DWORD);
		seq++;
		for (int i=0; i<frames.size(); i++)
			seq[i] = frames.at(i);
		curmem += (frames.size()+1)*sizeof(DWORD);

	//RATE header
		strcpy((char*)curmem,"rate");
		curmem += 4;
		DWORD* rate = (DWORD*)&curmem[0];
		rate[0] = framerates.size()*sizeof(DWORD);
		rate++;
		for (int i=0; i<framerates.size(); i++)
			rate[i] = framerates.at(i);
		curmem += (framerates.size()+1)*sizeof(DWORD);

	/*char fname[256];
	SNPRINTF(fname, sizeof(fname), "cursors/mycursor%d.ani", ++savedcount);
	FILE * pFile = fopen( fname , "wb" );
	fwrite(mem , 1 , curmem-mem, pFile );
	fclose(pFile);*/

	cursor = (HCURSOR)CreateIconFromResourceEx((PBYTE)mem,totalsize,FALSE,0x00030000,squaresize,squaresize,0);

	delete[] mem;
	for (std::vector<ImageData>::iterator it=icons.begin(); it<icons.end(); it++)
		delete[] (*it).data;
	icons.clear();

	//if (cursor==NULL) logOutput.Print("hw cursor failed: x%d y%d",squaresize,squaresize);
}
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;
}