/* add version resources to the dll by copying them from the source module */ static BOOL add_version_resource( HMODULE module, struct dll_info *dll_info ) { BOOL ret = FALSE; DWORD rva_start = ~0U, rva_end = 0, dir_size, total_size; const IMAGE_RESOURCE_DIRECTORY *basedir; const BYTE *data_start, *root; BYTE *buffer; if (!module) return TRUE; if (LdrFindResourceDirectory_U( module, NULL, 0, &basedir ) != STATUS_SUCCESS) return TRUE; root = (const BYTE *)basedir; get_resource_data( basedir, root, &rva_start, &rva_end ); data_start = (const BYTE *)module + rva_start; if (data_start <= root) return FALSE; dir_size = data_start - root; if (!(buffer = HeapAlloc( GetProcessHeap(), 0, dir_size ))) return FALSE; memcpy( buffer, root, dir_size ); fixup_resources( (IMAGE_RESOURCE_DIRECTORY *)buffer, buffer, dll_info->mem_pos + dir_size - rva_start ); if (!xwrite( dll_info, buffer, dir_size, dll_info->file_pos )) goto done; if (!xwrite( dll_info, data_start, rva_end - rva_start, dll_info->file_pos + dir_size )) goto done; total_size = dir_size + rva_end - rva_start; add_directory( dll_info, IMAGE_DIRECTORY_ENTRY_RESOURCE, dll_info->mem_pos, total_size ); add_section( dll_info, ".rsrc", total_size, IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_MEM_READ ); ret = TRUE; done: HeapFree( GetProcessHeap(), 0, buffer ); return ret; }
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 ); }
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}; 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) { 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 ); }