Release 960717 Wed Jul 17 16:10:16 1996 Alexandre Julliard <julliard@lrc.epfl.ch> * [configure.in] Generate include/config.h instead of putting everything on the command-line. Removed -with-malloc-debug option (not useful for end users anyway). Added check for memmove(). * [include/wintypes.h] [*/Makefile.in] Added definition of __WINE__ symbol when compiling Wine code (emulator or library) as opposed to user programs. * [debugger/editline.c] [debugger/readline/*] Moved all the readline code into debugger/editline.c. Removed the readline subdirectory. * [files/profile.c] Added PROFILE_GetWineIniInt(). * [include/stackframe.h] [loader/task.c] The 16-bit stackframe now also exists for Winelib (even though it only ever contains one frame). * [loader/module.c] Added function MODULE_CreateDummyModule() to create a dummy Win16 module for Winelib and Win32. * [memory/ldt.c] Make sure the ldt entry contents will be acceptable for the Linux kernel. * [memory/selector.c] Fixed SetSelectorLimit() when the limit is in pages. * [misc/port.c] Added memmove(). * [miscemu/dpmi.c] Clear the segment registers that contain the selector being freed in int31/ax=0001. Added missing break after SelectorAccessRights call. * [win32/struct32.c] Added conversions for MDICREATESTRUCT. * [windows/winproc.c] Added message conversions for WM_MDICREATE. Tue Jul 16 19:46:24 1996 Pavel Kankovsky <KAN@frode.dcit.cz> * [windows/class.c] Added GetExePtr() call in CLASS_FindClassByAtom(). Mon Jul 15 17:49:38 1996 Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de> * [if1632/*.spec] Some more trivial specs added. * [if1632/gdi32.spec] [objects/font.c][windows/dialog.c] CreateFont32* added, changed to new naming std. * [include/windows.h] [include/mmsystem.h] [include/wintypes.h] Some defines/types added. * [win32/thread.c] TlsSetValue() returns boolean. * [win32/resource.c] [loader/pe_resource.c] [loader/resource.c] [controls/menu.c] [objects/bitmap.c] Cleanup of the resource functions, mostly changes to new naming standard and fixing of argument types so that they agree with the win16/win32 API. Thu Jul 11 15:00:00 1996 Alex Korobka <alex@phm30.pharm.sunysb.edu> * [windows/winpos.c] ShowWindow() fixes. * [windows/mdi.c] Fix reversed LPARAM in WM_MDIACTIVATE. * [wine.ini] New option AllocSystemColors tells Wine how many colors to grab from the system colormap. * [objects/bitblt.c] [objects/dc.c] Fixed pink garbage over Word buttons in PseudoColor. Added optional DSTINVERT shortcut for faster text selection. * [misc/wsprintf.c] Skip bogus segmented pointers in wsvnprintf16(). * [objects/gdiobj.c] Added palette handling to UnrealizeObject(). * [objects/color.c] [objects/palette.c] [windows/dce.c] Wine gets palette manager with support for more than 20 colors. Only PseudoColor and TrueColor visuals tested so far. * [windows/winpos.c] [windows/win.c] Set X size hints for WS_EX_DLGMODALFRAME windows (no resize) and use XReconfigureWMWindows() instead of XConfigureWindow() in managed mode. * [memory/global.c] Do not allocate more than 640K of DOS memory. * [misc/main.c] Do not allow -desktop and -managed together.
diff --git a/loader/Makefile.in b/loader/Makefile.in index 166ce95..ba99e39 100644 --- a/loader/Makefile.in +++ b/loader/Makefile.in
@@ -1,3 +1,4 @@ +DEFS = -D__WINE__ TOPSRC = @top_srcdir@ MODULE = loader
diff --git a/loader/builtin.c b/loader/builtin.c index 73ebcd5..4717f66 100644 --- a/loader/builtin.c +++ b/loader/builtin.c
@@ -199,7 +199,7 @@ */ HMODULE16 BUILTIN_LoadModule( LPCSTR name, BOOL16 force ) { - HMODULE hModule; + HMODULE16 hModule; NE_MODULE *pModule; BUILTIN_DLL *table; char dllname[16], *p;
diff --git a/loader/module.c b/loader/module.c index 63c44e2..31a998b 100644 --- a/loader/module.c +++ b/loader/module.c
@@ -194,7 +194,7 @@ */ void MODULE_WalkModules(void) { - HMODULE hModule = hFirstModule; + HMODULE16 hModule = hFirstModule; fprintf( stderr, "Module Flags Name\n" ); while (hModule) { @@ -369,6 +369,84 @@ /*********************************************************************** + * MODULE_CreateDummyModule + * + * Create a dummy NE module for Win32 or Winelib. + */ +HMODULE16 MODULE_CreateDummyModule( const OFSTRUCT *ofs ) +{ + HMODULE16 hModule; + NE_MODULE *pModule; + SEGTABLEENTRY *pSegment; + char *pStr; + + INT32 of_size = sizeof(OFSTRUCT) - sizeof(ofs->szPathName) + + strlen(ofs->szPathName) + 1; + INT32 size = sizeof(NE_MODULE) + + /* loaded file info */ + of_size + + /* segment table: DS,CS */ + 2 * sizeof(SEGTABLEENTRY) + + /* name table */ + 9 + + /* several empty tables */ + 8; + + hModule = GlobalAlloc16( GMEM_MOVEABLE | GMEM_ZEROINIT, size ); + if (!hModule) return (HMODULE16)11; /* invalid exe */ + + FarSetOwner( hModule, hModule ); + pModule = (NE_MODULE *)GlobalLock16( hModule ); + + /* Set all used entries */ + pModule->magic = NE_SIGNATURE; + pModule->count = 1; + pModule->next = 0; + pModule->flags = 0; + pModule->dgroup = 1; + pModule->ss = 1; + pModule->cs = 2; + pModule->heap_size = 0xe000; + pModule->stack_size = 0x1000; + pModule->seg_count = 2; + pModule->modref_count = 0; + pModule->nrname_size = 0; + pModule->fileinfo = sizeof(NE_MODULE); + pModule->os_flags = NE_OSFLAGS_WINDOWS; + pModule->expected_version = 0x030a; + pModule->self = hModule; + + /* Set loaded file information */ + memcpy( pModule + 1, ofs, of_size ); + ((OFSTRUCT *)(pModule+1))->cBytes = of_size - 1; + + pSegment = (SEGTABLEENTRY*)((char*)(pModule + 1) + of_size); + pModule->seg_table = pModule->dgroup_entry = (int)pSegment - (int)pModule; + /* Data segment */ + pSegment->size = 0; + pSegment->flags = NE_SEGFLAGS_DATA; + pSegment->minsize = 0x1000; + pSegment++; + /* Code segment */ + pSegment->flags = 0; + pSegment++; + + /* Module name */ + pStr = (char *)pSegment; + pModule->name_table = (int)pStr - (int)pModule; + strcpy( pStr, "\x08W32SXXXX" ); + pStr += 9; + + /* All tables zero terminated */ + pModule->res_table = pModule->import_table = pModule->entry_table = + (int)pStr - (int)pModule; + + MODULE_RegisterModule( pModule ); + return hModule; +} + + +/*********************************************************************** * MODULE_LoadExeHeader */ static HMODULE16 MODULE_LoadExeHeader( HFILE hFile, OFSTRUCT *ofs ) @@ -932,6 +1010,7 @@ HANDLE hInstance, hPrevInstance; NE_MODULE *pModule; LOADPARAMS *params = (LOADPARAMS *)paramBlock; + OFSTRUCT ofs; #ifndef WINELIB WORD *pModRef, *pDLLs; HFILE hFile; @@ -941,8 +1020,6 @@ if (!hModule) /* We have to load the module */ { - OFSTRUCT ofs; - /* Try to load the built-in first if not disabled */ if ((hModule = BUILTIN_LoadModule( name, FALSE ))) return hModule; @@ -1134,13 +1211,11 @@ pModule->count++; } #else - hModule = GlobalAlloc16( GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof(NE_MODULE)); + lstrcpyn32A( ofs.szPathName, name, sizeof(ofs.szPathName) ); + if ((hModule = MODULE_CreateDummyModule( &ofs )) < 32) return hModule; pModule = (NE_MODULE *)GlobalLock16( hModule ); - pModule->count = 1; - pModule->magic = NE_SIGNATURE; - pModule->self = hModule; hPrevInstance = 0; - hInstance = MODULE_CreateInstance( hModule, (LOADPARAMS*)paramBlock ); + hInstance = MODULE_CreateInstance( hModule, params ); #endif /* WINELIB */ /* Create a task for this instance */
diff --git a/loader/ne_image.c b/loader/ne_image.c index 359242b..ad5af2f 100644 --- a/loader/ne_image.c +++ b/loader/ne_image.c
@@ -30,13 +30,13 @@ /*********************************************************************** * NE_LoadSegment */ -BOOL NE_LoadSegment( HMODULE hModule, WORD segnum ) +BOOL NE_LoadSegment( HMODULE16 hModule, WORD segnum ) { NE_MODULE *pModule; SEGTABLEENTRY *pSegTable, *pSeg; WORD *pModuleTable; WORD count, i, offset; - HMODULE module; + HMODULE16 module; FARPROC16 address; int fd; struct relocation_entry_s *rep, *reloc_entries; @@ -449,7 +449,7 @@ * * Call the DLL initialization code */ -static BOOL NE_InitDLL( HMODULE hModule ) +static BOOL NE_InitDLL( HMODULE16 hModule ) { #ifndef WINELIB int cs_reg, ds_reg, ip_reg, cx_reg, di_reg, bp_reg; @@ -498,7 +498,7 @@ pModule->cs = 0; /* Don't initialize it twice */ dprintf_dll( stddeb, "Calling LibMain, cs:ip=%04x:%04x ds=%04x di=%04x cx=%04x\n", cs_reg, ip_reg, ds_reg, di_reg, cx_reg ); - return CallTo16_regs_( (FARPROC)(cs_reg << 16 | ip_reg), ds_reg, + return CallTo16_regs_( (FARPROC16)(cs_reg << 16 | ip_reg), ds_reg, 0 /*es*/, 0 /*bp*/, 0 /*ax*/, 0 /*bx*/, cx_reg, 0 /*dx*/, 0 /*si*/, di_reg ); #else @@ -513,10 +513,10 @@ * * Initialize the loaded DLLs. */ -void NE_InitializeDLLs( HMODULE hModule ) +void NE_InitializeDLLs( HMODULE16 hModule ) { NE_MODULE *pModule; - HMODULE *pDLL; + HMODULE16 *pDLL; if (!(pModule = MODULE_GetPtr( hModule ))) return; if (pModule->flags & NE_FFLAGS_WIN32) @@ -528,7 +528,7 @@ { HANDLE to_init = pModule->dlls_to_init; pModule->dlls_to_init = 0; - for (pDLL = (HMODULE *)GlobalLock16( to_init ); *pDLL; pDLL++) + for (pDLL = (HMODULE16 *)GlobalLock16( to_init ); *pDLL; pDLL++) { NE_InitializeDLLs( *pDLL ); NE_InitDLL( *pDLL );
diff --git a/loader/ne_resource.c b/loader/ne_resource.c index 289e346..bd74e65 100644 --- a/loader/ne_resource.c +++ b/loader/ne_resource.c
@@ -30,7 +30,7 @@ * Find the type and resource id from their names. * Return value is MAKELONG( typeId, resId ), or 0 if not found. */ -static DWORD NE_FindNameTableId( HMODULE hModule, SEGPTR typeId, SEGPTR resId ) +static DWORD NE_FindNameTableId( HMODULE16 hModule, SEGPTR typeId, SEGPTR resId ) { NE_MODULE *pModule; NE_TYPEINFO *pTypeInfo; @@ -52,9 +52,9 @@ { dprintf_resource( stddeb, "NameTable entry: type=%04x id=%04x\n", pTypeInfo->type_id, pNameInfo->id ); - handle = LoadResource( hModule, + handle = LoadResource16( hModule, (HANDLE)((int)pNameInfo - (int)pModule) ); - for(p = (WORD*)LockResource(handle); p && *p; p = (WORD *)((char*)p+*p)) + for(p = (WORD*)LockResource16(handle); p && *p; p = (WORD *)((char*)p+*p)) { dprintf_resource( stddeb," type=%04x '%s' id=%04x '%s'\n", p[1], (char *)(p+3), p[2], @@ -88,7 +88,7 @@ ret = MAKELONG( p[1], p[2] ); break; } - FreeResource( handle ); + FreeResource16( handle ); if (ret) return ret; } } @@ -134,7 +134,7 @@ /*********************************************************************** * NE_FindResource */ -HRSRC NE_FindResource( HMODULE hModule, SEGPTR typeId, SEGPTR resId ) +HRSRC NE_FindResource( HMODULE16 hModule, SEGPTR typeId, SEGPTR resId ) { NE_TYPEINFO *pTypeInfo; HRSRC hRsrc; @@ -211,7 +211,7 @@ /*********************************************************************** * NE_AllocResource */ -HGLOBAL NE_AllocResource( HMODULE hModule, HRSRC hRsrc, DWORD size ) +HGLOBAL NE_AllocResource( HMODULE16 hModule, HRSRC hRsrc, DWORD size ) { NE_NAMEINFO *pNameInfo=NULL; WORD sizeShift; @@ -231,7 +231,7 @@ /*********************************************************************** * NE_AccessResource */ -int NE_AccessResource( HMODULE hModule, HRSRC hRsrc ) +int NE_AccessResource( HMODULE16 hModule, HRSRC hRsrc ) { NE_NAMEINFO *pNameInfo=NULL; int fd; @@ -254,7 +254,7 @@ /*********************************************************************** * NE_SizeofResource */ -DWORD NE_SizeofResource( HMODULE hModule, HRSRC hRsrc ) +DWORD NE_SizeofResource( HMODULE16 hModule, HRSRC hRsrc ) { NE_NAMEINFO *pNameInfo=NULL; WORD sizeShift; @@ -272,7 +272,7 @@ /*********************************************************************** * NE_LoadResource */ -HGLOBAL NE_LoadResource( HMODULE hModule, HRSRC hRsrc ) +HGLOBAL NE_LoadResource( HMODULE16 hModule, HRSRC hRsrc ) { NE_NAMEINFO *pNameInfo=NULL; WORD sizeShift; @@ -307,7 +307,7 @@ /*********************************************************************** * NE_LockResource */ -SEGPTR NE_LockResource( HMODULE hModule, HGLOBAL handle ) +SEGPTR NE_LockResource( HMODULE16 hModule, HGLOBAL handle ) { /* May need to reload the resource if discarded */ @@ -318,7 +318,7 @@ /*********************************************************************** * NE_FreeResource */ -BOOL NE_FreeResource( HMODULE hModule, HGLOBAL handle ) +BOOL NE_FreeResource( HMODULE16 hModule, HGLOBAL handle ) { NE_TYPEINFO *pTypeInfo; NE_NAMEINFO *pNameInfo; @@ -346,7 +346,7 @@ } pTypeInfo = (NE_TYPEINFO *)pNameInfo; } - fprintf( stderr, "FreeResource: %04x %04x not found!\n", hModule, handle ); + fprintf( stderr, "NE_FreeResource: %04x %04x not found!\n", hModule, handle ); return handle; } #endif /* WINELIB */
diff --git a/loader/pe_image.c b/loader/pe_image.c index e95c39f..4dad04b 100644 --- a/loader/pe_image.c +++ b/loader/pe_image.c
@@ -122,7 +122,7 @@ if(strcmp(ename,funcName)==0) return (FARPROC32)(load_addr + *function); }else{ - if(funcName == (int)*ordinal + exports->Base) + if((int)funcName == (int)*ordinal + exports->Base) return (FARPROC32)(load_addr + *function); } function++; @@ -132,14 +132,14 @@ return NULL; } -void fixup_imports(struct pe_data *pe, HMODULE hModule) +void fixup_imports(struct pe_data *pe, HMODULE16 hModule) { struct PE_Import_Directory * pe_imp; int fixup_failed=0; unsigned int load_addr = pe->load_addr; int i; NE_MODULE *ne_mod; - HMODULE *mod_ptr; + HMODULE16 *mod_ptr; /* OK, now dump the import list */ dprintf_win32(stddeb, "\nDumping imports list\n"); @@ -151,7 +151,7 @@ /* Now, allocate memory for dlls_to_init */ ne_mod = GlobalLock16(hModule); - ne_mod->dlls_to_init = GLOBAL_Alloc(GMEM_ZEROINIT,(i+1) * sizeof(HMODULE), + ne_mod->dlls_to_init = GLOBAL_Alloc(GMEM_ZEROINIT,(i+1) * sizeof(HMODULE16), hModule, FALSE, FALSE, FALSE ); mod_ptr = GlobalLock16(ne_mod->dlls_to_init); /* load the modules and put their handles into the list */ @@ -159,7 +159,7 @@ { char *name = (char*)load_addr+pe_imp->ModuleName; mod_ptr[i] = LoadModule(name,(LPVOID)-1); - if(mod_ptr[i]<=(HMODULE)32) + if(mod_ptr[i]<=(HMODULE16)32) { char *p, buffer[256]; @@ -169,7 +169,7 @@ strcpy( p + 1, name ); mod_ptr[i] = LoadModule( buffer, (LPVOID)-1 ); } - if(mod_ptr[i]<=(HMODULE)32) + if(mod_ptr[i]<=(HMODULE16)32) { fprintf(stderr,"Module %s not found\n",name); exit(0); @@ -349,7 +349,7 @@ * PE_LoadImage * Load one PE format executable into memory */ -static struct pe_data *PE_LoadImage( int fd, HMODULE hModule, WORD offset ) +static struct pe_data *PE_LoadImage( int fd, HMODULE16 hModule, WORD offset ) { struct pe_data *pe; int i, result; @@ -433,16 +433,9 @@ if(strcmp(pe->pe_seg[i].Name, ".edata") == 0) pe->pe_export = (struct PE_Export_Directory *) result; - if(strcmp(pe->pe_seg[i].Name, ".rsrc") == 0) { + if(strcmp(pe->pe_seg[i].Name, ".rsrc") == 0) pe->pe_resource = (struct PE_Resource_Directory *) result; -#if 0 -/* FIXME pe->resource_offset should be deleted from structure if this - ifdef doesn't break anything */ - /* save offset for PE_FindResource */ - pe->resource_offset = pe->pe_seg[i].Virtual_Address - - pe->pe_seg[i].PointerToRawData; -#endif - } + if(strcmp(pe->pe_seg[i].Name, ".reloc") == 0) pe->pe_reloc = (struct PE_Reloc_Block *) result; @@ -522,113 +515,45 @@ return pe; } -HINSTANCE MODULE_CreateInstance(HMODULE hModule,LOADPARAMS *params); +HINSTANCE MODULE_CreateInstance(HMODULE16 hModule,LOADPARAMS *params); void InitTask( SIGCONTEXT *context ); HINSTANCE PE_LoadModule( int fd, OFSTRUCT *ofs, LOADPARAMS* params ) { - PE_MODULE *pe; - int size, of_size; - NE_MODULE *pModule; - SEGTABLEENTRY *pSegment; - char *pStr; - DWORD cts; - HMODULE hModule; - HINSTANCE hInstance; - struct mz_header_s mz_header; + HMODULE16 hModule; + HINSTANCE16 hInstance; + NE_MODULE *pModule; + SEGTABLEENTRY *pSegment; + FARPROC16 startup; + struct mz_header_s mz_header; - lseek(fd,0,SEEK_SET); - read( fd, &mz_header, sizeof(mz_header) ); + if ((hModule = MODULE_CreateDummyModule( ofs )) < 32) return hModule; + pModule = (NE_MODULE *)GlobalLock16( hModule ); + pModule->flags = NE_FFLAGS_WIN32; - of_size = sizeof(OFSTRUCT) - sizeof(ofs->szPathName) - + strlen(ofs->szPathName) + 1; - size = sizeof(NE_MODULE) + - /* loaded file info */ - of_size + - /* segment table: DS,CS */ - 2 * sizeof(SEGTABLEENTRY) + - /* name table */ - 9 + - /* several empty tables */ - 8; + lseek( fd, 0, SEEK_SET ); + read( fd, &mz_header, sizeof(mz_header) ); - hModule = GlobalAlloc16( GMEM_MOVEABLE | GMEM_ZEROINIT, size ); - if (!hModule) return (HINSTANCE)11; /* invalid exe */ + /* Set the startup address */ - FarSetOwner( hModule, hModule ); - - pModule = (NE_MODULE*)GlobalLock16(hModule); + startup = MODULE_GetWndProcEntry16("Win32CallToStart"); + pSegment = NE_SEG_TABLE(pModule) + pModule->cs - 1; + pSegment->selector = SELECTOROF(startup); /* FIXME */ + pModule->ip = OFFSETOF(startup); - /* Set all used entries */ - pModule->magic=NE_SIGNATURE; - pModule->count=1; - pModule->next=0; - pModule->flags=NE_FFLAGS_WIN32; - pModule->dgroup=1; - pModule->ss=1; - pModule->cs=2; - /* Who wants to LocalAlloc for a PE Module? */ - pModule->heap_size=0x1000; - pModule->stack_size=0xF000; - pModule->seg_count=1; - pModule->modref_count=0; - pModule->nrname_size=0; - pModule->fileinfo=sizeof(NE_MODULE); - pModule->os_flags=NE_OSFLAGS_WINDOWS; - pModule->expected_version=0x30A; - pModule->self = hModule; + pModule->pe_module = PE_LoadImage( fd, hModule, mz_header.ne_offset ); - /* Set loaded file information */ - memcpy( pModule + 1, ofs, of_size ); - ((OFSTRUCT *)(pModule+1))->cBytes = of_size - 1; + hInstance = MODULE_CreateInstance( hModule, params ); - pSegment=(SEGTABLEENTRY*)((char*)(pModule + 1) + of_size); - pModule->seg_table=pModule->dgroup_entry=(int)pSegment-(int)pModule; - pSegment->size=0; - pSegment->flags=NE_SEGFLAGS_DATA; - pSegment->minsize=0x1000; - pSegment++; - - cts=(DWORD)MODULE_GetWndProcEntry16("Win32CallToStart"); -#ifdef WINELIB32 - pSegment->selector=(void*)cts; - pModule->ip=0; -#else - pSegment->selector=cts>>16; /* FIXME!! */ - pModule->ip=cts & 0xFFFF; -#endif - pSegment++; - - pStr=(char*)pSegment; - pModule->name_table=(int)pStr-(int)pModule; - strcpy(pStr,"\x08W32SXXXX"); - pStr+=9; - - /* All tables zero terminated */ - pModule->res_table=pModule->import_table=pModule->entry_table= - (int)pStr-(int)pModule; - - MODULE_RegisterModule( pModule ); - - pe = PE_LoadImage( fd, hModule, mz_header.ne_offset ); - - pModule->pe_module = pe; - pModule->heap_size=0x1000; - pModule->stack_size=0xE000; - - /* CreateInstance allocates now 64KB */ - hInstance=MODULE_CreateInstance(hModule,NULL /* FIX: NULL? really? */); - - /* FIXME: Is this really the correct place to initialise the DLL? */ - if ((pe->pe_header->coff.Characteristics & IMAGE_FILE_DLL)) { -/* PE_InitDLL(hModule); */ - } else { - TASK_CreateTask(hModule,hInstance,0, - params->hEnvironment,(LPSTR)PTR_SEG_TO_LIN(params->cmdLine), - *((WORD*)PTR_SEG_TO_LIN(params->showCmd)+1)); - PE_InitializeDLLs(hModule); - } - return hInstance; + if (!(pModule->pe_module->pe_header->coff.Characteristics & IMAGE_FILE_DLL)) + { + TASK_CreateTask( hModule, hInstance, 0, + params->hEnvironment, + (LPSTR)PTR_SEG_TO_LIN( params->cmdLine ), + *((WORD*)PTR_SEG_TO_LIN(params->showCmd) + 1) ); + PE_InitializeDLLs( hModule ); + } + return hInstance; } int USER_InitApp(HINSTANCE hInstance); @@ -637,29 +562,29 @@ void PE_Win32CallToStart( SIGCONTEXT *context ) { int fs; - HMODULE hModule; + HMODULE16 hModule; NE_MODULE *pModule; dprintf_win32(stddeb,"Going to start Win32 program\n"); - InitTask( &context ); + InitTask( context ); hModule = GetExePtr( GetCurrentTask() ); pModule = MODULE_GetPtr( hModule ); USER_InitApp( hModule ); fs=(int)GlobalAlloc16( GMEM_FIXED | GMEM_ZEROINIT, 0x10000 ); PE_InitTEB(fs); __asm__ __volatile__("movw %w0,%%fs"::"r" (fs)); - CallTaskStart32( (FARPROC)(pModule->pe_module->load_addr + + CallTaskStart32( (FARPROC32)(pModule->pe_module->load_addr + pModule->pe_module->pe_header->opt_coff.AddressOfEntryPoint) ); } -int PE_UnloadImage( HMODULE hModule ) +int PE_UnloadImage( HMODULE16 hModule ) { printf("PEunloadImage() called!\n"); /* free resources, image, unmap */ return 1; } -static void PE_InitDLL(HMODULE hModule) +static void PE_InitDLL(HMODULE16 hModule) { NE_MODULE *pModule; PE_MODULE *pe; @@ -675,7 +600,7 @@ if (pe->pe_header->coff.Characteristics & IMAGE_FILE_DLL) { printf("InitPEDLL() called!\n"); - CallDLLEntryProc32( (FARPROC)(pe->load_addr + + CallDLLEntryProc32( (FARPROC32)(pe->load_addr + pe->pe_header->opt_coff.AddressOfEntryPoint), hModule, 0, 0 ); } @@ -708,16 +633,16 @@ pTEB->taskid = getpid(); } -void PE_InitializeDLLs(HMODULE hModule) +void PE_InitializeDLLs(HMODULE16 hModule) { NE_MODULE *pModule; - HMODULE *pDLL; + HMODULE16 *pDLL; pModule = MODULE_GetPtr( GetExePtr(hModule) ); if (pModule->dlls_to_init) { HANDLE to_init = pModule->dlls_to_init; pModule->dlls_to_init = 0; - for (pDLL = (HMODULE *)GlobalLock16( to_init ); *pDLL; pDLL++) + for (pDLL = (HMODULE16 *)GlobalLock16( to_init ); *pDLL; pDLL++) { PE_InitializeDLLs( *pDLL ); PE_InitDLL( *pDLL );
diff --git a/loader/pe_resource.c b/loader/pe_resource.c index da19a65..9178772 100644 --- a/loader/pe_resource.c +++ b/loader/pe_resource.c
@@ -1,154 +1,167 @@ #ifndef WINELIB /* - * (c) 1994 Erik Bos <erik@xs4all.nl> + * PE (Portable Execute) File Resources * - * based on Eric Youndale's pe-test and: + * Copyright 1995 Thomas Sandford + * Copyright 1996 Martin von Loewis * - * ftp.microsoft.com:/pub/developer/MSDN/CD8/PEFILE.ZIP + * Based on the Win16 resource handling code in loader/resource.c + * Copyright 1993 Robert J. Amstadt + * Copyright 1995 Alexandre Julliard + * + * This is not even at ALPHA level yet. Don't expect it to work! */ -#include <stdio.h> -#include <stdlib.h> -#include <string.h> #include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> +#include "wintypes.h" #include "windows.h" -#include "ldt.h" -#include "neexe.h" -#include "peexe.h" +#include "kernel32.h" #include "pe_image.h" -#include "resource.h" +#include "module.h" +#include "handle32.h" +#include "libres.h" +#include "resource32.h" +#include "stackframe.h" +#include "neexe.h" +#include "accel.h" +#include "xmalloc.h" +#include "string32.h" #include "stddebug.h" -/* #define DEBUG_RESOURCE */ #include "debug.h" -#if 0 +int language = 0x0409; -static int -find_lang(char *root, struct PE_Resource_Directory *resource, RESOURCE *r) +#define PrintIdA(name) \ + if (HIWORD((DWORD)name)) \ + dprintf_resource( stddeb, "'%s'", name); \ + else \ + dprintf_resource( stddeb, "#%04x", LOWORD(name)); +#define PrintIdW(name) +#define PrintId(name) + +/********************************************************************** + * GetResDirEntryW + * + * Helper function - goes down one level of PE resource tree + * + */ +PIMAGE_RESOURCE_DIRECTORY GetResDirEntryW(PIMAGE_RESOURCE_DIRECTORY resdirptr, + LPCWSTR name, + DWORD root) { - struct PE_Directory_Entry *type_dir; - struct PE_Resource_Leaf_Entry *leaf; + int entrynum; + PIMAGE_RESOURCE_DIRECTORY_ENTRY entryTable; + int namelen; - type_dir = (struct PE_Directory_Entry *)(resource + 1); - type_dir += resource->NumberOfNamedEntries; - - /* grab the 1st resource available */ - leaf = (struct PE_Resource_Leaf_Entry *) (root + type_dir->OffsetToData); - dprintf_resource(stddeb, "\t\tPE_findlang: id %8x\n", (int) type_dir->Name); - dprintf_resource(stddeb, "\t\taddress %ld, size %ld, language id %ld\n", leaf->OffsetToData, leaf->Size, leaf->CodePage); - r->offset = leaf->OffsetToData - r->wpnt->pe->resource_offset; - r->size = leaf->Size; - printf("\t\toffset %d, size %d\n", r->offset, r->size); - return 1; - -/* for(i=0; i< resource->NumberOfIdEntries; i++) { - leaf = (root + (type_dir->OffsetToData & ~IMAGE_RESOURCE_DATA_IS_DIRECTORY)); - dprintf_resource(stddeb, "\t\tPE_findlang: id %8x\n", - (int) type_dir->Name); - dprintf_resource(stddeb, "\t\t%x %x %x\n", leaf->OffsetToData, - leaf->Size, leaf->CodePage); - type_dir++; - } */ -} - -static int -find_resource(char *root, struct PE_Resource_Directory *resource, - LPSTR resource_name, RESOURCE *r) -{ - int i; - char res_name[256]; - struct PE_Directory_Entry *type_dir; - struct PE_Directory_Name_String_U *name; - - type_dir = (struct PE_Directory_Entry *)(resource + 1); - - if (HIWORD((DWORD)resource_name)) { - for(i=0; i< resource->NumberOfNamedEntries; i++) { - name = (struct PE_Directory_Name_String_U *)(root + (type_dir->Name & ~IMAGE_RESOURCE_NAME_IS_STRING)); - memset(res_name, 0, sizeof(res_name)); - my_wcstombs(res_name, name->NameString, name->Length); - dprintf_resource(stddeb, "\tPE_findresource: name %s\n", res_name); - if (lstrcmpi(res_name, resource_name) == 0) - return find_lang(root, (struct PE_Resource_Directory *) (root + (type_dir->OffsetToData & ~IMAGE_RESOURCE_DATA_IS_DIRECTORY)), r); - type_dir++; - } - } else { - type_dir += resource->NumberOfNamedEntries; - for(i=0; i< resource->NumberOfIdEntries; i++) { - dprintf_resource(stddeb, "\tPE_findresource: name %8x\n", (int) type_dir->Name); - if (type_dir->Name == ((int) resource_name & 0xff)) - return find_lang(root, (struct PE_Resource_Directory *) (root + (type_dir->OffsetToData & ~IMAGE_RESOURCE_DATA_IS_DIRECTORY)), r); - type_dir++; - } + if (HIWORD(name)) { + /* FIXME: what about #xxx names? */ + entryTable = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) ( + (BYTE *) resdirptr + + sizeof(IMAGE_RESOURCE_DIRECTORY)); + namelen = lstrlen32W(name); + for (entrynum = 0; entrynum < resdirptr->NumberOfNamedEntries; entrynum++) + { + PIMAGE_RESOURCE_DIR_STRING_U str = + (PIMAGE_RESOURCE_DIR_STRING_U) (root + + (entryTable[entrynum].Name & 0x7fffffff)); + if(namelen != str->Length) + continue; + if(lstrncmpi32W(name,str->NameString,str->Length)==0) + return (PIMAGE_RESOURCE_DIRECTORY) ( + root + + (entryTable[entrynum].OffsetToData & 0x7fffffff)); } - return 0; -} - -static int -find_type(struct PE_Resource_Directory *resource, LPSTR resource_name, - LPSTR type_name) -{ - int i; - char *root, res_name[256]; - struct PE_Directory_Entry *type_dir; - struct PE_Directory_Name_String_U *name; - - root = (char *) resource; - type_dir = (struct PE_Directory_Entry *)(resource + 1); - - if (HIWORD((DWORD)type_name)) { - for(i=0; i< resource->NumberOfNamedEntries; i++) { - name = (struct PE_Directory_Name_String_U *)(root + (type_dir->Name & ~IMAGE_RESOURCE_NAME_IS_STRING)); - memset(res_name, 0, sizeof(res_name)); - my_wcstombs(res_name, name->NameString, name->Length); - dprintf_resource(stddeb, "PE_findtype: type %s\n", - res_name); - if (lstrcmpi(res_name, type_name) == 0) - return find_resource(root, (struct PE_Resource_Directory *) (root + (type_dir->OffsetToData & ~IMAGE_RESOURCE_DATA_IS_DIRECTORY)), resource_name, r); - type_dir++; - } - } else { - type_dir += resource->NumberOfNamedEntries; - for(i=0; i< resource->NumberOfIdEntries; i++) { - dprintf_resource(stddeb, "PE_findtype: type %8x\n", (int) type_dir->Name); - if (type_dir->Name == ((int) type_name & 0xff)) - return find_resource(root, (struct PE_Resource_Directory *) (root + (type_dir->OffsetToData & ~IMAGE_RESOURCE_DATA_IS_DIRECTORY)), resource_name, r); - type_dir++; - } - } - return 0; + return NULL; + } else { + entryTable = (PIMAGE_RESOURCE_DIRECTORY_ENTRY) ( + (BYTE *) resdirptr + + sizeof(IMAGE_RESOURCE_DIRECTORY) + + resdirptr->NumberOfNamedEntries * sizeof(IMAGE_RESOURCE_DIRECTORY_ENTRY)); + for (entrynum = 0; entrynum < resdirptr->NumberOfIdEntries; entrynum++) + if ((DWORD)entryTable[entrynum].Name == (DWORD)name) + return (PIMAGE_RESOURCE_DIRECTORY) ( + root + + (entryTable[entrynum].OffsetToData & 0x7fffffff)); + return NULL; + } } /********************************************************************** - * PE_FindResource [KERNEL.60] + * GetResDirEntryA + * + * Helper function - goes down one level of PE resource tree + * */ -int -PE_FindResource(HANDLE instance, SEGPTR resource_name, SEGPTR type_name, - RESOURCE *r) +PIMAGE_RESOURCE_DIRECTORY GetResDirEntryA(PIMAGE_RESOURCE_DIRECTORY resdirptr, + LPCSTR name, + DWORD root) { - dprintf_resource(stddeb, "PE_FindResource hInst=%04X typename=%08X resname=%08X\n", - instance, (int) type_name, (int) resource_name); - if (HIWORD(resource_name)) - { - char *resource_name_ptr = PTR_SEG_TO_LIN( resource_name ); - if (resource_name_ptr[0] == '#') - resource_name = (SEGPTR) atoi(resource_name_ptr + 1); - else - resource_name = (SEGPTR)resource_name_ptr; - } - if (HIWORD(type_name)) - { - char *type_name_ptr = PTR_SEG_TO_LIN( type_name ); - if (type_name_ptr[0] == '#') - type_name = (SEGPTR) atoi(type_name_ptr + 1); - else - type_name = (SEGPTR) type_name_ptr; - } - return find_type(r->wpnt->pe->pe_resource, resource_name, type_name); + LPWSTR xname; + PIMAGE_RESOURCE_DIRECTORY ret; + + if (HIWORD((DWORD)name)) + xname = STRING32_DupAnsiToUni(name); + else + xname = (LPWSTR)name; + + ret=GetResDirEntryW(resdirptr,xname,root); + if (HIWORD((DWORD)name)) + free(xname); + return ret; +} + +/********************************************************************** + * PE_FindResource32W + */ +HANDLE32 PE_FindResource32W( HINSTANCE hModule, LPCWSTR name, LPCWSTR type ) +{ + PE_MODULE *pe; + NE_MODULE *pModule; + PIMAGE_RESOURCE_DIRECTORY resdirptr; + DWORD root; + HANDLE32 result; + + hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */ + dprintf_resource(stddeb, "FindResource: module=%08x type=", hModule ); + PrintId( type ); + dprintf_resource( stddeb, " name=" ); + PrintId( name ); + dprintf_resource( stddeb, "\n" ); + if (!(pModule = MODULE_GetPtr( hModule ))) return 0; + if (!(pModule->flags & NE_FFLAGS_WIN32)) return 0; /* FIXME? */ + if (!(pe = pModule->pe_module) || !pe->pe_resource) return 0; + + resdirptr = (PIMAGE_RESOURCE_DIRECTORY) pe->pe_resource; + root = (DWORD) resdirptr; + if ((resdirptr = GetResDirEntryW(resdirptr, type, root)) == NULL) + return 0; + if ((resdirptr = GetResDirEntryW(resdirptr, name, root)) == NULL) + return 0; + result = (HANDLE32)GetResDirEntryW(resdirptr, (LPCWSTR)language, root); + /* Try LANG_NEUTRAL, too */ + if(!result) + return (HANDLE32)GetResDirEntryW(resdirptr, (LPCWSTR)0, root); + return result; +} + + +/********************************************************************** + * PE_LoadResource32 + */ +HANDLE32 PE_LoadResource32( HINSTANCE hModule, HANDLE32 hRsrc ) +{ + NE_MODULE *pModule; + PE_MODULE *pe; + + if (!hModule) hModule = GetTaskDS(); /* FIXME: see FindResource32W */ + hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */ + dprintf_resource(stddeb, "PE_LoadResource32: module=%04x res=%04x\n", + hModule, hRsrc ); + if (!hRsrc) return 0; + + if (!(pModule = MODULE_GetPtr( hModule ))) return 0; + if (!(pModule->flags & NE_FFLAGS_WIN32)) return 0; /* FIXME? */ + if (!(pe = pModule->pe_module) || !pe->pe_resource) return 0; + return (HANDLE32) (pe->load_addr+((PIMAGE_RESOURCE_DATA_ENTRY)hRsrc)->OffsetToData); } #endif - -#endif /* WINELIB */
diff --git a/loader/resource.c b/loader/resource.c index 9f0aa83..cea0057 100644 --- a/loader/resource.c +++ b/loader/resource.c
@@ -23,6 +23,8 @@ #include "stddebug.h" #include "debug.h" #include "libres.h" +#include "string32.h" +#include "xmalloc.h" #define PrintId(name) \ if (HIWORD((DWORD)name)) \ @@ -32,14 +34,14 @@ /********************************************************************** - * FindResource (KERNEL.60) + * FindResource16 (KERNEL.60) */ -HRSRC FindResource( HMODULE hModule, SEGPTR name, SEGPTR type ) +HRSRC16 FindResource16( HMODULE16 hModule, SEGPTR name, SEGPTR type ) { NE_MODULE *pModule; hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */ - dprintf_resource(stddeb, "FindResource: module=%04x type=", hModule ); + dprintf_resource(stddeb, "FindResource16: module=%04x type=", hModule ); PrintId( type ); if (HIWORD(name)) /* Check for '#xxx' name */ { @@ -55,7 +57,7 @@ #ifndef WINELIB if (pModule->flags & NE_FFLAGS_WIN32) { - fprintf(stderr,"Don't know how to FindResource() for Win32 module\n"); + fprintf(stderr,"Don't know how to FindResource16() for Win32 module\n"); return 0; } return NE_FindResource( hModule, type, name ); @@ -66,21 +68,67 @@ /********************************************************************** - * LoadResource (KERNEL.61) + * FindResource32A (KERNEL32.128) */ -HGLOBAL LoadResource( HMODULE hModule, HRSRC hRsrc ) +HANDLE32 FindResource32A( HINSTANCE32 hModule, LPCSTR name, LPCSTR type ) +{ + LPWSTR xname,xtype; + HANDLE32 ret; + + if (HIWORD((DWORD)name)) xname = STRING32_DupAnsiToUni(name); + else xname = (LPWSTR)name; + if (HIWORD((DWORD)type)) xtype = STRING32_DupAnsiToUni(type); + else xtype = (LPWSTR)type; + ret = FindResource32W(hModule,xname,xtype); + if (HIWORD((DWORD)name)) free(xname); + if (HIWORD((DWORD)type)) free(xtype); + return ret; +} + + +/********************************************************************** + * FindResource32W (KERNEL32.131) + */ +HRSRC32 FindResource32W( HINSTANCE32 hModule, LPCWSTR name, LPCWSTR type ) +{ +#ifndef WINELIB + NE_MODULE *pModule; + + /* Sometimes we get passed hModule = 0x00000000. FIXME: is GetTaskDS() + * ok? + */ + if (!hModule) hModule = GetTaskDS(); + hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */ + dprintf_resource(stddeb, "FindResource32W: module=%08x type=", hModule ); + PrintId( type ); + dprintf_resource( stddeb, " name=" ); + PrintId( name ); + dprintf_resource( stddeb, "\n" ); + if (!(pModule = MODULE_GetPtr( hModule ))) return 0; + if (!(pModule->flags & NE_FFLAGS_WIN32)) return 0; + return PE_FindResource32W(hModule,name,type); +#else + return LIBRES_FindResource( hModule, name, type ); +#endif +} + + +/********************************************************************** + * LoadResource16 (KERNEL.61) + */ +HGLOBAL16 LoadResource16( HMODULE16 hModule, HRSRC16 hRsrc ) { NE_MODULE *pModule; hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */ - dprintf_resource(stddeb, "LoadResource: module=%04x res=%04x\n", + dprintf_resource(stddeb, "LoadResource16: module=%04x res=%04x\n", hModule, hRsrc ); if (!hRsrc) return 0; if (!(pModule = MODULE_GetPtr( hModule ))) return 0; #ifndef WINELIB if (pModule->flags & NE_FFLAGS_WIN32) { - fprintf(stderr,"Don't know how to LoadResource() for Win32 module\n"); + fprintf(stderr,"Don't know how to LoadResource16() for Win32 module\n"); return 0; } return NE_LoadResource( hModule, hRsrc ); @@ -89,15 +137,41 @@ #endif } +/********************************************************************** + * LoadResource32 (KERNEL32.370) + */ +HGLOBAL32 LoadResource32( HINSTANCE32 hModule, HRSRC32 hRsrc ) +{ +#ifndef WINELIB + NE_MODULE *pModule; + + if (!hModule) hModule = GetTaskDS(); /* FIXME: see FindResource32W */ + hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */ + dprintf_resource(stddeb, "LoadResource32: module=%04x res=%04x\n", + hModule, hRsrc ); + if (!hRsrc) return 0; + + if (!(pModule = MODULE_GetPtr( hModule ))) return 0; + if (!(pModule->flags & NE_FFLAGS_WIN32)) + { + fprintf(stderr,"LoadResource32: tried to load a non win32 resource.\n"); + return 0; /* FIXME? */ + } + return PE_LoadResource32(hModule,hRsrc); +#else + return LIBRES_LoadResource( hModule, hRsrc ); +#endif +} + /********************************************************************** * LockResource (KERNEL.62) */ /* 16-bit version */ -SEGPTR WIN16_LockResource( HGLOBAL handle ) +SEGPTR WIN16_LockResource16(HGLOBAL16 handle) { #ifndef WINELIB - HMODULE hModule; + HMODULE16 hModule; NE_MODULE *pModule; dprintf_resource(stddeb, "LockResource: handle=%04x\n", handle ); @@ -115,11 +189,11 @@ #endif } -/* 32-bit version */ -LPVOID LockResource( HGLOBAL handle ) +/* WINELIB 16-bit version */ +LPVOID LockResource16( HGLOBAL16 handle ) { #ifndef WINELIB - HMODULE hModule; + HMODULE16 hModule; NE_MODULE *pModule; dprintf_resource(stddeb, "LockResource: handle=%04x\n", handle ); @@ -128,7 +202,7 @@ if (!(pModule = MODULE_GetPtr( hModule ))) return 0; if (pModule->flags & NE_FFLAGS_WIN32) { - fprintf(stderr,"Don't know how to LockResource() for Win32 module\n"); + fprintf(stderr,"Don't know how to LockResource16() for Win32 module\n"); return 0; } return (LPSTR)PTR_SEG_TO_LIN( NE_LockResource( hModule, handle ) ); @@ -139,21 +213,30 @@ /********************************************************************** - * FreeResource (KERNEL.63) + * LockResource32 (KERNEL32.384) */ -BOOL FreeResource( HGLOBAL handle ) +LPVOID LockResource32( HGLOBAL32 handle ) +{ + return (LPVOID)handle; +} + + +/********************************************************************** + * FreeResource16 (KERNEL.63) + */ +BOOL16 FreeResource16( HGLOBAL16 handle ) { #ifndef WINELIB - HMODULE hModule; + HMODULE16 hModule; NE_MODULE *pModule; - dprintf_resource(stddeb, "FreeResource: handle=%04x\n", handle ); + dprintf_resource(stddeb, "FreeResource16: handle=%04x\n", handle ); if (!handle) return FALSE; hModule = GetExePtr( handle ); if (!(pModule = MODULE_GetPtr( hModule ))) return 0; if (pModule->flags & NE_FFLAGS_WIN32) { - fprintf(stderr,"Don't know how to FreeResource() for Win32 module\n"); + fprintf(stderr,"Don't know how to FreeResource16() for Win32 module\n"); return 0; } return NE_FreeResource( hModule, handle ); @@ -162,23 +245,32 @@ #endif } +/********************************************************************** + * FreeResource32 (KERNEL32.145) + */ +BOOL32 FreeResource32( HGLOBAL32 handle ) +{ + /* no longer used in Win32 */ + return TRUE; +} + /********************************************************************** - * AccessResource (KERNEL.64) + * AccessResource16 (KERNEL.64) */ -INT AccessResource( HINSTANCE hModule, HRSRC hRsrc ) +INT16 AccessResource16( HINSTANCE16 hModule, HRSRC16 hRsrc ) { NE_MODULE *pModule; hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */ - dprintf_resource(stddeb, "AccessResource: module=%04x res=%04x\n", + dprintf_resource(stddeb, "AccessResource16: module=%04x res=%04x\n", hModule, hRsrc ); if (!hRsrc) return 0; if (!(pModule = MODULE_GetPtr( hModule ))) return 0; #ifndef WINELIB if (pModule->flags & NE_FFLAGS_WIN32) { - fprintf(stderr,"Don't know how to AccessResource() for Win32 module\n"); + fprintf(stderr,"Don't know how to AccessResource16() for Win32 module\n"); return 0; } return NE_AccessResource( hModule, hRsrc ); @@ -189,20 +281,34 @@ /********************************************************************** - * SizeofResource (KERNEL.65) + * AccessResource32 (KERNEL32.64) */ -DWORD SizeofResource( HMODULE hModule, HRSRC hRsrc ) +INT32 AccessResource32( HINSTANCE32 hModule, HRSRC32 hRsrc ) +{ + hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */ + dprintf_resource(stddeb, "AccessResource: module=%04x res=%04x\n", + hModule, hRsrc ); + if (!hRsrc) return 0; + fprintf(stderr,"AccessResource32: not implemented\n"); + return 0; +} + + +/********************************************************************** + * SizeofResource16 (KERNEL.65) + */ +DWORD SizeofResource16( HMODULE16 hModule, HRSRC16 hRsrc ) { NE_MODULE *pModule; hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */ - dprintf_resource(stddeb, "SizeofResource: module=%04x res=%04x\n", + dprintf_resource(stddeb, "SizeofResource16: module=%04x res=%04x\n", hModule, hRsrc ); if (!(pModule = MODULE_GetPtr( hModule ))) return 0; #ifndef WINELIB if (pModule->flags & NE_FFLAGS_WIN32) { - fprintf(stderr,"Don't know how to SizeOfResource() for Win32 module\n"); + fprintf(stderr,"Don't know how to SizeOfResource16() for Win32 module\n"); return 0; } return NE_SizeofResource( hModule, hRsrc ); @@ -213,9 +319,22 @@ /********************************************************************** - * AllocResource (KERNEL.66) + * SizeofResource32 (KERNEL32.522) */ -HGLOBAL AllocResource( HMODULE hModule, HRSRC hRsrc, DWORD size ) +DWORD SizeofResource32( HINSTANCE32 hModule, HRSRC32 hRsrc ) +{ + hModule = GetExePtr( hModule ); /* In case we were passed an hInstance */ + dprintf_resource(stddeb, "SizeofResource32: module=%04x res=%04x\n", + hModule, hRsrc ); + fprintf(stderr,"SizeofResource32: not implemented\n"); + return 0; +} + + +/********************************************************************** + * AllocResource16 (KERNEL.66) + */ +HGLOBAL16 AllocResource16( HMODULE16 hModule, HRSRC16 hRsrc, DWORD size ) { NE_MODULE *pModule; @@ -255,13 +374,13 @@ /********************************************************************** - * LoadAccelerators [USER.177] + * LoadAccelerators16 [USER.177] */ -HANDLE LoadAccelerators(HANDLE instance, SEGPTR lpTableName) +HACCEL16 LoadAccelerators16(HINSTANCE16 instance, SEGPTR lpTableName) { - HANDLE hAccel; - HANDLE rsc_mem; - HRSRC hRsrc; + HACCEL16 hAccel; + HGLOBAL16 rsc_mem; + HRSRC16 hRsrc; BYTE *lp; ACCELHEADER *lpAccelTbl; int i, n; @@ -273,12 +392,12 @@ dprintf_accel( stddeb, "LoadAccelerators: %04x %04x\n", instance, LOWORD(lpTableName) ); - if (!(hRsrc = FindResource( instance, lpTableName, RT_ACCELERATOR ))) + if (!(hRsrc = FindResource16( instance, lpTableName, RT_ACCELERATOR ))) return 0; - if (!(rsc_mem = LoadResource( instance, hRsrc ))) return 0; + if (!(rsc_mem = LoadResource16( instance, hRsrc ))) return 0; - lp = (BYTE *)LockResource(rsc_mem); - n = SizeofResource( instance, hRsrc ) / sizeof(ACCELENTRY); + lp = (BYTE *)LockResource16(rsc_mem); + n = SizeofResource16(instance,hRsrc)/sizeof(ACCELENTRY); hAccel = GlobalAlloc16(GMEM_MOVEABLE, sizeof(ACCELHEADER) + (n + 1)*sizeof(ACCELENTRY)); lpAccelTbl = (LPACCELHEADER)GlobalLock16(hAccel); @@ -297,10 +416,78 @@ lpAccelTbl->wCount++; } GlobalUnlock16(hAccel); - FreeResource( rsc_mem ); + FreeResource16( rsc_mem ); return hAccel; } - + +/********************************************************************** + * LoadAccelerators32W [USER.177] + */ +HACCEL32 LoadAccelerators32W(HINSTANCE32 instance,LPCWSTR lpTableName) +{ +#if 0 + HACCEL32 hAccel; + HGLOBAL32 rsc_mem; + HRSRC32 hRsrc; + BYTE *lp; + ACCELHEADER *lpAccelTbl; + int i, n; + + if (HIWORD(lpTableName)) + dprintf_accel( stddeb, "LoadAccelerators: %04x '%s'\n", + instance, (char *)( lpTableName ) ); + else + dprintf_accel( stddeb, "LoadAccelerators: %04x %04x\n", + instance, LOWORD(lpTableName) ); + + if (!(hRsrc = FindResource32W( instance, lpTableName, + (LPCWSTR)RT_ACCELERATOR ))) + return 0; + if (!(rsc_mem = LoadResource32( instance, hRsrc ))) return 0; + + lp = (BYTE *)LockResource32(rsc_mem); + n = SizeofResource32(instance,hRsrc)/sizeof(ACCELENTRY); + hAccel = GlobalAlloc16(GMEM_MOVEABLE, + sizeof(ACCELHEADER) + (n + 1)*sizeof(ACCELENTRY)); + lpAccelTbl = (LPACCELHEADER)GlobalLock16(hAccel); + lpAccelTbl->wCount = 0; + for (i = 0; i < n; i++) { + lpAccelTbl->tbl[i].type = *(lp++); + lpAccelTbl->tbl[i].wEvent = *((WORD *)lp); + lp += 2; + lpAccelTbl->tbl[i].wIDval = *((WORD *)lp); + lp += 2; + if (lpAccelTbl->tbl[i].wEvent == 0) break; + dprintf_accel(stddeb, + "Accelerator #%u / event=%04X id=%04X type=%02X \n", + i, lpAccelTbl->tbl[i].wEvent, lpAccelTbl->tbl[i].wIDval, + lpAccelTbl->tbl[i].type); + lpAccelTbl->wCount++; + } + GlobalUnlock16(hAccel); + FreeResource32(rsc_mem); + return hAccel; +#else + fprintf(stderr,"LoadAcceleratorsW: not implemented\n"); + return 0x100; /* Return something anyway */ +#endif +} + +HACCEL32 LoadAccelerators32A(HINSTANCE32 instance,LPCSTR lpTableName) +{ + LPWSTR uni; + HACCEL32 result; + if (HIWORD(lpTableName)) + uni=STRING32_DupAnsiToUni(lpTableName); + else + uni=(LPWSTR)lpTableName; + result=LoadAccelerators32W(instance,uni); + if (HIWORD(uni)) + free(uni); + return result; +} + + /********************************************************************** * TranslateAccelerator [USER.178] */ @@ -351,14 +538,15 @@ GlobalUnlock16(hAccel); return 0; } - + /********************************************************************** - * LoadString + * LoadString16 */ -int -LoadString(HANDLE instance, WORD resource_id, LPSTR buffer, int buflen) +INT16 +LoadString16(HINSTANCE16 instance,UINT16 resource_id,LPSTR buffer,INT16 buflen) { - HANDLE hmem, hrsrc; + HGLOBAL16 hmem; + HRSRC16 hrsrc; unsigned char *p; int string_num; int i; @@ -366,12 +554,12 @@ dprintf_resource(stddeb,"LoadString: inst=%04x id=%04x buff=%08x len=%d\n", instance, resource_id, (int) buffer, buflen); - hrsrc = FindResource( instance, (SEGPTR)((resource_id>>4)+1), RT_STRING ); + hrsrc = FindResource16( instance, (SEGPTR)((resource_id>>4)+1), RT_STRING ); if (!hrsrc) return 0; - hmem = LoadResource( instance, hrsrc ); + hmem = LoadResource16( instance, hrsrc ); if (!hmem) return 0; - p = LockResource(hmem); + p = LockResource16(hmem); string_num = resource_id & 0x000f; for (i = 0; i < string_num; i++) p += *p + 1; @@ -392,11 +580,73 @@ fprintf(stderr,"LoadString // I dont know why , but caller give buflen=%d *p=%d !\n", buflen, *p); fprintf(stderr,"LoadString // and try to obtain string '%s'\n", p + 1); } - FreeResource( hmem ); + FreeResource16( hmem ); dprintf_resource(stddeb,"LoadString // '%s' copied !\n", buffer); return i; } +/********************************************************************** + * LoadString32W (USER32.375) + */ +INT32 +LoadString32W(HINSTANCE32 instance,UINT32 resource_id,LPWSTR buffer,int buflen) +{ + HGLOBAL32 hmem; + HRSRC32 hrsrc; + WCHAR *p; + int string_num; + int i; + dprintf_resource(stddeb, "LoadString: instance = %04x, id = %04x, buffer = %08x, " + "length = %d\n", instance, (int)resource_id, (int) buffer, buflen); + + hrsrc = FindResource32W( instance, (LPCWSTR)((resource_id>>4)+1), + (LPCWSTR)RT_STRING ); + if (!hrsrc) return 0; + hmem = LoadResource32( instance, hrsrc ); + if (!hmem) return 0; + + p = LockResource32(hmem); + string_num = resource_id & 0x000f; + for (i = 0; i < string_num; i++) + p += *p + 1; + + dprintf_resource( stddeb, "strlen = %d\n", (int)*p ); + + i = MIN(buflen - 1, *p); + if (buffer == NULL) + return i; + if (i > 0) { + memcpy(buffer, p + 1, i * sizeof (WCHAR)); + buffer[i] = (WCHAR) 0; + } else { + if (buflen > 1) { + buffer[0] = (WCHAR) 0; + return 0; + } +#if 0 + fprintf(stderr,"LoadString // I dont know why , but caller give buflen=%d *p=%d !\n", buflen, *p); + fprintf(stderr,"LoadString // and try to obtain string '%s'\n", p + 1); +#endif + } +#if 0 + dprintf_resource(stddeb,"LoadString // '%s' copied !\n", buffer); +#endif + return i; +} + +/********************************************************************** + * LoadString32A (USER32.374) + */ +INT32 +LoadString32A(HINSTANCE32 instance,UINT32 resource_id,LPSTR buffer,int buflen) +{ + LPWSTR buffer2 = (LPWSTR)xmalloc(buflen*2); + INT32 retval = LoadString32W(instance,resource_id,buffer2,buflen); + + STRING32_UniToAnsi(buffer,buffer2); + free(buffer2); + return retval; +}
diff --git a/loader/task.c b/loader/task.c index 1cfeb3a..ef862d2 100644 --- a/loader/task.c +++ b/loader/task.c
@@ -38,19 +38,27 @@ #define STACK32_SIZE 0x10000 extern void USER_AppExit(HTASK, HINSTANCE, HQUEUE ); -/* ------ Internal variables ------ */ -static HTASK hFirstTask = 0; -static HTASK hCurrentTask = 0; -static HTASK hTaskToKill = 0; -static HTASK hLockedTask = 0; + /* Saved 16-bit stack for current process (Win16 only) */ +WORD IF1632_Saved16_ss = 0; +WORD IF1632_Saved16_sp = 0; + + /* Saved 32-bit stack for current process (Win16 only) */ +DWORD IF1632_Saved32_esp = 0; +SEGPTR IF1632_Stack32_base = 0; + + /* Original Unix stack */ +DWORD IF1632_Original32_esp; + +static HTASK16 hFirstTask = 0; +static HTASK16 hCurrentTask = 0; +static HTASK16 hTaskToKill = 0; +static HTASK16 hLockedTask = 0; static WORD nTaskCount = 0; static HANDLE hDOSEnvironment = 0; -/* ------ Internal declarations ------ */ - /* TASK_Reschedule() 16-bit entry point */ -static FARPROC TASK_RescheduleProc; +static FARPROC16 TASK_RescheduleProc; #ifdef WINELIB #define TASK_SCHEDULE() TASK_Reschedule(); @@ -63,7 +71,7 @@ /*********************************************************************** * TASK_Init */ -BOOL TASK_Init(void) +BOOL32 TASK_Init(void) { TASK_RescheduleProc = MODULE_GetWndProcEntry16( "TASK_Reschedule" ); if (!(hDOSEnvironment = TASK_CreateDOSEnvironment())) @@ -196,9 +204,9 @@ /*********************************************************************** * TASK_LinkTask */ -static void TASK_LinkTask( HTASK hTask ) +static void TASK_LinkTask( HTASK16 hTask ) { - HTASK *prevTask; + HTASK16 *prevTask; TDB *pTask; if (!(pTask = (TDB *)GlobalLock16( hTask ))) return; @@ -218,9 +226,9 @@ /*********************************************************************** * TASK_UnlinkTask */ -static void TASK_UnlinkTask( HTASK hTask ) +static void TASK_UnlinkTask( HTASK16 hTask ) { - HTASK *prevTask; + HTASK16 *prevTask; TDB *pTask; prevTask = &hFirstTask; @@ -369,7 +377,7 @@ cs_reg, ip_reg, ds_reg, IF1632_Saved16_ss, IF1632_Saved16_sp); - CallTo16_regs_( (FARPROC)(cs_reg << 16 | ip_reg), ds_reg, + CallTo16_regs_( (FARPROC16)(cs_reg << 16 | ip_reg), ds_reg, pTask->hPDB /*es*/, 0 /*bp*/, 0 /*ax*/, pModule->stack_size /*bx*/, pModule->heap_size /*cx*/, 0 /*dx*/, 0 /*si*/, ds_reg /*di*/ ); @@ -384,8 +392,9 @@ /*********************************************************************** * TASK_CreateTask */ -HTASK TASK_CreateTask( HMODULE hModule, HANDLE hInstance, HANDLE hPrevInstance, - HANDLE hEnvironment, char *cmdLine, WORD cmdShow ) +HTASK16 TASK_CreateTask( HMODULE16 hModule, HINSTANCE16 hInstance, + HINSTANCE16 hPrevInstance, HANDLE16 hEnvironment, + LPCSTR cmdLine, UINT16 cmdShow ) { HTASK hTask; TDB *pTask; @@ -394,10 +403,10 @@ SEGTABLEENTRY *pSegTable; LPSTR name; char filename[256]; -#ifndef WINELIB32 char *stack16Top, *stack32Top; STACK16FRAME *frame16; STACK32FRAME *frame32; +#ifndef WINELIB32 extern DWORD CALLTO16_RetAddr_word; #endif @@ -466,17 +475,16 @@ /* Fill the PDB */ pTask->pdb.int20 = 0x20cd; -#ifndef WINELIB pTask->pdb.dispatcher[0] = 0x9a; /* ljmp */ +#ifndef WINELIB *(FARPROC16 *)&pTask->pdb.dispatcher[1] = MODULE_GetEntryPoint( GetModuleHandle("KERNEL"), 102 ); /* KERNEL.102 is DOS3Call() */ pTask->pdb.savedint22 = INT_GetHandler( 0x22 ); pTask->pdb.savedint23 = INT_GetHandler( 0x23 ); pTask->pdb.savedint24 = INT_GetHandler( 0x24 ); - pTask->pdb.fileHandlesPtr = (SEGPTR)MAKELONG( 0x18, - GlobalHandleToSel(pTask->hPDB) ); -#else - pTask->pdb.fileHandlesPtr = pTask->pdb.fileHandles; #endif + pTask->pdb.fileHandlesPtr = + PTR_SEG_OFF_TO_SEGPTR( GlobalHandleToSel(pTask->hPDB), + (int)&((PDB *)0)->fileHandles ); memset( pTask->pdb.fileHandles, 0xff, sizeof(pTask->pdb.fileHandles) ); pTask->pdb.environment = hEnvironment; pTask->pdb.nbFiles = 20; @@ -504,7 +512,6 @@ /* Allocate the 32-bit stack */ -#ifndef WINELIB pTask->hStack32 = GLOBAL_Alloc( GMEM_FIXED, STACK32_SIZE, pTask->hPDB, FALSE, FALSE, FALSE ); @@ -520,8 +527,10 @@ frame32->ecx = 0; frame32->ebx = 0; frame32->ebp = 0; +#ifndef WINELIB frame32->retaddr = (DWORD)TASK_CallToStart; frame32->codeselector = WINE_CODE_SELECTOR; +#endif pTask->esp = (DWORD)frame32; /* Create the 16-bit stack frame */ @@ -531,15 +540,17 @@ pSegTable[pModule->ss-1].minsize + pModule->stack_size) & ~1; stack16Top = (char *)PTR_SEG_OFF_TO_LIN( pTask->ss, pTask->sp ); frame16 = (STACK16FRAME *)stack16Top - 1; - frame16->saved_ss = 0; /*pTask->ss;*/ - frame16->saved_sp = 0; /*pTask->sp;*/ + frame16->saved_ss = 0; + frame16->saved_sp = 0; frame16->ds = frame16->es = pTask->hInstance; frame16->entry_point = 0; frame16->entry_ip = OFFSETOF(TASK_RescheduleProc) + 14; frame16->entry_cs = SELECTOROF(TASK_RescheduleProc); frame16->bp = 0; +#ifndef WINELIB frame16->ip = LOWORD( CALLTO16_RetAddr_word ); frame16->cs = HIWORD( CALLTO16_RetAddr_word ); +#endif /* WINELIB */ pTask->sp -= sizeof(STACK16FRAME); /* If there's no 16-bit stack yet, use a part of the new task stack */ @@ -554,6 +565,7 @@ /* Add a breakpoint at the start of the task */ +#ifndef WINELIB if (Options.debug) { if (pModule->flags & NE_FFLAGS_WIN32) @@ -570,7 +582,7 @@ DEBUG_AddBreakpoint( &addr ); } } -#endif +#endif /* WINELIB */ /* Add the task to the linked list */ @@ -626,7 +638,7 @@ * be killed when either TASK_Reschedule or this function is called again * in the context of another task. */ -void TASK_KillCurrentTask( int exitCode ) +void TASK_KillCurrentTask( INT16 exitCode ) { extern void EXEC_ExitWindows( int retCode ); @@ -731,7 +743,6 @@ /* Save the stacks of the previous task (if any) */ -#ifndef WINELIB /* FIXME: JBP: IF1632 not allowed in libwine.a */ if (pOldTask) { pOldTask->ss = IF1632_Saved16_ss; @@ -739,7 +750,6 @@ pOldTask->esp = IF1632_Saved32_esp; } else IF1632_Original32_esp = IF1632_Saved32_esp; -#endif /* Make the task the last in the linked list (round-robin scheduling) */ @@ -751,12 +761,10 @@ /* Switch to the new stack */ hCurrentTask = hTask; -#ifndef WINELIB /* FIXME: JBP: IF1632 not allowed in libwine.a */ IF1632_Saved16_ss = pNewTask->ss; IF1632_Saved16_sp = pNewTask->sp; IF1632_Saved32_esp = pNewTask->esp; IF1632_Stack32_base = WIN16_GlobalLock16( pNewTask->hStack32 ); -#endif } @@ -965,7 +973,7 @@ SEGPTR thunkaddr; thunkaddr = TASK_AllocThunk( hCurrentTask ); - if (!thunkaddr) return (FARPROC)0; + if (!thunkaddr) return (FARPROC16)0; thunk = PTR_SEG_TO_LIN( thunkaddr ); dprintf_task( stddeb, "MakeProcInstance(%08lx,%04x): got thunk %08lx\n", @@ -976,7 +984,7 @@ *thunk++ = (BYTE)(hInstance >> 8); *thunk++ = 0xea; /* ljmp func */ *(DWORD *)thunk = (DWORD)func; - return (FARPROC)thunkaddr; + return (FARPROC16)thunkaddr; #endif } @@ -996,7 +1004,7 @@ /********************************************************************** * GetCodeHandle (KERNEL.93) */ -HANDLE GetCodeHandle( FARPROC proc ) +HANDLE GetCodeHandle( FARPROC16 proc ) { #ifndef WINELIB32 HANDLE handle; @@ -1109,7 +1117,7 @@ char *ptr = (char *)GlobalLock16( instance ); if (!ptr || !len) return 0; if ((int)buffer + len >= 0x10000) len = 0x10000 - buffer; - memcpy( ptr + buffer, (char *)GlobalLock16( CURRENT_DS ) + buffer, len ); + memcpy( (char *)GlobalLock16(CURRENT_DS) + buffer, ptr + buffer, len ); return len; } @@ -1178,11 +1186,11 @@ /*********************************************************************** * GetExePtr (KERNEL.133) */ -HMODULE GetExePtr( HANDLE handle ) +HMODULE16 GetExePtr( HANDLE16 handle ) { char *ptr; - HTASK hTask; - HANDLE owner; + HTASK16 hTask; + HANDLE16 owner; /* Check for module handle */