summaryrefslogtreecommitdiffstats
path: root/loader/win32.c
diff options
context:
space:
mode:
Diffstat (limited to 'loader/win32.c')
-rw-r--r--loader/win32.c5779
1 files changed, 0 insertions, 5779 deletions
diff --git a/loader/win32.c b/loader/win32.c
deleted file mode 100644
index 635892f22d..0000000000
--- a/loader/win32.c
+++ /dev/null
@@ -1,5779 +0,0 @@
-/***********************************************************
-
-Win32 emulation code. Functions that emulate
-responses from corresponding Win32 API calls.
-Since we are not going to be able to load
-virtually any DLL, we can only implement this
-much, adding needed functions with each new codec.
-
-Basic principle of implementation: it's not good
-for DLL to know too much about its environment.
-
-************************************************************/
-
-/*
- * Modified for use with MPlayer, detailed changelog at
- * http://svn.mplayerhq.hu/mplayer/trunk/
- */
-
-#include "config.h"
-#include "mangle.h"
-
-#define REALPLAYER
-//#define LOADLIB_TRY_NATIVE
-
-/* Hack to make sure the correct function declaration in com.h is used when
- * this file is built for the test applications with WIN32_LOADER disabled. */
-#ifndef WIN32_LOADER
-#define WIN32_LOADER
-#endif
-
-#ifdef CONFIG_QTX_CODECS
-#define PSEUDO_SCREEN_WIDTH /*640*/800
-#define PSEUDO_SCREEN_HEIGHT /*480*/600
-#endif
-
-#include "wine/winbase.h"
-#include "wine/winreg.h"
-#include "wine/winnt.h"
-#include "wine/winerror.h"
-#include "wine/debugtools.h"
-#include "wine/module.h"
-#include "wine/winuser.h"
-#include "wine/objbase.h"
-
-#include <stdio.h>
-#include "win32.h"
-
-#include "registry.h"
-#include "loader.h"
-#include "com.h"
-#include "ext.h"
-#include "ldt_keeper.h"
-#include "path.h"
-
-#include <stdlib.h>
-#include <assert.h>
-#include <stdarg.h>
-#include <ctype.h>
-#include <pthread.h>
-#include <errno.h>
-#include <time.h>
-#include <math.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/types.h>
-#include <dirent.h>
-#include <sys/time.h>
-#include <sys/stat.h>
-
-#ifdef HAVE_SYS_MMAN_H
-#include <sys/mman.h>
-#else
-#include "osdep/mmap.h"
-#endif
-#include "osdep/mmap_anon.h"
-#include "libavutil/avstring.h"
-#include "cpudetect.h"
-
-static unsigned int c_localcount_tsc(void)
-{
- int a;
- __asm__ volatile
- (
- "rdtsc\n\t"
- :"=a"(a)
- :
- :"edx"
- );
- return a;
-}
-static void c_longcount_tsc(long long* z)
-{
- __asm__ volatile
- (
- "pushl %%ebx\n\t"
- "movl %%eax, %%ebx\n\t"
- "rdtsc\n\t"
- "movl %%eax, 0(%%ebx)\n\t"
- "movl %%edx, 4(%%ebx)\n\t"
- "popl %%ebx\n\t"
- ::"a"(z)
- :"edx"
- );
-}
-static unsigned int c_localcount_notsc(void)
-{
- struct timeval tv;
- unsigned limit=~0;
- limit/=1000000;
- gettimeofday(&tv, 0);
- return limit*tv.tv_usec;
-}
-static void c_longcount_notsc(long long* z)
-{
- struct timeval tv;
- unsigned long long result;
- unsigned limit=~0;
- if(!z)return;
- limit/=1000000;
- gettimeofday(&tv, 0);
- result=tv.tv_sec;
- result<<=32;
- result+=limit*tv.tv_usec;
- *z=result;
-}
-static unsigned int localcount_stub(void);
-static void longcount_stub(long long*);
-static unsigned int (*localcount)(void)=localcount_stub;
-static void (*longcount)(long long*)=longcount_stub;
-
-static pthread_mutex_t memmut = PTHREAD_MUTEX_INITIALIZER;
-
-
-static void do_cpuid(unsigned int ax, unsigned int *p)
-{
-// code from libavcodec:
- __asm__ volatile
- ("mov %%"REG_b", %%"REG_S"\n\t"
- "cpuid\n\t"
- "xchg %%"REG_b", %%"REG_S
- : "=a" (p[0]), "=S" (p[1]),
- "=c" (p[2]), "=d" (p[3])
- : "0" (ax));
-}
-
-static unsigned int localcount_stub(void)
-{
- unsigned int regs[4];
- do_cpuid(1, regs);
- if ((regs[3] & 0x00000010) != 0)
- {
- localcount=c_localcount_tsc;
- longcount=c_longcount_tsc;
- }
- else
- {
- localcount=c_localcount_notsc;
- longcount=c_longcount_notsc;
- }
- return localcount();
-}
-static void longcount_stub(long long* z)
-{
- unsigned int regs[4];
- do_cpuid(1, regs);
- if ((regs[3] & 0x00000010) != 0)
- {
- localcount=c_localcount_tsc;
- longcount=c_longcount_tsc;
- }
- else
- {
- localcount=c_localcount_notsc;
- longcount=c_longcount_notsc;
- }
- longcount(z);
-}
-
-#include "mp_msg.h"
-int LOADER_DEBUG=1; // active only if compiled with -DDETAILED_OUT
-//#define DETAILED_OUT
-static inline void dbgprintf(char* fmt, ...)
-{
-#ifdef DETAILED_OUT
- if(LOADER_DEBUG)
- {
- FILE* f;
- va_list va;
- va_start(va, fmt);
- f=fopen("./log", "a");
- vprintf(fmt, va);
- fflush(stdout);
- if(f)
- {
- vfprintf(f, fmt, va);
- fsync(fileno(f));
- fclose(f);
- }
- va_end(va);
- }
-#endif
- if ( mp_msg_test(MSGT_WIN32,MSGL_DBG3) )
- {
- va_list va;
-
- va_start(va, fmt);
- vprintf(fmt, va);
-// mp_dbg(MSGT_WIN32, MSGL_DBG3, fmt, va);
- va_end(va);
- fflush(stdout);
- }
-}
-
-
-char export_names[300][32]={
- "name1",
- //"name2",
- //"name3"
-};
-//#define min(x,y) ((x)<(y)?(x):(y))
-
-void destroy_event(void* event);
-
-struct th_list_t;
-typedef struct th_list_t{
- int id;
- void* thread;
- struct th_list_t* next;
- struct th_list_t* prev;
-} th_list;
-
-
-// have to be cleared by GARBAGE COLLECTOR
-//static unsigned char* heap=NULL;
-//static int heap_counter=0;
-static tls_t* g_tls=NULL;
-static th_list* list=NULL;
-static pthread_mutex_t list_lock = PTHREAD_MUTEX_INITIALIZER;
-
-#if 0
-static void test_heap(void)
-{
- int offset=0;
- if(heap==0)
- return;
- while(offset<heap_counter)
- {
- if(*(int*)(heap+offset)!=0x433476)
- {
- printf("Heap corruption at address %d\n", offset);
- return;
- }
- offset+=8+*(int*)(heap+offset+4);
- }
- for(;offset<min(offset+1000, 20000000); offset++)
- if(heap[offset]!=0xCC)
- {
- printf("Free heap corruption at address %d\n", offset);
- }
-}
-#endif
-#undef MEMORY_DEBUG
-
-#ifdef MEMORY_DEBUG
-
-static void* my_mreq(int size, int to_zero)
-{
- static int test=0;
- test++;
- if(test%10==0)printf("Memory: %d bytes allocated\n", heap_counter);
- // test_heap();
- if(heap==NULL)
- {
- heap=malloc(20000000);
- memset(heap, 0xCC,20000000);
- }
- if(heap==0)
- {
- printf("No enough memory\n");
- return 0;
- }
- if(heap_counter+size>20000000)
- {
- printf("No enough memory\n");
- return 0;
- }
- *(int*)(heap+heap_counter)=0x433476;
- heap_counter+=4;
- *(int*)(heap+heap_counter)=size;
- heap_counter+=4;
- printf("Allocated %d bytes of memory: sys %d, user %d-%d\n", size, heap_counter-8, heap_counter, heap_counter+size);
- if(to_zero)
- memset(heap+heap_counter, 0, size);
- else
- memset(heap+heap_counter, 0xcc, size); // make crash reproducable
- heap_counter+=size;
- return heap+heap_counter-size;
-}
-static int my_release(char* memory)
-{
- // test_heap();
- if(memory==NULL)
- {
- printf("ERROR: free(0)\n");
- return 0;
- }
- if(*(int*)(memory-8)!=0x433476)
- {
- printf("MEMORY CORRUPTION !!!!!!!!!!!!!!!!!!!\n");
- return 0;
- }
- printf("Freed %d bytes of memory\n", *(int*)(memory-4));
- // memset(memory-8, *(int*)(memory-4), 0xCC);
- return 0;
-}
-
-#else
-#define GARBAGE
-typedef struct alloc_header_t alloc_header;
-struct alloc_header_t
-{
- // let's keep allocated data 16 byte aligned
- alloc_header* prev;
- alloc_header* next;
- long deadbeef;
- long size;
- long type;
- long reserved1;
- long reserved2;
- long reserved3;
-};
-
-#ifdef GARBAGE
-static alloc_header* last_alloc = NULL;
-static int alccnt = 0;
-#endif
-
-#define AREATYPE_CLIENT 0
-#define AREATYPE_EVENT 1
-#define AREATYPE_MUTEX 2
-#define AREATYPE_COND 3
-#define AREATYPE_CRITSECT 4
-
-/* -- critical sections -- */
-struct CRITSECT
-{
- pthread_t id;
- pthread_mutex_t mutex;
- pthread_cond_t unlocked;
- int lock_count;
- long deadbeef;
-};
-
-void* mreq_private(int size, int to_zero, int type);
-void* mreq_private(int size, int to_zero, int type)
-{
- int nsize = size + sizeof(alloc_header);
- alloc_header* header = malloc(nsize);
- if (!header)
- return 0;
- if (to_zero)
- memset(header, 0, nsize);
-#ifdef GARBAGE
- pthread_mutex_lock(&memmut);
- if (last_alloc)
- {
- last_alloc->next = header; /* set next */
- }
-
- header->prev = last_alloc;
- header->next = 0;
- last_alloc = header;
- alccnt++;
- pthread_mutex_unlock(&memmut);
-#endif
- header->deadbeef = 0xdeadbeef;
- header->size = size;
- header->type = type;
-
- //if (alccnt < 40000) printf("MY_REQ: %p\t%d t:%d (cnt:%d)\n", header, size, type, alccnt);
- return header + 1;
-}
-
-static int my_release(void* memory)
-{
- alloc_header* header = (alloc_header*) memory - 1;
-#ifdef GARBAGE
- alloc_header* prevmem;
- alloc_header* nextmem;
-
- if (memory == 0)
- return 0;
-
- if (header->deadbeef != (long) 0xdeadbeef)
- {
- dbgprintf("FATAL releasing corrupted memory! %p 0x%lx (%d)\n", header, header->deadbeef, alccnt);
- return 0;
- }
-
- pthread_mutex_lock(&memmut);
-
- switch(header->type)
- {
- case AREATYPE_EVENT:
- destroy_event(memory);
- break;
- case AREATYPE_COND:
- pthread_cond_destroy((pthread_cond_t*)memory);
- break;
- case AREATYPE_MUTEX:
- pthread_mutex_destroy((pthread_mutex_t*)memory);
- break;
- case AREATYPE_CRITSECT:
- pthread_mutex_destroy(&((struct CRITSECT*)memory)->mutex);
- break;
- default:
- //memset(memory, 0xcc, header->size);
- ;
- }
-
- header->deadbeef = 0;
- prevmem = header->prev;
- nextmem = header->next;
-
- if (prevmem)
- prevmem->next = nextmem;
- if (nextmem)
- nextmem->prev = prevmem;
-
- if (header == last_alloc)
- last_alloc = prevmem;
-
- alccnt--;
-
- pthread_mutex_unlock(&memmut);
-
- //if (alccnt < 40000) printf("MY_RELEASE: %p\t%ld (%d)\n", header, header->size, alccnt);
-#else
- if (memory == 0)
- return 0;
-#endif
- //memset(header + 1, 0xcc, header->size);
- free(header);
- return 0;
-}
-#endif
-
-static inline void* my_mreq(int size, int to_zero)
-{
- return mreq_private(size, to_zero, AREATYPE_CLIENT);
-}
-
-static int my_size(void* memory)
-{
- if(!memory) return 0;
- return ((alloc_header*)memory)[-1].size;
-}
-
-static void* my_realloc(void* memory, int size)
-{
- void *ans = memory;
- int osize;
- if (memory == NULL)
- return my_mreq(size, 0);
- osize = my_size(memory);
- if (osize < size)
- {
- ans = my_mreq(size, 0);
- memcpy(ans, memory, osize);
- my_release(memory);
- }
- return ans;
-}
-
-/*
- *
- * WINE API - native implementation for several win32 libraries
- *
- */
-
-static int WINAPI ext_unknown(void)
-{
- printf("Unknown func called\n");
- return 0;
-}
-
-static int WINAPI expGetVolumeInformationA( const char *root, char *label,
- unsigned int label_len, unsigned int *serial,
- unsigned int *filename_len,unsigned int *flags,
- char *fsname, unsigned int fsname_len )
-{
-dbgprintf("GetVolumeInformationA( %s, 0x%x, %ld, 0x%x, 0x%x, 0x%x, 0x%x, %ld) => 1\n",
- root,label,label_len,serial,filename_len,flags,fsname,fsname_len);
-//hack Do not return any real data - do nothing
-return 1;
-}
-
-static unsigned int WINAPI expGetDriveTypeA( const char *root )
-{
- dbgprintf("GetDriveTypeA( %s ) => %d\n",root,DRIVE_FIXED);
- // hack return as Fixed Drive Type
- return DRIVE_FIXED;
-}
-
-static unsigned int WINAPI expGetLogicalDriveStringsA( unsigned int len, char *buffer )
-{
- dbgprintf("GetLogicalDriveStringsA(%d, 0x%x) => 4\n",len,buffer);
- // hack only have one drive c:\ in this hack
- *buffer++='c';
- *buffer++=':';
- *buffer++='\\';
- *buffer++='\0';
- *buffer= '\0';
-return 4; // 1 drive * 4 bytes (includes null)
-}
-
-
-static int WINAPI expIsBadWritePtr(void* ptr, unsigned int count)
-{
- int result = (count == 0 || ptr != 0) ? 0 : 1;
- dbgprintf("IsBadWritePtr(0x%x, 0x%x) => %d\n", ptr, count, result);
- return result;
-}
-static int WINAPI expIsBadReadPtr(void* ptr, unsigned int count)
-{
- int result = (count == 0 || ptr != 0) ? 0 : 1;
- dbgprintf("IsBadReadPtr(0x%x, 0x%x) => %d\n", ptr, count, result);
- return result;
-}
-static int WINAPI expDisableThreadLibraryCalls(int module)
-{
- dbgprintf("DisableThreadLibraryCalls(0x%x) => 0\n", module);
- return 0;
-}
-
-static HMODULE WINAPI expGetDriverModuleHandle(DRVR* pdrv)
-{
- HMODULE result;
- if (pdrv==NULL)
- result=0;
- else
- result=pdrv->hDriverModule;
- dbgprintf("GetDriverModuleHandle(%p) => %p\n", pdrv, result);
- return result;
-}
-
-#define MODULE_HANDLE_kernel32 ((HMODULE)0x120)
-#define MODULE_HANDLE_user32 ((HMODULE)0x121)
-#ifdef CONFIG_QTX_CODECS
-#define MODULE_HANDLE_wininet ((HMODULE)0x122)
-#define MODULE_HANDLE_ddraw ((HMODULE)0x123)
-#define MODULE_HANDLE_advapi32 ((HMODULE)0x124)
-#endif
-#define MODULE_HANDLE_comdlg32 ((HMODULE)0x125)
-#define MODULE_HANDLE_msvcrt ((HMODULE)0x126)
-#define MODULE_HANDLE_ole32 ((HMODULE)0x127)
-#define MODULE_HANDLE_winmm ((HMODULE)0x128)
-#define MODULE_HANDLE_psapi ((HMODULE)0x129)
-
-// Fake PE header, since some software (and the Microsoft CRT v8 and newer)
-// assume GetModuleHandle(NULL) returns a pointer to a PE header.
-// We simulate a very simple header with only one section.
-//
-// NOTE: If you have a section called .mixcrt, the Microsoft CRT will assume
-// it's running in a POSIX binary, and stop using EncodePointer/DecodePointer.
-static const struct {
- IMAGE_DOS_HEADER doshdr;
- IMAGE_NT_HEADERS nthdr;
- IMAGE_SECTION_HEADER opthdr;
-} __attribute__((__packed__)) mp_exe = {
- .doshdr.e_lfanew = sizeof(IMAGE_DOS_HEADER),
- .nthdr.FileHeader.NumberOfSections = 1,
- .nthdr.FileHeader.SizeOfOptionalHeader =
- sizeof(IMAGE_NT_HEADERS) - FIELD_OFFSET(IMAGE_NT_HEADERS, OptionalHeader), /* 0xe0 */
- .opthdr.Name = ".text"
-};
-
-static HMODULE WINAPI expGetModuleHandleA(const char* name)
-{
- WINE_MODREF* wm;
- HMODULE result;
- if(!name)
- result=(HMODULE)&mp_exe.doshdr;
- else
- {
- wm=MODULE_FindModule(name);
- if(wm==0)result=0;
- else
- result=(HMODULE)(wm->module);
- }
- if(!result)
- {
- if(name && (strcasecmp(name, "kernel32")==0 || !strcasecmp(name, "kernel32.dll")))
- result=MODULE_HANDLE_kernel32;
-#ifdef CONFIG_QTX_CODECS
- if(name && strcasecmp(name, "user32")==0)
- result=MODULE_HANDLE_user32;
-#endif
- }
- dbgprintf("GetModuleHandleA('%s') => 0x%x\n", name, result);
- return result;
-}
-
-static HMODULE WINAPI expGetModuleHandleW(const uint16_t* name)
-{
- char aname[256];
- int pos = 0;
- while (*name) {
- if (*name > 256 || pos >= sizeof(aname) - 1)
- return 0;
- aname[pos++] = *name++;
- }
- aname[pos] = 0;
- return expGetModuleHandleA(aname);
-}
-
-static void* WINAPI expCreateThread(void* pSecAttr, long dwStackSize,
- void* lpStartAddress, void* lpParameter,
- long dwFlags, long* dwThreadId)
-{
- pthread_t *pth;
- // printf("CreateThread:");
- pth = (pthread_t*) my_mreq(sizeof(pthread_t), 0);
- pthread_create(pth, NULL, (void*(*)(void*))lpStartAddress, lpParameter);
- if(dwFlags)
- printf( "WARNING: CreateThread flags not supported\n");
- if(dwThreadId)
- *dwThreadId=(long)pth;
- pthread_mutex_lock(&list_lock);
- if(list==NULL)
- {
- list=my_mreq(sizeof(th_list), 1);
- list->next=list->prev=NULL;
- }
- else
- {
- list->next=my_mreq(sizeof(th_list), 0);
- list->next->prev=list;
- list->next->next=NULL;
- list=list->next;
- }
- list->thread=pth;
- pthread_mutex_unlock(&list_lock);
- dbgprintf("CreateThread(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x) => 0x%x\n",
- pSecAttr, dwStackSize, lpStartAddress, lpParameter, dwFlags, dwThreadId, pth);
- return pth;
-}
-
-static DWORD WINAPI expResumeThread(HANDLE hThread)
-{
- int ret = 1;
- dbgprintf("ResumeThread(0x%x) => 0x%x\n", hThread, ret);
- return ret;
-}
-
-struct mutex_list_t;
-
-struct mutex_list_t
-{
- char type;
- pthread_mutex_t *pm;
- pthread_cond_t *pc;
- char state;
- char reset;
- char name[128];
- int semaphore;
- int lock_count;
- pthread_t owner;
- struct mutex_list_t* next;
- struct mutex_list_t* prev;
-};
-typedef struct mutex_list_t mutex_list;
-static mutex_list* mlist=NULL;
-static pthread_mutex_t mlist_lock = PTHREAD_MUTEX_INITIALIZER;
-
-void destroy_event(void* event)
-{
- mutex_list *pp;
- pthread_mutex_lock(&mlist_lock);
- pp=mlist;
- // printf("garbage collector: destroy_event(%x)\n", event);
- while(pp)
- {
- if(pp==(mutex_list*)event)
- {
- if(pp->next)
- pp->next->prev=pp->prev;
- if(pp->prev)
- pp->prev->next=pp->next;
- if(mlist==(mutex_list*)event)
- mlist=mlist->prev;
- /*
- pp=mlist;
- while(pp)
- {
- printf("%x => ", pp);
- pp=pp->prev;
- }
- printf("0\n");
- */
- pthread_mutex_unlock(&mlist_lock);
- return;
- }
- pp=pp->prev;
- }
- pthread_mutex_unlock(&mlist_lock);
-}
-
-static void* WINAPI expCreateEventA(void* pSecAttr, char bManualReset,
- char bInitialState, const char* name)
-{
- pthread_mutex_t *pm;
- pthread_cond_t *pc;
- void *ret;
- /*
- mutex_list* pp;
- pp=mlist;
- while(pp)
- {
- printf("%x => ", pp);
- pp=pp->prev;
- }
- printf("0\n");
- */
- pthread_mutex_lock(&mlist_lock);
- if(mlist!=NULL)
- {
- mutex_list* pp=mlist;
- if(name!=NULL)
- do
- {
- if((strcmp(pp->name, name)==0) && (pp->type==0))
- {
- dbgprintf("CreateEventA(0x%x, 0x%x, 0x%x, 0x%x='%s') => 0x%x\n",
- pSecAttr, bManualReset, bInitialState, name, name, pp->pm);
- pthread_mutex_unlock(&mlist_lock);
- return pp->pm;
- }
- }while((pp=pp->prev) != NULL);
- }
- pm=mreq_private(sizeof(pthread_mutex_t), 0, AREATYPE_MUTEX);
- pthread_mutex_init(pm, NULL);
- pc=mreq_private(sizeof(pthread_cond_t), 0, AREATYPE_COND);
- pthread_cond_init(pc, NULL);
- if(mlist==NULL)
- {
- mlist=mreq_private(sizeof(mutex_list), 00, AREATYPE_EVENT);
- mlist->next=mlist->prev=NULL;
- }
- else
- {
- mlist->next=mreq_private(sizeof(mutex_list), 00, AREATYPE_EVENT);
- mlist->next->prev=mlist;
- mlist->next->next=NULL;
- mlist=mlist->next;
- }
- mlist->type=0; /* Type Event */
- mlist->pm=pm;
- mlist->pc=pc;
- mlist->state=bInitialState;
- mlist->reset=!bManualReset;
- if(name)
- strncpy(mlist->name, name, 127);
- else
- mlist->name[0]=0;
- if(pm==NULL)
- dbgprintf("ERROR::: CreateEventA failure\n");
- /*
- if(bInitialState)
- pthread_mutex_lock(pm);
- */
- if(name)
- dbgprintf("CreateEventA(0x%x, 0x%x, 0x%x, 0x%x='%s') => 0x%x\n",
- pSecAttr, bManualReset, bInitialState, name, name, mlist);
- else
- dbgprintf("CreateEventA(0x%x, 0x%x, 0x%x, NULL) => 0x%x\n",
- pSecAttr, bManualReset, bInitialState, mlist);
- ret = mlist;
- pthread_mutex_unlock(&mlist_lock);
- return ret;
-}
-
-static void* WINAPI expCreateEventW(void* pSecAttr, char bManualReset,
- char bInitialState, const WCHAR* name)
-{
- char ascii_name[256];
- char *aname = NULL;
- if (name) {
- WideCharToMultiByte(65001, 0x0, name, -1, ascii_name, 256, NULL, NULL);
- aname = ascii_name;
- }
- return expCreateEventA(pSecAttr, bManualReset, bInitialState, aname);
-}
-
-static void* WINAPI expSetEvent(void* event)
-{
- mutex_list *ml = (mutex_list *)event;
- dbgprintf("SetEvent(%x) => 0x1\n", event);
- pthread_mutex_lock(ml->pm);
- if (ml->state == 0) {
- ml->state = 1;
- pthread_cond_signal(ml->pc);
- }
- pthread_mutex_unlock(ml->pm);
-
- return (void *)1;
-}
-static void* WINAPI expResetEvent(void* event)
-{
- mutex_list *ml = (mutex_list *)event;
- dbgprintf("ResetEvent(0x%x) => 0x1\n", event);
- pthread_mutex_lock(ml->pm);
- ml->state = 0;
- pthread_mutex_unlock(ml->pm);
-
- return (void *)1;
-}
-
-static void* WINAPI expWaitForSingleObject(void* object, int duration)
-{
- mutex_list *ml = (mutex_list *)object;
- // FIXME FIXME FIXME - this value is sometime unititialize !!!
- int ret = WAIT_FAILED;
- mutex_list* pp;
- th_list* tp;
- if(object == (void*)0xcfcf9898)
- {
- /**
- From GetCurrentThread() documentation:
- A pseudo handle is a special constant that is interpreted as the current thread handle. The calling thread can use this handle to specify itself whenever a thread handle is required. Pseudo handles are not inherited by child processes.
-
- This handle has the maximum possible access to the thread object. For systems that support security descriptors, this is the maximum access allowed by the security descriptor for the calling process. For systems that do not support security descriptors, this is THREAD_ALL_ACCESS.
-
- The function cannot be used by one thread to create a handle that can be used by other threads to refer to the first thread. The handle is always interpreted as referring to the thread that is using it. A thread can create a "real" handle to itself that can be used by other threads, or inherited by other processes, by specifying the pseudo handle as the source handle in a call to the DuplicateHandle function.
- **/
- dbgprintf("WaitForSingleObject(thread_handle) called\n");
- return (void*)WAIT_FAILED;
- }
- dbgprintf("WaitForSingleObject(0x%x, duration %d) =>\n",object, duration);
-
- // See if this is a thread.
- pthread_mutex_lock(&list_lock);
- tp=list;
- while (tp && (tp->thread != object))
- tp = tp->prev;
- pthread_mutex_unlock(&list_lock);
- if (tp) {
- if (pthread_join(*(pthread_t*)object, NULL) == 0) {
- return (void*)WAIT_OBJECT_0;
- } else {
- return (void*)WAIT_FAILED;
- }
- }
-
- // loop below was slightly fixed - its used just for checking if
- // this object really exists in our list
- if (!ml)
- return (void*) ret;
- pthread_mutex_lock(&mlist_lock);
- pp=mlist;
- while (pp && (pp->pm != ml->pm))
- pp = pp->prev;
- pthread_mutex_unlock(&mlist_lock);
- if (!pp) {
- dbgprintf("WaitForSingleObject: NotFound\n");
- return (void*)ret;
- }
-
- pthread_mutex_lock(ml->pm);
-
- switch(ml->type) {
- case 0: /* Event */
- if (duration == 0) { /* Check Only */
- if (ml->state == 1) ret = WAIT_OBJECT_0;
- else ret = WAIT_FAILED;
- }
- if (duration == -1) { /* INFINITE */
- if (ml->state == 0)
- pthread_cond_wait(ml->pc,ml->pm);
- if (ml->reset)
- ml->state = 0;
- ret = WAIT_OBJECT_0;
- }
- if (duration > 0) { /* Timed Wait */
- struct timespec abstime;
- struct timeval now;
- gettimeofday(&now, 0);
- abstime.tv_sec = now.tv_sec + (now.tv_usec+duration)/1000000;
- abstime.tv_nsec = ((now.tv_usec+duration)%1000000)*1000;
- if (ml->state == 0)
- ret=pthread_cond_timedwait(ml->pc,ml->pm,&abstime);
- if (ret == ETIMEDOUT) ret = WAIT_TIMEOUT;
- else ret = WAIT_OBJECT_0;
- if (ml->reset)
- ml->state = 0;
- }
- break;
- case 1: /* Semaphore */
- if (duration == 0) {
- if(ml->semaphore==0) ret = WAIT_FAILED;
- else {
- ml->semaphore--;
- ret = WAIT_OBJECT_0;
- }
- }
- if (duration == -1) {
- if (ml->semaphore==0)
- pthread_cond_wait(ml->pc,ml->pm);
- ml->semaphore--;
- ret = WAIT_OBJECT_0;
- }
- break;
- case 2: /* Mutex */
- if (duration == 0) {
- if(ml->lock_count > 0 && ml->owner != pthread_self()) ret = WAIT_FAILED;
- else {
- ml->lock_count++;
- ml->owner = pthread_self();
- ret = WAIT_OBJECT_0;
- }
- }
- if (duration == -1) {
- if (ml->lock_count > 0 && ml->owner != pthread_self()) {
- pthread_cond_wait(ml->pc,ml->pm);
- }
- ml->lock_count++;
- ml->owner = pthread_self();
- ret = WAIT_OBJECT_0;
- }
- break;
- }
- pthread_mutex_unlock(ml->pm);
-
- dbgprintf("WaitForSingleObject(0x%x, %d): 0x%x => 0x%x \n",object,duration,ml,ret);
- return (void *)ret;
-}
-
-#ifdef CONFIG_QTX_CODECS
-static void* WINAPI expWaitForMultipleObjects(int count, const void** objects,
- int WaitAll, int duration)
-{
- int i;
- void *object;
- void *ret;
-
- dbgprintf("WaitForMultipleObjects(%d, 0x%x, %d, duration %d) =>\n",
- count, objects, WaitAll, duration);
-
- for (i = 0; i < count; i++)
- {
- object = (void *)objects[i];
- ret = expWaitForSingleObject(object, duration);
- if (WaitAll)
- dbgprintf("WaitAll flag not yet supported...\n");
- else
- return ret;
- }
- return NULL;
-}
-
-static void WINAPI expExitThread(int retcode)
-{
- dbgprintf("ExitThread(%d)\n", retcode);
- pthread_exit(&retcode);
-}
-#endif
-
-static int pf_set = 0;
-static BYTE PF[64] = {0,};
-
-static void DumpSystemInfo(const SYSTEM_INFO* si)
-{
- dbgprintf(" Processor architecture %d\n", si->u.s.wProcessorArchitecture);
- dbgprintf(" Page size: %d\n", si->dwPageSize);
- dbgprintf(" Minimum app address: %d\n", si->lpMinimumApplicationAddress);
- dbgprintf(" Maximum app address: %d\n", si->lpMaximumApplicationAddress);
- dbgprintf(" Active processor mask: 0x%x\n", si->dwActiveProcessorMask);
- dbgprintf(" Number of processors: %d\n", si->dwNumberOfProcessors);
- dbgprintf(" Processor type: 0x%x\n", si->dwProcessorType);
- dbgprintf(" Allocation granularity: 0x%x\n", si->dwAllocationGranularity);
- dbgprintf(" Processor level: 0x%x\n", si->wProcessorLevel);
- dbgprintf(" Processor revision: 0x%x\n", si->wProcessorRevision);
-}
-
-static void WINAPI expGetSystemInfo(SYSTEM_INFO* si)
-{
- /* FIXME: better values for the two entries below... */
- static int cache = 0;
- static SYSTEM_INFO cachedsi;
- dbgprintf("GetSystemInfo(%p) =>\n", si);
-
- if (cache) {
- goto exit;
- }
- memset(PF,0,sizeof(PF));
- pf_set = 1;
-
- cachedsi.u.s.wProcessorArchitecture = PROCESSOR_ARCHITECTURE_INTEL;
- cachedsi.dwPageSize = getpagesize();
-
- /* FIXME: better values for the two entries below... */
- cachedsi.lpMinimumApplicationAddress = (void *)0x00000000;
- cachedsi.lpMaximumApplicationAddress = (void *)0x7FFFFFFF;
- cachedsi.dwActiveProcessorMask = 1;
- cachedsi.dwNumberOfProcessors = 1;
- cachedsi.dwProcessorType = PROCESSOR_INTEL_386;
- cachedsi.dwAllocationGranularity = 0x10000;
- cachedsi.wProcessorLevel = 5; /* pentium */
- cachedsi.wProcessorRevision = 0x0101;
-
- /* mplayer's way to detect PF's */
- {
-
- if (gCpuCaps.hasMMX)
- PF[PF_MMX_INSTRUCTIONS_AVAILABLE] = TRUE;
- if (gCpuCaps.hasSSE)
- PF[PF_XMMI_INSTRUCTIONS_AVAILABLE] = TRUE;
- if (gCpuCaps.hasSSE2)
- PF[PF_XMMI64_INSTRUCTIONS_AVAILABLE] = TRUE;
-
- cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
- cachedsi.wProcessorLevel = 5;
- cachedsi.dwNumberOfProcessors = 1; /* hardcoded */
- }
-
-/* MPlayer: linux detection enabled (based on proc/cpuinfo) for checking
- fdiv_bug and fpu emulation flags -- alex/MPlayer */
-#ifdef __linux__
- {
- char buf[20];
- char line[200];
- FILE *f = fopen ("/proc/cpuinfo", "r");
-
- if (!f)
- {
- mp_msg(MSGT_WIN32, MSGL_WARN, "expGetSystemInfo: "
- "/proc/cpuinfo not readable! "
- "Expect bad performance and/or weird behaviour\n");
- goto exit;
- }
- while (fgets(line,200,f)!=NULL) {
- char *s,*value;
-
- /* NOTE: the ':' is the only character we can rely on */
- if (!(value = strchr(line,':')))
- continue;
- /* terminate the valuename */
- *value++ = '\0';
- /* skip any leading spaces */
- while (*value==' ') value++;
- if ((s=strchr(value,'\n')))
- *s='\0';
-
- /* 2.1 method */
- if (!lstrncmpiA(line, "cpu family",strlen("cpu family"))) {
- if (isdigit (value[0])) {
- switch (value[0] - '0') {
- case 3: cachedsi.dwProcessorType = PROCESSOR_INTEL_386;
- cachedsi.wProcessorLevel= 3;
- break;
- case 4: cachedsi.dwProcessorType = PROCESSOR_INTEL_486;
- cachedsi.wProcessorLevel= 4;
- break;
- case 5: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
- cachedsi.wProcessorLevel= 5;
- break;
- case 6: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
- cachedsi.wProcessorLevel= 5;
- break;
- default:cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
- cachedsi.wProcessorLevel= 5;
- break;
- }
- }
- /* set the CPU type of the current processor */
- sprintf(buf,"CPU %ld",cachedsi.dwProcessorType);
- continue;
- }
- /* old 2.0 method */
- if (!lstrncmpiA(line, "cpu",strlen("cpu"))) {
- if ( isdigit (value[0]) && value[1] == '8' &&
- value[2] == '6' && value[3] == 0
- ) {
- switch (value[0] - '0') {
- case 3: cachedsi.dwProcessorType = PROCESSOR_INTEL_386;
- cachedsi.wProcessorLevel= 3;
- break;
- case 4: cachedsi.dwProcessorType = PROCESSOR_INTEL_486;
- cachedsi.wProcessorLevel= 4;
- break;
- case 5: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
- cachedsi.wProcessorLevel= 5;
- break;
- case 6: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
- cachedsi.wProcessorLevel= 5;
- break;
- default:cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
- cachedsi.wProcessorLevel= 5;
- break;
- }
- }
- /* set the CPU type of the current processor */
- sprintf(buf,"CPU %ld",cachedsi.dwProcessorType);
- continue;
- }
- if (!lstrncmpiA(line,"fdiv_bug",strlen("fdiv_bug"))) {
- if (!lstrncmpiA(value,"yes",3))
- PF[PF_FLOATING_POINT_PRECISION_ERRATA] = TRUE;
-
- continue;
- }
- if (!lstrncmpiA(line,"fpu",strlen("fpu"))) {
- if (!lstrncmpiA(value,"no",2))
- PF[PF_FLOATING_POINT_EMULATED] = TRUE;
-
- continue;
- }
- if (!lstrncmpiA(line,"processor",strlen("processor"))) {
- /* processor number counts up...*/
- unsigned int x;
-
- if (sscanf(value,"%d",&x))
- if (x+1>cachedsi.dwNumberOfProcessors)
- cachedsi.dwNumberOfProcessors=x+1;
-
- /* Create a new processor subkey on a multiprocessor
- * system
- */
- sprintf(buf,"%d",x);
- }
- if (!lstrncmpiA(line,"stepping",strlen("stepping"))) {
- int x;
-
- if (sscanf(value,"%d",&x))
- cachedsi.wProcessorRevision = x;
- }
- if
- ( (!lstrncmpiA(line,"flags",strlen("flags")))
- || (!lstrncmpiA(line,"features",strlen("features"))) )
- {
- if (strstr(value,"cx8"))
- PF[PF_COMPARE_EXCHANGE_DOUBLE] = TRUE;
- if (strstr(value,"mmx"))
- PF[PF_MMX_INSTRUCTIONS_AVAILABLE] = TRUE;
- if (strstr(value,"tsc"))
- PF[PF_RDTSC_INSTRUCTION_AVAILABLE] = TRUE;
- if (strstr(value,"xmm") || strstr(value,"sse"))
- PF[PF_XMMI_INSTRUCTIONS_AVAILABLE] = TRUE;
- if (strstr(value,"sse2"))
- PF[PF_XMMI64_INSTRUCTIONS_AVAILABLE] = TRUE;
- if (strstr(value,"3dnow"))
- PF[PF_AMD3D_INSTRUCTIONS_AVAILABLE] = TRUE;
- }
- }
- fclose (f);
- }
-#endif /* __linux__ */
- cache = 1;
-exit:
- memcpy(si,&cachedsi,sizeof(*si));
- DumpSystemInfo(si);
-}
-
-// avoid undefined expGetSystemInfo
-static WIN_BOOL WINAPI expIsProcessorFeaturePresent(DWORD v)
-{
- WIN_BOOL result = 0;
- if (!pf_set)
- {
- SYSTEM_INFO si;
- expGetSystemInfo(&si);
- }
- if(v<64) result=PF[v];
- dbgprintf("IsProcessorFeaturePresent(0x%x) => 0x%x\n", v, result);
- return result;
-}
-
-static WIN_BOOL WINAPI expIsDebuggerPresent(void)
-{
- return 0;
-}
-
-static long WINAPI expGetVersion(void)
-{
- dbgprintf("GetVersion() => 0xC0000004\n");
- return 0xC0000004;//Windows 95
-}
-
-static HANDLE WINAPI expHeapCreate(long