/********************************************************************** * DirectResAlloc (KERNEL.168) * * Check Schulman, p. 232 for details */ HGLOBAL16 WINAPI DirectResAlloc16( HINSTANCE16 hInstance, WORD wType, UINT16 wSize ) { HGLOBAL16 ret; TRACE("(%04x,%04x,%04x)\n", hInstance, wType, wSize ); if (!(hInstance = GetExePtr( hInstance ))) return 0; if(wType != 0x10) /* 0x10 is the only observed value, passed from CreateCursorIndirect. */ TRACE("(wType=%x)\n", wType); ret = GlobalAlloc16( GMEM_MOVEABLE, wSize ); if (ret) FarSetOwner16( ret, hInstance ); return ret; }
/*********************************************************************** * NE_LoadAllSegments */ BOOL NE_LoadAllSegments( NE_MODULE *pModule ) { int i; SEGTABLEENTRY * pSegTable = NE_SEG_TABLE(pModule); if (pModule->ne_flags & NE_FFLAGS_SELFLOAD) { HFILE16 hFile16; HGLOBAL16 sel; /* Handle self-loading modules */ SELFLOADHEADER *selfloadheader; HMODULE16 mod = GetModuleHandle16("KERNEL"); void *oldstack; WORD args[2]; TRACE_(module)("%.*s is a self-loading module!\n", *((BYTE*)pModule + pModule->ne_restab), (char *)pModule + pModule->ne_restab + 1); if (!NE_LoadSegment( pModule, 1 )) return FALSE; selfloadheader = MapSL( MAKESEGPTR(SEL(pSegTable->hSeg), 0) ); selfloadheader->EntryAddrProc = GetProcAddress16(mod,"EntryAddrProc"); selfloadheader->MyAlloc = GetProcAddress16(mod,"MyAlloc"); selfloadheader->SetOwner = GetProcAddress16(mod,"FarSetOwner"); sel = GlobalAlloc16( GMEM_ZEROINIT, 0xFF00 ); pModule->self_loading_sel = SEL(sel); FarSetOwner16( sel, pModule->self ); oldstack = getWOW32Reserved(); setWOW32Reserved((void *)MAKESEGPTR(pModule->self_loading_sel, 0xff00 - sizeof(STACK16FRAME) )); hFile16 = NE_OpenFile(pModule); TRACE_(dll)("CallBootAppProc(hModule=0x%04x,hf=0x%04x)\n", pModule->self,hFile16); args[1] = pModule->self; args[0] = hFile16; WOWCallback16Ex( (DWORD)selfloadheader->BootApp, WCB16_PASCAL, sizeof(args), args, NULL ); TRACE_(dll)("Return from CallBootAppProc\n"); _lclose16(hFile16); setWOW32Reserved(oldstack); for (i = 2; i <= pModule->ne_cseg; i++) if (!NE_LoadSegment( pModule, i )) return FALSE; } else { for (i = 1; i <= pModule->ne_cseg; i++) if (!NE_LoadSegment( pModule, i )) return FALSE; } return TRUE; }
/*********************************************************************** * NE_LoadAllSegments */ BOOL NE_LoadAllSegments( NE_MODULE *pModule ) { int i; SEGTABLEENTRY * pSegTable = (SEGTABLEENTRY *) NE_SEG_TABLE(pModule); if (pModule->flags & NE_FFLAGS_SELFLOAD) { HANDLE hf; HFILE16 hFile16; HGLOBAL16 sel; /* Handle self-loading modules */ SELFLOADHEADER *selfloadheader; HMODULE16 mod = GetModuleHandle16("KERNEL"); DWORD oldstack; TRACE_(module)("%.*s is a self-loading module!\n", *((BYTE*)pModule + pModule->name_table), (char *)pModule + pModule->name_table + 1); if (!NE_LoadSegment( pModule, 1 )) return FALSE; selfloadheader = MapSL( MAKESEGPTR(SEL(pSegTable->hSeg), 0) ); selfloadheader->EntryAddrProc = GetProcAddress16(mod,"EntryAddrProc"); selfloadheader->MyAlloc = GetProcAddress16(mod,"MyAlloc"); selfloadheader->SetOwner = GetProcAddress16(mod,"FarSetOwner"); sel = GlobalAlloc16( GMEM_ZEROINIT, 0xFF00 ); pModule->self_loading_sel = SEL(sel); FarSetOwner16( sel, pModule->self ); oldstack = NtCurrentTeb()->WOW32Reserved; NtCurrentTeb()->WOW32Reserved = MAKESEGPTR(pModule->self_loading_sel, 0xff00 - sizeof(STACK16FRAME) ); DuplicateHandle( GetCurrentProcess(), NE_OpenFile(pModule), GetCurrentProcess(), &hf, 0, FALSE, DUPLICATE_SAME_ACCESS ); hFile16 = Win32HandleToDosFileHandle( hf ); TRACE_(dll)("CallBootAppProc(hModule=0x%04x,hf=0x%04x)\n", pModule->self,hFile16); NE_CallTo16_word_ww(selfloadheader->BootApp, pModule->self,hFile16); TRACE_(dll)("Return from CallBootAppProc\n"); _lclose16(hFile16); NtCurrentTeb()->WOW32Reserved = oldstack; for (i = 2; i <= pModule->seg_count; i++) if (!NE_LoadSegment( pModule, i )) return FALSE; } else { for (i = 1; i <= pModule->seg_count; i++) if (!NE_LoadSegment( pModule, i )) return FALSE; } return TRUE; }
/********************************************************************** * AllocResource (KERNEL.66) */ HGLOBAL16 WINAPI AllocResource16( HMODULE16 hModule, HRSRC16 hRsrc, DWORD size) { NE_NAMEINFO *pNameInfo=NULL; WORD sizeShift; HGLOBAL16 ret; NE_MODULE *pModule = NE_GetPtr( hModule ); if (!pModule || !pModule->ne_rsrctab || !hRsrc) return 0; TRACE("module=%04x res=%04x size=%ld\n", hModule, hRsrc, size ); sizeShift = *(WORD *)((char *)pModule + pModule->ne_rsrctab); pNameInfo = (NE_NAMEINFO*)((char*)pModule + hRsrc); if (size < (DWORD)pNameInfo->length << sizeShift) size = (DWORD)pNameInfo->length << sizeShift; ret = GlobalAlloc16( GMEM_FIXED, size ); if (ret) FarSetOwner16( ret, hModule ); return ret; }
/*********************************************************************** * TASK_Create * * NOTE: This routine might be called by a Win32 thread. Thus, we need * to be careful to protect global data structures. We do this * by entering the Win16Lock while linking the task into the * global task list. */ static TDB *TASK_Create( NE_MODULE *pModule, UINT16 cmdShow, LPCSTR cmdline, BYTE len ) { HTASK16 hTask; TDB *pTask; FARPROC16 proc; char curdir[MAX_PATH]; HMODULE16 hModule = pModule ? pModule->self : 0; /* Allocate the task structure */ hTask = GlobalAlloc16( GMEM_FIXED | GMEM_ZEROINIT, sizeof(TDB) ); if (!hTask) return NULL; pTask = TASK_GetPtr( hTask ); FarSetOwner16( hTask, hModule ); /* Fill the task structure */ pTask->hSelf = hTask; pTask->version = pModule ? pModule->ne_expver : 0x0400; pTask->hModule = hModule; pTask->hParent = GetCurrentTask(); pTask->magic = TDB_MAGIC; pTask->nCmdShow = cmdShow; GetCurrentDirectoryA( sizeof(curdir), curdir ); GetShortPathNameA( curdir, curdir, sizeof(curdir) ); pTask->curdrive = (curdir[0] - 'A') | 0x80; lstrcpynA( pTask->curdir, curdir + 2, sizeof(pTask->curdir) ); /* Create the thunks block */ TASK_CreateThunks( hTask, (char *)pTask->thunks - (char *)pTask, 7 ); /* Copy the module name */ if (hModule) { char name[sizeof(pTask->module_name)+1]; size_t len; GetModuleName16( hModule, name, sizeof(name) ); len = strlen(name) + 1; memcpy(pTask->module_name, name, min(len,sizeof(pTask->module_name))); pTask->compat_flags = GetProfileIntA( "Compatibility", name, 0 ); } /* Allocate a selector for the PDB */ pTask->hPDB = GLOBAL_CreateBlock( GMEM_FIXED, &pTask->pdb, sizeof(PDB16), hModule, WINE_LDT_FLAGS_DATA ); /* Fill the PDB */ pTask->pdb.int20 = 0x20cd; pTask->pdb.dispatcher[0] = 0x9a; /* ljmp */ proc = GetProcAddress16( GetModuleHandle16("KERNEL"), "DOS3Call" ); memcpy( &pTask->pdb.dispatcher[1], &proc, sizeof(proc) ); pTask->pdb.savedint22 = 0; pTask->pdb.savedint23 = 0; pTask->pdb.savedint24 = 0; pTask->pdb.fileHandlesPtr = MAKESEGPTR( GlobalHandleToSel16(pTask->hPDB), FIELD_OFFSET( PDB16, fileHandles )); pTask->pdb.hFileHandles = 0; memset( pTask->pdb.fileHandles, 0xff, sizeof(pTask->pdb.fileHandles) ); /* FIXME: should we make a copy of the environment? */ pTask->pdb.environment = SELECTOROF(GetDOSEnvironment16()); pTask->pdb.nbFiles = 20; /* Fill the command line */ if (!cmdline) { cmdline = GetCommandLineA(); /* remove the first word (program name) */ if (*cmdline == '"') if (!(cmdline = strchr( cmdline+1, '"' ))) cmdline = GetCommandLineA(); while (*cmdline && (*cmdline != ' ') && (*cmdline != '\t')) cmdline++; while ((*cmdline == ' ') || (*cmdline == '\t')) cmdline++; len = strlen(cmdline); } if (len >= sizeof(pTask->pdb.cmdLine)) len = sizeof(pTask->pdb.cmdLine)-1; pTask->pdb.cmdLine[0] = len; memcpy( pTask->pdb.cmdLine + 1, cmdline, len ); /* pTask->pdb.cmdLine[len+1] = 0; */ TRACE("cmdline='%.*s' task=%04x\n", len, cmdline, hTask ); /* Allocate a code segment alias for the TDB */ pTask->hCSAlias = GLOBAL_CreateBlock( GMEM_FIXED, pTask, sizeof(TDB), pTask->hPDB, WINE_LDT_FLAGS_CODE ); /* Default DTA overwrites command line */ pTask->dta = MAKESEGPTR( pTask->hPDB, FIELD_OFFSET( PDB16, cmdLine )); /* Create scheduler event for 16-bit tasks */ if ( !(pTask->flags & TDBF_WIN32) ) NtCreateEvent( &pTask->hEvent, EVENT_ALL_ACCESS, NULL, NotificationEvent, FALSE ); if (!initial_task) initial_task = hTask; return pTask; }