static void register_fake_dll( const WCHAR *name, const void *data, size_t size ) { static const WCHAR atlW[] = {'a','t','l','1','0','0','.','d','l','l',0}; static const WCHAR moduleW[] = {'M','O','D','U','L','E',0}; static const WCHAR regtypeW[] = {'W','I','N','E','_','R','E','G','I','S','T','R','Y',0}; const IMAGE_RESOURCE_DIRECTORY *resdir; LDR_RESOURCE_INFO info; HRESULT hr = S_OK; HMODULE module = (HMODULE)((ULONG_PTR)data | 1); struct dll_data dll_data = { name, data, size }; EnumResourceNamesW( module, (WCHAR*)RT_MANIFEST, register_manifest, (LONG_PTR)&dll_data ); info.Type = (ULONG_PTR)regtypeW; if (LdrFindResourceDirectory_U( module, &info, 1, &resdir )) return; if (!registrar) { HRESULT (WINAPI *pAtlCreateRegistrar)(IRegistrar**); HMODULE atl = LoadLibraryW( atlW ); if ((pAtlCreateRegistrar = (void *)GetProcAddress( atl, "AtlCreateRegistrar" ))) hr = pAtlCreateRegistrar( ®istrar ); else hr = E_NOINTERFACE; if (!registrar) { ERR( "failed to create IRegistrar: %x\n", hr ); return; } } TRACE( "registering %s\n", debugstr_w(name) ); IRegistrar_ClearReplacements( registrar ); IRegistrar_AddReplacement( registrar, moduleW, name ); EnumResourceNamesW( module, regtypeW, register_resource, (LONG_PTR)&hr ); if (FAILED(hr)) ERR( "failed to register %s: %x\n", debugstr_w(name), hr ); }
static void register_fake_dll( const WCHAR *name, const void *data, size_t size ) { static const WCHAR atlW[] = {'a','t','l','.','d','l','l',0}; static const WCHAR moduleW[] = {'M','O','D','U','L','E',0}; static const WCHAR regtypeW[] = {'W','I','N','E','_','R','E','G','I','S','T','R','Y',0}; static const WCHAR manifestW[] = {'W','I','N','E','_','M','A','N','I','F','E','S','T',0}; const IMAGE_RESOURCE_DIRECTORY *resdir; LDR_RESOURCE_INFO info; HRESULT hr = S_OK; HMODULE module = (HMODULE)((ULONG_PTR)data | 1); HRSRC rsrc; if ((rsrc = FindResourceW( module, manifestW, MAKEINTRESOURCEW(RT_MANIFEST) ))) { char *manifest = LoadResource( module, rsrc ); register_manifest( name, manifest, SizeofResource( module, rsrc ), data, size ); } info.Type = (ULONG_PTR)regtypeW; if (LdrFindResourceDirectory_U( module, &info, 1, &resdir )) return; if (!registrar) { /* create the object by hand since we can't guarantee that atl and ole32 are registered */ IClassFactory *cf; HRESULT (WINAPI *pDllGetClassObject)( REFCLSID clsid, REFIID iid, LPVOID *ppv ); HMODULE atl = LoadLibraryW( atlW ); if ((pDllGetClassObject = (void *)GetProcAddress( atl, "DllGetClassObject" ))) { hr = pDllGetClassObject( &CLSID_Registrar, &IID_IClassFactory, (void **)&cf ); if (SUCCEEDED( hr )) { hr = IClassFactory_CreateInstance( cf, NULL, &IID_IRegistrar, (void **)®istrar ); IClassFactory_Release( cf ); } } if (!registrar) { ERR( "failed to create IRegistrar: %x\n", hr ); return; } } TRACE( "registering %s\n", debugstr_w(name) ); IRegistrar_ClearReplacements( registrar ); IRegistrar_AddReplacement( registrar, moduleW, name ); EnumResourceNamesW( module, regtypeW, register_resource, (LONG_PTR)&hr ); if (FAILED(hr)) ERR( "failed to register %s: %x\n", debugstr_w(name), hr ); }
BOOL CALLBACK EnumTypesProc( HMODULE Module, PWSTR Type, LONG Param ) { if (!EnumResourceNamesW(Module, Type = Uppercase(Type), EnumNamesProc, 0)) { WCHAR Buffer[20]; DWORD Error = GetLastError(); wprintf(L"EnumResourceNames(%p, %x %ls) failed %x\n", Module, Type, IdToString(Type, Buffer, NUMBER_OF(Buffer)), Error); } return TRUE; }
INT_PTR CALLBACK PickIconProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam ) { LPMEASUREITEMSTRUCT lpmis; LPDRAWITEMSTRUCT lpdis; HICON hIcon; INT index, count; WCHAR szText[MAX_PATH], szTitle[100], szFilter[100]; OPENFILENAMEW ofn = {0}; PPICK_ICON_CONTEXT pIconContext = (PPICK_ICON_CONTEXT)GetWindowLongPtr(hwndDlg, DWLP_USER); switch(uMsg) { case WM_INITDIALOG: pIconContext = (PPICK_ICON_CONTEXT)lParam; SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG)pIconContext); pIconContext->hDlgCtrl = GetDlgItem(hwndDlg, IDC_PICKICON_LIST); EnumResourceNamesW(pIconContext->hLibrary, RT_ICON, EnumPickIconResourceProc, (LPARAM)pIconContext); if (PathUnExpandEnvStringsW(pIconContext->szName, szText, MAX_PATH)) SetDlgItemTextW(hwndDlg, IDC_EDIT_PATH, szText); else SetDlgItemTextW(hwndDlg, IDC_EDIT_PATH, pIconContext->szName); count = SendMessage(pIconContext->hDlgCtrl, LB_GETCOUNT, 0, 0); if (count != LB_ERR) { if (count > pIconContext->Index) SendMessageW(pIconContext->hDlgCtrl, LB_SETCURSEL, pIconContext->Index, 0); else SendMessageW(pIconContext->hDlgCtrl, LB_SETCURSEL, 0, 0); } return TRUE; case WM_COMMAND: switch(LOWORD(wParam)) { case IDOK: index = SendMessageW(pIconContext->hDlgCtrl, LB_GETCURSEL, 0, 0); pIconContext->Index = index; GetDlgItemTextW(hwndDlg, IDC_EDIT_PATH, pIconContext->szName, MAX_PATH); DestroyIconList(pIconContext->hDlgCtrl); EndDialog(hwndDlg, 1); break; case IDCANCEL: DestroyIconList(pIconContext->hDlgCtrl); EndDialog(hwndDlg, 0); break; case IDC_PICKICON_LIST: if (HIWORD(wParam) == LBN_SELCHANGE) InvalidateRect((HWND)lParam, NULL, TRUE); // FIXME USE UPDATE RECT break; case IDC_BUTTON_PATH: szText[0] = 0; szTitle[0] = 0; szFilter[0] = 0; ofn.lStructSize = sizeof(ofn); ofn.hwndOwner = hwndDlg; ofn.lpstrFile = szText; ofn.nMaxFile = MAX_PATH; LoadStringW(shell32_hInstance, IDS_PICK_ICON_TITLE, szTitle, sizeof(szTitle) / sizeof(WCHAR)); ofn.lpstrTitle = szTitle; LoadStringW(shell32_hInstance, IDS_PICK_ICON_FILTER, szFilter, sizeof(szFilter) / sizeof(WCHAR)); ofn.lpstrFilter = szFilter; if (GetOpenFileNameW(&ofn)) { HMODULE hLibrary; if (!wcsicmp(pIconContext->szName, szText)) break; DestroyIconList(pIconContext->hDlgCtrl); hLibrary = LoadLibraryExW(szText, NULL, LOAD_LIBRARY_AS_DATAFILE | LOAD_LIBRARY_AS_IMAGE_RESOURCE); if (hLibrary == NULL) break; FreeLibrary(pIconContext->hLibrary); pIconContext->hLibrary = hLibrary; wcscpy(pIconContext->szName, szText); EnumResourceNamesW(pIconContext->hLibrary, RT_ICON, EnumPickIconResourceProc, (LPARAM)pIconContext); if (PathUnExpandEnvStringsW(pIconContext->szName, szText, MAX_PATH)) SetDlgItemTextW(hwndDlg, IDC_EDIT_PATH, szText); else SetDlgItemTextW(hwndDlg, IDC_EDIT_PATH, pIconContext->szName); SendMessageW(pIconContext->hDlgCtrl, LB_SETCURSEL, 0, 0); } break; } break; case WM_MEASUREITEM: lpmis = (LPMEASUREITEMSTRUCT) lParam; lpmis->itemHeight = 32; lpmis->itemWidth = 64; return TRUE; case WM_DRAWITEM: lpdis = (LPDRAWITEMSTRUCT) lParam; if (lpdis->itemID == (UINT)-1) { break; } switch (lpdis->itemAction) { case ODA_SELECT: case ODA_DRAWENTIRE: index = SendMessageW(pIconContext->hDlgCtrl, LB_GETCURSEL, 0, 0); hIcon =(HICON)SendMessage(lpdis->hwndItem, LB_GETITEMDATA, lpdis->itemID, (LPARAM) 0); if (lpdis->itemID == (UINT)index) { HBRUSH hBrush; hBrush = CreateSolidBrush(RGB(0, 0, 255)); FillRect(lpdis->hDC, &lpdis->rcItem, hBrush); DeleteObject(hBrush); } else { HBRUSH hBrush; hBrush = CreateSolidBrush(RGB(255, 255, 255)); FillRect(lpdis->hDC, &lpdis->rcItem, hBrush); DeleteObject(hBrush); } DrawIconEx(lpdis->hDC, lpdis->rcItem.left,lpdis->rcItem.top, hIcon, 0, 0, 0, NULL, DI_NORMAL); break; } break; } return FALSE; }
/*********************************************************************** * 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; }