blob: f54605af0e3af98ecefe51c4ffeef5222c38ab5c [file] [log] [blame]
/*
* Selector manipulation functions
*
* Copyright 1993 Robert J. Amstadt
* Copyright 1995 Alexandre Julliard
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#ifndef WINELIB
#ifdef __linux__
#include <sys/mman.h>
#include <linux/unistd.h>
#include <linux/head.h>
#include <linux/mman.h>
#include <linux/a.out.h>
#include <linux/ldt.h>
#endif
#if defined(__NetBSD__) || defined(__FreeBSD__)
#include <sys/mman.h>
#include <machine/segments.h>
#endif
#include "windows.h"
#include "ldt.h"
#include "wine.h"
#include "global.h"
#include "dlls.h"
#include "neexe.h"
#include "if1632.h"
#include "prototypes.h"
#include "module.h"
#include "stddebug.h"
/* #define DEBUG_SELECTORS */
#include "debug.h"
#define MAX_ENV_SIZE 16384 /* Max. environment size (ought to be dynamic) */
static HANDLE EnvironmentHandle = 0;
extern char WindowsPath[256];
extern char **Argv;
extern int Argc;
extern char **environ;
/**********************************************************************
* Check whether pseudo-functions like __0040H for direct memory
* access are referenced and return 1 if so.
* FIXME: Reading and writing to the returned selectors has no effect
* (e.g. reading from the Bios data segment (esp. clock!) )
*/
unsigned int GetMemoryReference( char *dll_name, char *function,
WORD *sel, WORD *offset )
{
static HANDLE memory_handles[ 10 ] = { 0,0,0,0,0,0,0,0,0,0 };
static char *memory_names[ 10 ] = { "segment 0xA000",
"segment 0xB000",
"segment 0xB800",
"Bios-Rom",
"segment 0xD000",
"segment 0x0000",
"segment 0xE000",
"segment 0xF000",
"segment 0xC000",
"Bios data segment" };
short nr;
if( strcasecmp( dll_name, "KERNEL" ) )
return 0;
if( HIWORD( function ) ) {
if( ( *function != '_' ) || ( *(function+1) != '_' ) )
return 0;
if( !strcasecmp( function, "__A000H" ) ) nr = 0;
else if( !strcasecmp( function, "__B000H" ) ) nr = 1;
else if( !strcasecmp( function, "__B800H" ) ) nr = 2;
else if( !strcasecmp( function, "__ROMBIOS" ) ) nr = 3;
else if( !strcasecmp( function, "__D000H" ) ) nr = 4;
else if( !strcasecmp( function, "__0000H" ) ) nr = 5;
else if( !strcasecmp( function, "__E000H" ) ) nr = 6;
else if( !strcasecmp( function, "__F000H" ) ) nr = 7;
else if( !strcasecmp( function, "__C000H" ) ) nr = 8;
else if( !strcasecmp( function, "__0040H" ) ) nr = 9;
else
return 0;
}
else {
switch( LOWORD( function ) ) {
case 174: nr = 0; break;
case 181: nr = 1; break;
case 182: nr = 2; break;
case 173: nr = 3; break;
case 179: nr = 4; break;
case 183: nr = 5; break;
case 190: nr = 6; break;
case 194: nr = 7; break;
case 195: nr = 8; break;
case 193: nr = 9; break;
default: return 0;
}
}
if( !memory_handles[ nr ] ) {
fprintf( stderr, "Warning: Direct access to %s!\n", memory_names[ nr ] );
memory_handles[ nr ] = GlobalAlloc( GMEM_FIXED, 65535 );
}
*sel = *offset = memory_handles[ nr ];
return 1;
}
unsigned int GetEntryDLLName( char * dll_name, char * function,
WORD* sel, WORD *offset )
{
HMODULE hModule;
struct dll_table_s *dll_table;
int ordinal, addr;
if( GetMemoryReference( dll_name, function, sel, offset ) )
return 0;
hModule = GetModuleHandle( dll_name );
ordinal = MODULE_GetOrdinal( hModule, function );
if (!ordinal) return 1;
addr = MODULE_GetEntryPoint( hModule, ordinal );
if (!addr) return 1;
#ifdef WINESTAT
if ((dll_table = FindDLLTable(dll_name)) != NULL)
{
dll_table->dll_table[ordinal].used++;
}
#endif
*offset = LOWORD(addr);
*sel = HIWORD(addr);
return 0;
}
unsigned int GetEntryDLLOrdinal( char * dll_name, int ordinal,
WORD *sel, WORD *offset )
{
HMODULE hModule;
struct dll_table_s *dll_table;
int addr;
if( GetMemoryReference( dll_name, (char*)ordinal, sel, offset ) )
return 0;
hModule = GetModuleHandle( dll_name );
addr = MODULE_GetEntryPoint( hModule, ordinal );
if (!addr) return 1;
#ifdef WINESTAT
if ((dll_table = FindDLLTable(dll_name)) != NULL)
dll_table->dll_table[ordinal].used++;
#endif
*offset = LOWORD(addr);
*sel = HIWORD(addr);
return 0;
}
WNDPROC GetWndProcEntry16( char *name )
{
WORD sel, offset;
GetEntryDLLName( "WINPROCS", name, &sel, &offset );
return (WNDPROC) MAKELONG( offset, sel );
}
/***********************************************************************
* GetDOSEnvironment (KERNEL.131)
*/
SEGPTR GetDOSEnvironment(void)
{
return WIN16_GlobalLock( EnvironmentHandle );
}
/**********************************************************************
* CreateEnvironment
*/
static HANDLE CreateEnvironment(void)
{
HANDLE handle;
char **e;
char *p;
handle = GlobalAlloc( GMEM_MOVEABLE, MAX_ENV_SIZE );
if (!handle) return 0;
p = (char *) GlobalLock( handle );
/*
* Fill environment with Windows path, the Unix environment,
* and program name.
*/
strcpy(p, "PATH=");
strcat(p, WindowsPath);
p += strlen(p) + 1;
for (e = environ; *e; e++)
{
if (strncasecmp(*e, "path", 4))
{
strcpy(p, *e);
p += strlen(p) + 1;
}
}
*p++ = '\0';
/*
* Display environment
*/
p = (char *) GlobalLock( handle );
dprintf_selectors(stddeb, "Environment at %p\n", p);
for (; *p; p += strlen(p) + 1) dprintf_selectors(stddeb, " %s\n", p);
return handle;
}
/**********************************************************************
* CreateSelectors
*/
void CreateSelectors(void)
{
if(!EnvironmentHandle) EnvironmentHandle = CreateEnvironment();
}
#endif /* ifndef WINELIB */