/*********************************************************************** * USER initialisation routine */ static BOOL process_attach(void) { HINSTANCE16 instance; /* Create USER heap */ if ((instance = LoadLibrary16( "USER.EXE" )) >= 32) USER_HeapSel = instance | 7; else { USER_HeapSel = GlobalAlloc16( GMEM_FIXED, 65536 ); LocalInit16( USER_HeapSel, 32, 65534 ); } /* some Win9x dlls expect keyboard to be loaded */ if (GetVersion() & 0x80000000) LoadLibrary16( "keyboard.drv" ); winstation_init(); /* Initialize system colors and metrics */ SYSPARAMS_Init(); /* Setup palette function pointers */ palette_init(); /* Initialize built-in window classes */ CLASS_RegisterBuiltinClasses(); /* Initialize message spying */ if (!SPY_Init()) return FALSE; return TRUE; }
/************************************************************************** * DllEntryPoint (KERNEL.669) */ BOOL WINAPI KERNEL_DllEntryPoint( DWORD reasion, HINSTANCE16 inst, WORD ds, WORD heap, DWORD reserved1, WORD reserved2 ) { static BOOL done; /* the entry point can be called multiple times */ if (done) return TRUE; done = TRUE; /* create the shared heap for broken win95 native dlls */ HeapCreate( HEAP_SHARED, 0, 0 ); /* setup emulation of protected instructions from 32-bit code */ if (GetVersion() & 0x80000000) RtlAddVectoredExceptionHandler( TRUE, INSTR_vectored_handler ); /* Initialize 16-bit thunking entry points */ if (!WOWTHUNK_Init()) return FALSE; /* Initialize DOS memory */ if (!DOSMEM_Init()) return FALSE; /* Initialize special KERNEL entry points */ NE_SetEntryPoint( inst, 178, GetWinFlags16() ); NE_SetEntryPoint( inst, 454, wine_get_cs() ); NE_SetEntryPoint( inst, 455, wine_get_ds() ); NE_SetEntryPoint( inst, 183, DOSMEM_0000H ); /* KERNEL.183: __0000H */ NE_SetEntryPoint( inst, 173, DOSMEM_BiosSysSeg ); /* KERNEL.173: __ROMBIOS */ NE_SetEntryPoint( inst, 193, DOSMEM_BiosDataSeg ); /* KERNEL.193: __0040H */ NE_SetEntryPoint( inst, 194, DOSMEM_BiosSysSeg ); /* KERNEL.194: __F000H */ /* Initialize KERNEL.THHOOK */ TASK_InstallTHHook(MapSL((SEGPTR)GetProcAddress16( inst, (LPCSTR)332 ))); TASK_CreateMainTask(); /* Initialize the real-mode selector entry points */ #define SET_ENTRY_POINT( num, addr ) \ NE_SetEntryPoint( inst, (num), GLOBAL_CreateBlock( GMEM_FIXED, \ DOSMEM_MapDosToLinear(addr), 0x10000, inst, \ WINE_LDT_FLAGS_DATA )) SET_ENTRY_POINT( 174, 0xa0000 ); /* KERNEL.174: __A000H */ SET_ENTRY_POINT( 181, 0xb0000 ); /* KERNEL.181: __B000H */ SET_ENTRY_POINT( 182, 0xb8000 ); /* KERNEL.182: __B800H */ SET_ENTRY_POINT( 195, 0xc0000 ); /* KERNEL.195: __C000H */ SET_ENTRY_POINT( 179, 0xd0000 ); /* KERNEL.179: __D000H */ SET_ENTRY_POINT( 190, 0xe0000 ); /* KERNEL.190: __E000H */ #undef SET_ENTRY_POINT /* Force loading of some dlls */ LoadLibrary16( "system.drv" ); LoadLibrary16( "comm.drv" ); return TRUE; }
/**************************************************************************** * UTRegister (KERNEL32.@) */ BOOL WINAPI UTRegister( HMODULE hModule, LPSTR lpsz16BITDLL, LPSTR lpszInitName, LPSTR lpszProcName, FARPROC *ppfn32Thunk, FARPROC pfnUT32CallBack, LPVOID lpBuff ) { UTINFO *ut; HMODULE16 hModule16; FARPROC16 target16, init16; /* Load 16-bit DLL and get UTProc16 entry point */ if ( (hModule16 = LoadLibrary16( lpsz16BITDLL )) <= 32 || (target16 = GetProcAddress16( hModule16, lpszProcName )) == 0 ) return FALSE; /* Allocate UTINFO struct */ RtlAcquirePebLock(); if ( (ut = UTFind( hModule )) != NULL ) ut = NULL; else ut = UTAlloc( hModule, hModule16, target16, pfnUT32CallBack ); RtlReleasePebLock(); if ( !ut ) { FreeLibrary16( hModule16 ); return FALSE; } /* Call UTInit16 if present */ if ( lpszInitName && (init16 = GetProcAddress16( hModule16, lpszInitName )) != 0 ) { SEGPTR callback = MapLS( &ut->ut16 ); SEGPTR segBuff = MapLS( lpBuff ); WORD args[4]; DWORD ret; args[3] = SELECTOROF(callback); args[2] = OFFSETOF(callback); args[1] = SELECTOROF(segBuff); args[0] = OFFSETOF(segBuff); WOWCallback16Ex( (DWORD)init16, WCB16_PASCAL, sizeof(args), args, &ret ); UnMapLS( segBuff ); UnMapLS( callback ); if (!ret) { UTUnRegister( hModule ); return FALSE; } } /* Return 32-bit thunk */ *ppfn32Thunk = (FARPROC) &ut->ut32; return TRUE; }
/*********************************************************************** * SystemHeapInfo (TOOLHELP.71) */ BOOL16 WINAPI SystemHeapInfo16( SYSHEAPINFO *pHeapInfo ) { STACK16FRAME* stack16 = MapSL((SEGPTR)NtCurrentTeb()->WOW32Reserved); HANDLE16 oldDS = stack16->ds; WORD user = LoadLibrary16( "USER.EXE" ); WORD gdi = LoadLibrary16( "GDI.EXE" ); stack16->ds = user; pHeapInfo->wUserFreePercent = (int)LocalCountFree16() * 100 / LocalHeapSize16(); stack16->ds = gdi; pHeapInfo->wGDIFreePercent = (int)LocalCountFree16() * 100 / LocalHeapSize16(); stack16->ds = oldDS; pHeapInfo->hUserSegment = user; pHeapInfo->hGDISegment = gdi; FreeLibrary16( user ); FreeLibrary16( gdi ); return TRUE; }
/************************************************************************** * DllEntryPoint (KERNEL.669) */ BOOL WINAPI KERNEL_DllEntryPoint( DWORD reasion, HINSTANCE16 inst, WORD ds, WORD heap, DWORD reserved1, WORD reserved2 ) { static int done; /* the entry point can be called multiple times */ if (done) return TRUE; done = 1; /* Initialize 16-bit thunking entry points */ if (!WOWTHUNK_Init()) return FALSE; /* Initialize DOS memory */ if (!DOSMEM_Init()) return FALSE; /* Initialize special KERNEL entry points */ NE_SetEntryPoint( inst, 178, GetWinFlags16() ); NE_SetEntryPoint( inst, 454, wine_get_cs() ); NE_SetEntryPoint( inst, 455, wine_get_ds() ); NE_SetEntryPoint( inst, 183, DOSMEM_0000H ); /* KERNEL.183: __0000H */ NE_SetEntryPoint( inst, 173, DOSMEM_BiosSysSeg ); /* KERNEL.173: __ROMBIOS */ NE_SetEntryPoint( inst, 193, DOSMEM_BiosDataSeg ); /* KERNEL.193: __0040H */ NE_SetEntryPoint( inst, 194, DOSMEM_BiosSysSeg ); /* KERNEL.194: __F000H */ /* Initialize KERNEL.THHOOK */ TASK_InstallTHHook(MapSL((SEGPTR)GetProcAddress16( inst, (LPCSTR)332 ))); /* Initialize the real-mode selector entry points */ #define SET_ENTRY_POINT( num, addr ) \ NE_SetEntryPoint( inst, (num), GLOBAL_CreateBlock( GMEM_FIXED, \ DOSMEM_MapDosToLinear(addr), 0x10000, inst, \ WINE_LDT_FLAGS_DATA )) SET_ENTRY_POINT( 174, 0xa0000 ); /* KERNEL.174: __A000H */ SET_ENTRY_POINT( 181, 0xb0000 ); /* KERNEL.181: __B000H */ SET_ENTRY_POINT( 182, 0xb8000 ); /* KERNEL.182: __B800H */ SET_ENTRY_POINT( 195, 0xc0000 ); /* KERNEL.195: __C000H */ SET_ENTRY_POINT( 179, 0xd0000 ); /* KERNEL.179: __D000H */ SET_ENTRY_POINT( 190, 0xe0000 ); /* KERNEL.190: __E000H */ #undef SET_ENTRY_POINT /* Force loading of some dlls */ LoadLibrary16( "system.drv" ); return TRUE; }
/************************************************************************** * DllMain */ BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved ) { switch(reason) { case DLL_PROCESS_ATTACH: LoadLibrary16( "krnl386.exe" ); /* fall through */ case DLL_THREAD_ATTACH: thread_attach(); break; case DLL_THREAD_DETACH: thread_detach(); break; } return TRUE; }
/************************************************************************** * DRIVER_TryOpenDriver16 [internal] * * Tries to load a 16 bit driver whose DLL's (module) name is lpFileName. */ static LPWINE_DRIVER DRIVER_TryOpenDriver16(LPCSTR lpFileName, LPARAM lParam2) { static WORD DRIVER_hDrvr16Counter /* = 0 */; LPWINE_DRIVER lpDrv = NULL; HMODULE16 hModule; DRIVERPROC16 lpProc; LPCSTR lpSFN; LPSTR ptr; TRACE("('%s', %08lX);\n", lpFileName, lParam2); if (strlen(lpFileName) < 1) return lpDrv; if ((lpSFN = strrchr(lpFileName, '\\')) == NULL) lpSFN = lpFileName; else lpSFN++; if ((ptr = strchr(lpFileName, ' ')) != NULL) { *ptr++ = '\0'; while (*ptr == ' ') ptr++; if (*ptr == '\0') ptr = NULL; } if ((hModule = LoadLibrary16(lpFileName)) < 32) goto exit; if ((lpProc = (DRIVERPROC16)GetProcAddress16(hModule, "DRIVERPROC")) == NULL) goto exit; if ((lpDrv = HeapAlloc(GetProcessHeap(), 0, sizeof(WINE_DRIVER))) == NULL) goto exit; lpDrv->dwDriverID = 0; while (DRIVER_FindFromHDrvr16(++DRIVER_hDrvr16Counter)); lpDrv->hDriver16 = DRIVER_hDrvr16Counter; lstrcpynA(lpDrv->szAliasName, lpSFN, sizeof(lpDrv->szAliasName)); lpDrv->hModule16 = hModule; lpDrv->lpDrvProc = lpProc; if (!DRIVER_AddToList(lpDrv, (LPARAM)ptr, lParam2)) goto exit; return lpDrv; exit: TRACE("Unable to load 16 bit module (%s): %04x\n", lpFileName, hModule); if (hModule >= 32) FreeLibrary16(hModule); HeapFree(GetProcessHeap(), 0, lpDrv); return NULL; }
/****************************************************************************** * OleMetaFilePictFromIconAndLabel (OLE2.56) * * Returns a global memory handle to a metafile which contains the icon and * label given. * I guess the result of that should look somehow like desktop icons. * If no hIcon is given, we load the icon via lpszSourceFile and iIconIndex. * This code might be wrong at some places. */ HGLOBAL16 WINAPI OleMetaFilePictFromIconAndLabel16( HICON16 hIcon, LPCOLESTR16 lpszLabel, LPCOLESTR16 lpszSourceFile, UINT16 iIconIndex ) { METAFILEPICT16 *mf16; HGLOBAL16 hmf16; HMETAFILE hmf; INT mfSize; HDC hdc; if (!hIcon) { if (lpszSourceFile) { HINSTANCE16 hInstance = LoadLibrary16(lpszSourceFile); /* load the icon at index from lpszSourceFile */ hIcon = HICON_16(LoadIconA(HINSTANCE_32(hInstance), (LPCSTR)(DWORD)iIconIndex)); FreeLibrary16(hInstance); } else return 0; } FIXME("(%04x, '%s', '%s', %d): incorrect metrics, please try to correct them !\n", hIcon, lpszLabel, lpszSourceFile, iIconIndex); hdc = CreateMetaFileW(NULL); DrawIcon(hdc, 0, 0, HICON_32(hIcon)); /* FIXME */ TextOutA(hdc, 0, 0, lpszLabel, 1); /* FIXME */ hmf = CloseMetaFile(hdc); hmf16 = GlobalAlloc16(0, sizeof(METAFILEPICT16)); mf16 = (METAFILEPICT16 *)GlobalLock16(hmf16); mf16->mm = MM_ANISOTROPIC; mf16->xExt = 20; /* FIXME: bogus */ mf16->yExt = 20; /* dito */ mfSize = GetMetaFileBitsEx(hmf, 0, 0); mf16->hMF = GlobalAlloc16(GMEM_MOVEABLE, mfSize); if(mf16->hMF) { GetMetaFileBitsEx(hmf, mfSize, GlobalLock16(mf16->hMF)); GlobalUnlock16(mf16->hMF); } return hmf16; }
/********************************************************************** * INT_GetPMHandler * * Return the protected mode interrupt vector for a given interrupt. */ FARPROC16 INT_GetPMHandler( BYTE intnum ) { if (!INT_Vectors[intnum]) { static HMODULE16 wprocs; if (!wprocs) { if (((wprocs = GetModuleHandle16( "wprocs" )) < 32) && ((wprocs = LoadLibrary16( "wprocs" )) < 32)) { ERR("could not load wprocs.dll\n"); return 0; } } if (!(INT_Vectors[intnum] = GetProcAddress16( wprocs, (LPCSTR)(FIRST_INTERRUPT + intnum)))) { WARN("int%x not implemented, returning dummy handler\n", intnum ); INT_Vectors[intnum] = GetProcAddress16( wprocs, (LPCSTR)(FIRST_INTERRUPT + 256) ); } } return INT_Vectors[intnum]; }
/*********************************************************************** * GetFreeSystemResources (USER.284) */ WORD WINAPI GetFreeSystemResources16( WORD resType ) { HINSTANCE16 gdi_inst; WORD gdi_heap; int userPercent, gdiPercent; if ((gdi_inst = LoadLibrary16( "GDI" )) < 32) return 0; gdi_heap = gdi_inst | 7; switch(resType) { case GFSR_USERRESOURCES: userPercent = (int)LOCAL_CountFree( USER_HeapSel ) * 100 / LOCAL_HeapSize( USER_HeapSel ); gdiPercent = 100; break; case GFSR_GDIRESOURCES: gdiPercent = (int)LOCAL_CountFree( gdi_inst ) * 100 / LOCAL_HeapSize( gdi_inst ); userPercent = 100; break; case GFSR_SYSTEMRESOURCES: userPercent = (int)LOCAL_CountFree( USER_HeapSel ) * 100 / LOCAL_HeapSize( USER_HeapSel ); gdiPercent = (int)LOCAL_CountFree( gdi_inst ) * 100 / LOCAL_HeapSize( gdi_inst ); break; default: userPercent = gdiPercent = 0; break; } FreeLibrary16( gdi_inst ); return (WORD)min( userPercent, gdiPercent ); }
/*********************************************************************** * GDI_Init * * GDI initialization. */ BOOL GDI_Init(void) { HINSTANCE16 instance; HKEY hkey; GDIOBJHDR *ptr; int i; create_gdi_syslevel_cs(); initialize_driver(); if (RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\Wine\\Config\\Tweak.Fonts", &hkey)) hkey = 0; /* create GDI heap */ if ((instance = LoadLibrary16( "GDI.EXE" )) < 32) return FALSE; GDI_HeapSel = instance | 7; /* create stock objects */ stock_objects[WHITE_BRUSH] = CreateBrushIndirect( &WhiteBrush ); stock_objects[LTGRAY_BRUSH] = CreateBrushIndirect( &LtGrayBrush ); stock_objects[GRAY_BRUSH] = CreateBrushIndirect( &GrayBrush ); stock_objects[DKGRAY_BRUSH] = CreateBrushIndirect( &DkGrayBrush ); stock_objects[BLACK_BRUSH] = CreateBrushIndirect( &BlackBrush ); stock_objects[NULL_BRUSH] = CreateBrushIndirect( &NullBrush ); stock_objects[WHITE_PEN] = CreatePenIndirect( &WhitePen ); stock_objects[BLACK_PEN] = CreatePenIndirect( &BlackPen ); stock_objects[NULL_PEN] = CreatePenIndirect( &NullPen ); stock_objects[DEFAULT_PALETTE] = PALETTE_Init(); stock_objects[DEFAULT_BITMAP] = CreateBitmap( 1, 1, 1, 1, NULL ); stock_objects[OEM_FIXED_FONT] = create_stock_font( "OEMFixed", &OEMFixedFont, hkey ); stock_objects[ANSI_FIXED_FONT] = create_stock_font( "AnsiFixed", &AnsiFixedFont, hkey ); stock_objects[ANSI_VAR_FONT] = create_stock_font( "AnsiVar", &AnsiVarFont, hkey ); stock_objects[SYSTEM_FONT] = create_stock_font( "System", &SystemFont, hkey ); stock_objects[DEVICE_DEFAULT_FONT] = create_stock_font( "DeviceDefault", &DeviceDefaultFont, hkey ); stock_objects[SYSTEM_FIXED_FONT] = create_stock_font( "SystemFixed", &SystemFixedFont, hkey ); stock_objects[DEFAULT_GUI_FONT] = create_stock_font( "DefaultGui", &DefaultGuiFont, hkey ); /* clear the NOSYSTEM bit on all stock objects*/ for (i = 0; i < NB_STOCK_OBJECTS; i++) { if (!stock_objects[i]) { if (i == 9) continue; /* there's no stock object 9 */ ERR( "could not create stock object %d\n", i ); return FALSE; } ptr = GDI_GetObjPtr( stock_objects[i], MAGIC_DONTCARE ); ptr->wMagic &= ~OBJECT_NOSYSTEM; GDI_ReleaseObj( stock_objects[i] ); } if (hkey) RegCloseKey( hkey ); WineEngInit(); return TRUE; }
/*********************************************************************** * CoGetClassObject [COMPOBJ.7] * */ HRESULT WINAPI CoGetClassObject16( SEGPTR rclsid, DWORD dwClsContext, COSERVERINFO *pServerInfo, SEGPTR riid, SEGPTR ppv) { LPVOID *ppvl = MapSL(ppv); TRACE("CLSID: %s, IID: %s\n", debugstr_guid(MapSL(rclsid)), debugstr_guid(MapSL(riid))); *ppvl = NULL; if (pServerInfo) { FIXME("pServerInfo->name=%s pAuthInfo=%p\n", debugstr_w(pServerInfo->pwszName), pServerInfo->pAuthInfo); } if (CLSCTX_INPROC_SERVER & dwClsContext) { char idstr[CHARS_IN_GUID]; char buf_key[CHARS_IN_GUID+19], dllpath[MAX_PATH+1]; LONG dllpath_len = sizeof(dllpath); HMODULE16 dll; FARPROC16 DllGetClassObject; WORD args[6]; DWORD dwRet; StringFromGUID216(MapSL(rclsid), idstr, CHARS_IN_GUID); sprintf(buf_key, "CLSID\\%s\\InprocServer", idstr); if (RegQueryValueA(HKEY_CLASSES_ROOT, buf_key, dllpath, &dllpath_len)) { ERR("class %s not registered\n", debugstr_guid(MapSL(rclsid))); return REGDB_E_CLASSNOTREG; } dll = LoadLibrary16(dllpath); if (!dll) { ERR("couldn't load in-process dll %s\n", debugstr_a(dllpath)); return E_ACCESSDENIED; /* FIXME: or should this be CO_E_DLLNOTFOUND? */ } DllGetClassObject = GetProcAddress16(dll, "DllGetClassObject"); if (!DllGetClassObject) { ERR("couldn't find function DllGetClassObject in %s\n", debugstr_a(dllpath)); FreeLibrary16(dll); return CO_E_DLLNOTFOUND; } TRACE("calling DllGetClassObject %p\n", DllGetClassObject); args[5] = SELECTOROF(rclsid); args[4] = OFFSETOF(rclsid); args[3] = SELECTOROF(riid); args[2] = OFFSETOF(riid); args[1] = SELECTOROF(ppv); args[0] = OFFSETOF(ppv); WOWCallback16Ex((DWORD) DllGetClassObject, WCB16_PASCAL, sizeof(args), args, &dwRet); if (dwRet != S_OK) { ERR("DllGetClassObject returned error 0x%08x\n", dwRet); FreeLibrary16(dll); return dwRet; } return S_OK; } FIXME("semi-stub\n"); return E_NOTIMPL; }
/*********************************************************************** * main */ int main( int argc, char *argv[] ) { DWORD count; HINSTANCE16 instance; LOADPARAMS16 params; WORD showCmd[2]; char buffer[MAX_PATH]; STARTUPINFOA info; char *cmdline, *appname, **first_arg; char *p; if (!argv[1]) usage(); if (!strcmp( argv[1], "--app-name" )) { if (!(appname = argv[2])) usage(); first_arg = argv + 3; } else { if (!SearchPathA( NULL, argv[1], ".exe", sizeof(buffer), buffer, NULL )) { WINE_MESSAGE( "winevdm: unable to exec '%s': file not found\n", argv[1] ); ExitProcess(1); } appname = buffer; first_arg = argv + 1; } if (*first_arg) first_arg++; /* skip program name */ cmdline = build_command_line( first_arg ); if (WINE_TRACE_ON(winevdm)) { int i; WINE_TRACE( "GetCommandLine = '%s'\n", GetCommandLineA() ); WINE_TRACE( "appname = '%s'\n", appname ); WINE_TRACE( "cmdline = '%.*s'\n", cmdline[0], cmdline+1 ); for (i = 0; argv[i]; i++) WINE_TRACE( "argv[%d]: '%s'\n", i, argv[i] ); } GetStartupInfoA( &info ); showCmd[0] = 2; showCmd[1] = (info.dwFlags & STARTF_USESHOWWINDOW) ? info.wShowWindow : SW_SHOWNORMAL; params.hEnvironment = 0; params.cmdLine = MapLS( cmdline ); params.showCmd = MapLS( showCmd ); params.reserved = 0; RestoreThunkLock(1); /* grab the Win16 lock */ /* some programs assume mmsystem is always present */ LoadLibrary16( "gdi.exe" ); LoadLibrary16( "user.exe" ); LoadLibrary16( "mmsystem.dll" ); if ((instance = LoadModule16( appname, ¶ms )) < 32) { if (instance == 11) { /* first see if it is a .pif file */ if( ( p = strrchr( appname, '.' )) && !strcasecmp( p, ".pif")) pif_cmd( appname, cmdline + 1); else { /* try DOS format */ /* loader expects arguments to be regular C strings */ start_dos_exe( appname, cmdline + 1 ); } /* if we get back here it failed */ instance = GetLastError(); } WINE_MESSAGE( "winevdm: can't exec '%s': ", appname ); switch (instance) { case 2: WINE_MESSAGE("file not found\n" ); break; case 11: WINE_MESSAGE("invalid program file\n" ); break; default: WINE_MESSAGE("error=%d\n", instance ); break; } ExitProcess(instance); } /* wait forever; the process will be killed when the last task exits */ ReleaseThunkLock( &count ); Sleep( INFINITE ); return 0; }
/*********************************************************************** * VERSION_GetFileVersionInfo_16 [internal] * * NOTE: returns size of the 16-bit VERSION resource or 0xFFFFFFFF * in the case if file exists, but VERSION_INFO not found. * FIXME: handle is not used. */ static DWORD VERSION_GetFileVersionInfo_16( LPCSTR filename, LPDWORD handle, DWORD datasize, LPVOID data ) { VS_FIXEDFILEINFO *vffi; DWORD len; BYTE *buf; HMODULE16 hModule; HRSRC16 hRsrc; HGLOBAL16 hMem; BOOL do_free_library = FALSE; TRACE("(%s,%p)\n", debugstr_a(filename), handle ); hModule = GetModuleHandle16(filename); if(hModule < 32) { hModule = LoadLibrary16(filename); do_free_library = TRUE; } if(hModule < 32) { WARN("Could not load %s\n", debugstr_a(filename)); return 0; } hRsrc = FindResource16(hModule, MAKEINTRESOURCEA(VS_VERSION_INFO), MAKEINTRESOURCEA(VS_FILE_INFO)); if(!hRsrc) { WARN("Could not find VS_VERSION_INFO in %s\n", debugstr_a(filename)); if(do_free_library) FreeLibrary16(hModule); return 0xFFFFFFFF; } len = SizeofResource16(hModule, hRsrc); hMem = LoadResource16(hModule, hRsrc); if(!hMem) { WARN("Could not load VS_VERSION_INFO from %s\n", debugstr_a(filename)); if(do_free_library) FreeLibrary16(hModule); return 0xFFFFFFFF; } buf = LockResource16(hMem); if(!VersionInfoIs16(buf)) goto END; vffi = (VS_FIXEDFILEINFO *)VersionInfo16_Value( (VS_VERSION_INFO_STRUCT16 *)buf ); if ( vffi->dwSignature != VS_FFI_SIGNATURE ) { WARN("vffi->dwSignature is 0x%08lx, but not 0x%08lx!\n", vffi->dwSignature, VS_FFI_SIGNATURE ); len = 0xFFFFFFFF; goto END; } if ( TRACE_ON(ver) ) print_vffi_debug( vffi ); if(data) { if(datasize < len) len = datasize; /* truncate data */ if(len) memcpy(data, buf, len); else len = 0xFFFFFFFF; } END: FreeResource16(hMem); if(do_free_library) FreeLibrary16(hModule); return len; }
/************************************************************************* * InternalExtractIcon [SHELL.39] * * This abortion is called directly by Progman */ HGLOBAL16 WINAPI InternalExtractIcon16(HINSTANCE16 hInstance, LPCSTR lpszExeFileName, UINT16 nIconIndex, WORD n ) { HGLOBAL16 hRet = 0; HICON16 *RetPtr = NULL; OFSTRUCT ofs; HFILE hFile; TRACE("(%04x,file %s,start %d,extract %d\n", hInstance, lpszExeFileName, nIconIndex, n); if( !n ) return 0; hFile = OpenFile( lpszExeFileName, &ofs, OF_READ|OF_EXIST ); hRet = GlobalAlloc16( GMEM_FIXED | GMEM_ZEROINIT, sizeof(HICON16)*n); RetPtr = (HICON16*)GlobalLock16(hRet); if (hFile == HFILE_ERROR) { /* not found - load from builtin module if available */ HINSTANCE hInst = (HINSTANCE)LoadLibrary16(lpszExeFileName); if (hInst < 32) /* hmm, no Win16 module - try Win32 :-) */ hInst = LoadLibraryA(lpszExeFileName); if (hInst) { int i; for (i=nIconIndex; i < nIconIndex + n; i++) RetPtr[i-nIconIndex] = (HICON16)LoadIconA(hInst, (LPCSTR)(DWORD)i); FreeLibrary(hInst); return hRet; } GlobalFree16( hRet ); return 0; } if (nIconIndex == (UINT16)-1) /* get number of icons */ { RetPtr[0] = PrivateExtractIconsA( ofs.szPathName, -1, 0, 0, NULL, 0, 0, 0 ); } else { HRESULT res; HICON *icons; icons = HeapAlloc( GetProcessHeap(), 0, n * sizeof(*icons) ); res = PrivateExtractIconsA( ofs.szPathName, nIconIndex, GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON), icons, 0, n, 0 ); if (!res) { int i; for (i = 0; i < n; i++) RetPtr[i] = (HICON16)icons[i]; } else { GlobalFree16( hRet ); hRet = 0; } HeapFree( GetProcessHeap(), 0, icons ); } return hRet; }