loader: Reuse do_cpuid from cpudetect.c in loader/win32.c
[mplayer/glamo.git] / loader / win32.c
blob13ac8d4a2879ea4079f466186be6890f7fa65b4a
1 /***********************************************************
3 Win32 emulation code. Functions that emulate
4 responses from corresponding Win32 API calls.
5 Since we are not going to be able to load
6 virtually any DLL, we can only implement this
7 much, adding needed functions with each new codec.
9 Basic principle of implementation: it's not good
10 for DLL to know too much about its environment.
12 ************************************************************/
15 * Modified for use with MPlayer, detailed changelog at
16 * http://svn.mplayerhq.hu/mplayer/trunk/
19 #include "config.h"
20 #include "mangle.h"
22 #define REALPLAYER
23 //#define LOADLIB_TRY_NATIVE
25 /* Hack to make sure the correct function declaration in com.h is used when
26 * this file is built for the test applications with WIN32_LOADER disabled. */
27 #ifndef WIN32_LOADER
28 #define WIN32_LOADER
29 #endif
31 #ifdef CONFIG_QTX_CODECS
32 #define PSEUDO_SCREEN_WIDTH /*640*/800
33 #define PSEUDO_SCREEN_HEIGHT /*480*/600
34 #endif
36 #include "wine/winbase.h"
37 #include "wine/winreg.h"
38 #include "wine/winnt.h"
39 #include "wine/winerror.h"
40 #include "wine/debugtools.h"
41 #include "wine/module.h"
42 #include "wine/winuser.h"
43 #include "wine/objbase.h"
45 #include <stdio.h>
46 #include "win32.h"
48 #include "registry.h"
49 #include "loader.h"
50 #include "com.h"
51 #include "ext.h"
52 #include "path.h"
54 #include <stdlib.h>
55 #include <assert.h>
56 #include <stdarg.h>
57 #include <ctype.h>
58 #include <pthread.h>
59 #include <errno.h>
60 #include <time.h>
61 #include <math.h>
62 #include <unistd.h>
63 #include <fcntl.h>
64 #include <sys/types.h>
65 #include <dirent.h>
66 #include <sys/time.h>
67 #include <sys/stat.h>
68 #ifdef HAVE_KSTAT
69 #include <kstat.h>
70 #endif
72 #ifdef HAVE_SYS_MMAN_H
73 #include <sys/mman.h>
74 #else
75 #include "osdep/mmap.h"
76 #endif
77 #include "osdep/mmap_anon.h"
78 #include "libavutil/avstring.h"
79 #include "cpudetect.h"
81 static unsigned int c_localcount_tsc(void)
83 int a;
84 __asm__ volatile
86 "rdtsc\n\t"
87 :"=a"(a)
89 :"edx"
91 return a;
93 static void c_longcount_tsc(long long* z)
95 __asm__ volatile
97 "pushl %%ebx\n\t"
98 "movl %%eax, %%ebx\n\t"
99 "rdtsc\n\t"
100 "movl %%eax, 0(%%ebx)\n\t"
101 "movl %%edx, 4(%%ebx)\n\t"
102 "popl %%ebx\n\t"
103 ::"a"(z)
104 :"edx"
107 static unsigned int c_localcount_notsc(void)
109 struct timeval tv;
110 unsigned limit=~0;
111 limit/=1000000;
112 gettimeofday(&tv, 0);
113 return limit*tv.tv_usec;
115 static void c_longcount_notsc(long long* z)
117 struct timeval tv;
118 unsigned long long result;
119 unsigned limit=~0;
120 if(!z)return;
121 limit/=1000000;
122 gettimeofday(&tv, 0);
123 result=tv.tv_sec;
124 result<<=32;
125 result+=limit*tv.tv_usec;
126 *z=result;
128 static unsigned int localcount_stub(void);
129 static void longcount_stub(long long*);
130 static unsigned int (*localcount)(void)=localcount_stub;
131 static void (*longcount)(long long*)=longcount_stub;
133 static pthread_mutex_t memmut = PTHREAD_MUTEX_INITIALIZER;
135 static unsigned int localcount_stub(void)
137 unsigned int regs[4];
138 do_cpuid(1, regs);
139 if ((regs[3] & 0x00000010) != 0)
141 localcount=c_localcount_tsc;
142 longcount=c_longcount_tsc;
144 else
146 localcount=c_localcount_notsc;
147 longcount=c_longcount_notsc;
149 return localcount();
151 static void longcount_stub(long long* z)
153 unsigned int regs[4];
154 do_cpuid(1, regs);
155 if ((regs[3] & 0x00000010) != 0)
157 localcount=c_localcount_tsc;
158 longcount=c_longcount_tsc;
160 else
162 localcount=c_localcount_notsc;
163 longcount=c_longcount_notsc;
165 longcount(z);
168 #include "mp_msg.h"
169 int LOADER_DEBUG=1; // active only if compiled with -DDETAILED_OUT
170 //#define DETAILED_OUT
171 static inline void dbgprintf(char* fmt, ...)
173 #ifdef DETAILED_OUT
174 if(LOADER_DEBUG)
176 FILE* f;
177 va_list va;
178 va_start(va, fmt);
179 f=fopen("./log", "a");
180 vprintf(fmt, va);
181 fflush(stdout);
182 if(f)
184 vfprintf(f, fmt, va);
185 fsync(fileno(f));
186 fclose(f);
188 va_end(va);
190 #endif
191 if ( mp_msg_test(MSGT_WIN32,MSGL_DBG3) )
193 va_list va;
195 va_start(va, fmt);
196 vprintf(fmt, va);
197 // mp_dbg(MSGT_WIN32, MSGL_DBG3, fmt, va);
198 va_end(va);
199 fflush(stdout);
204 char export_names[300][32]={
205 "name1",
206 //"name2",
207 //"name3"
209 //#define min(x,y) ((x)<(y)?(x):(y))
211 void destroy_event(void* event);
213 struct th_list_t;
214 typedef struct th_list_t{
215 int id;
216 void* thread;
217 struct th_list_t* next;
218 struct th_list_t* prev;
219 } th_list;
222 // have to be cleared by GARBAGE COLLECTOR
223 //static unsigned char* heap=NULL;
224 //static int heap_counter=0;
225 static tls_t* g_tls=NULL;
226 static th_list* list=NULL;
227 static pthread_mutex_t list_lock = PTHREAD_MUTEX_INITIALIZER;
229 #if 0
230 static void test_heap(void)
232 int offset=0;
233 if(heap==0)
234 return;
235 while(offset<heap_counter)
237 if(*(int*)(heap+offset)!=0x433476)
239 printf("Heap corruption at address %d\n", offset);
240 return;
242 offset+=8+*(int*)(heap+offset+4);
244 for(;offset<min(offset+1000, 20000000); offset++)
245 if(heap[offset]!=0xCC)
247 printf("Free heap corruption at address %d\n", offset);
250 #endif
251 #undef MEMORY_DEBUG
253 #ifdef MEMORY_DEBUG
255 static void* my_mreq(int size, int to_zero)
257 static int test=0;
258 test++;
259 if(test%10==0)printf("Memory: %d bytes allocated\n", heap_counter);
260 // test_heap();
261 if(heap==NULL)
263 heap=malloc(20000000);
264 memset(heap, 0xCC,20000000);
266 if(heap==0)
268 printf("No enough memory\n");
269 return 0;
271 if(heap_counter+size>20000000)
273 printf("No enough memory\n");
274 return 0;
276 *(int*)(heap+heap_counter)=0x433476;
277 heap_counter+=4;
278 *(int*)(heap+heap_counter)=size;
279 heap_counter+=4;
280 printf("Allocated %d bytes of memory: sys %d, user %d-%d\n", size, heap_counter-8, heap_counter, heap_counter+size);
281 if(to_zero)
282 memset(heap+heap_counter, 0, size);
283 else
284 memset(heap+heap_counter, 0xcc, size); // make crash reproducable
285 heap_counter+=size;
286 return heap+heap_counter-size;
288 static int my_release(char* memory)
290 // test_heap();
291 if(memory==NULL)
293 printf("ERROR: free(0)\n");
294 return 0;
296 if(*(int*)(memory-8)!=0x433476)
298 printf("MEMORY CORRUPTION !!!!!!!!!!!!!!!!!!!\n");
299 return 0;
301 printf("Freed %d bytes of memory\n", *(int*)(memory-4));
302 // memset(memory-8, *(int*)(memory-4), 0xCC);
303 return 0;
306 #else
307 #define GARBAGE
308 typedef struct alloc_header_t alloc_header;
309 struct alloc_header_t
311 // let's keep allocated data 16 byte aligned
312 alloc_header* prev;
313 alloc_header* next;
314 long deadbeef;
315 long size;
316 long type;
317 long reserved1;
318 long reserved2;
319 long reserved3;
322 #ifdef GARBAGE
323 static alloc_header* last_alloc = NULL;
324 static int alccnt = 0;
325 #endif
327 #define AREATYPE_CLIENT 0
328 #define AREATYPE_EVENT 1
329 #define AREATYPE_MUTEX 2
330 #define AREATYPE_COND 3
331 #define AREATYPE_CRITSECT 4
333 /* -- critical sections -- */
334 struct CRITSECT
336 pthread_t id;
337 pthread_mutex_t mutex;
338 pthread_cond_t unlocked;
339 int lock_count;
340 long deadbeef;
343 void* mreq_private(int size, int to_zero, int type);
344 void* mreq_private(int size, int to_zero, int type)
346 int nsize = size + sizeof(alloc_header);
347 alloc_header* header = malloc(nsize);
348 if (!header)
349 return 0;
350 if (to_zero)
351 memset(header, 0, nsize);
352 #ifdef GARBAGE
353 pthread_mutex_lock(&memmut);
354 if (last_alloc)
356 last_alloc->next = header; /* set next */
359 header->prev = last_alloc;
360 header->next = 0;
361 last_alloc = header;
362 alccnt++;
363 pthread_mutex_unlock(&memmut);
364 #endif
365 header->deadbeef = 0xdeadbeef;
366 header->size = size;
367 header->type = type;
369 //if (alccnt < 40000) printf("MY_REQ: %p\t%d t:%d (cnt:%d)\n", header, size, type, alccnt);
370 return header + 1;
373 static int my_release(void* memory)
375 alloc_header* header = (alloc_header*) memory - 1;
376 #ifdef GARBAGE
377 alloc_header* prevmem;
378 alloc_header* nextmem;
380 if (memory == 0)
381 return 0;
383 if (header->deadbeef != (long) 0xdeadbeef)
385 dbgprintf("FATAL releasing corrupted memory! %p 0x%lx (%d)\n", header, header->deadbeef, alccnt);
386 return 0;
389 pthread_mutex_lock(&memmut);
391 switch(header->type)
393 case AREATYPE_EVENT:
394 destroy_event(memory);
395 break;
396 case AREATYPE_COND:
397 pthread_cond_destroy((pthread_cond_t*)memory);
398 break;
399 case AREATYPE_MUTEX:
400 pthread_mutex_destroy((pthread_mutex_t*)memory);
401 break;
402 case AREATYPE_CRITSECT:
403 pthread_mutex_destroy(&((struct CRITSECT*)memory)->mutex);
404 break;
405 default:
406 //memset(memory, 0xcc, header->size);
410 header->deadbeef = 0;
411 prevmem = header->prev;
412 nextmem = header->next;
414 if (prevmem)
415 prevmem->next = nextmem;
416 if (nextmem)
417 nextmem->prev = prevmem;
419 if (header == last_alloc)
420 last_alloc = prevmem;
422 alccnt--;
424 pthread_mutex_unlock(&memmut);
426 //if (alccnt < 40000) printf("MY_RELEASE: %p\t%ld (%d)\n", header, header->size, alccnt);
427 #else
428 if (memory == 0)
429 return 0;
430 #endif
431 //memset(header + 1, 0xcc, header->size);
432 free(header);
433 return 0;
435 #endif
437 static inline void* my_mreq(int size, int to_zero)
439 return mreq_private(size, to_zero, AREATYPE_CLIENT);
442 static int my_size(void* memory)
444 if(!memory) return 0;
445 return ((alloc_header*)memory)[-1].size;
448 static void* my_realloc(void* memory, int size)
450 void *ans = memory;
451 int osize;
452 if (memory == NULL)
453 return my_mreq(size, 0);
454 osize = my_size(memory);
455 if (osize < size)
457 ans = my_mreq(size, 0);
458 memcpy(ans, memory, osize);
459 my_release(memory);
461 return ans;
466 * WINE API - native implementation for several win32 libraries
470 static int WINAPI ext_unknown(void)
472 printf("Unknown func called\n");
473 return 0;
476 static int WINAPI expGetVolumeInformationA( const char *root, char *label,
477 unsigned int label_len, unsigned int *serial,
478 unsigned int *filename_len,unsigned int *flags,
479 char *fsname, unsigned int fsname_len )
481 dbgprintf("GetVolumeInformationA( %s, 0x%x, %ld, 0x%x, 0x%x, 0x%x, 0x%x, %ld) => 1\n",
482 root,label,label_len,serial,filename_len,flags,fsname,fsname_len);
483 //hack Do not return any real data - do nothing
484 return 1;
487 static unsigned int WINAPI expGetDriveTypeA( const char *root )
489 dbgprintf("GetDriveTypeA( %s ) => %d\n",root,DRIVE_FIXED);
490 // hack return as Fixed Drive Type
491 return DRIVE_FIXED;
494 static unsigned int WINAPI expGetLogicalDriveStringsA( unsigned int len, char *buffer )
496 dbgprintf("GetLogicalDriveStringsA(%d, 0x%x) => 4\n",len,buffer);
497 // hack only have one drive c:\ in this hack
498 *buffer++='c';
499 *buffer++=':';
500 *buffer++='\\';
501 *buffer++='\0';
502 *buffer= '\0';
503 return 4; // 1 drive * 4 bytes (includes null)
507 static int WINAPI expIsBadWritePtr(void* ptr, unsigned int count)
509 int result = (count == 0 || ptr != 0) ? 0 : 1;
510 dbgprintf("IsBadWritePtr(0x%x, 0x%x) => %d\n", ptr, count, result);
511 return result;
513 static int WINAPI expIsBadReadPtr(void* ptr, unsigned int count)
515 int result = (count == 0 || ptr != 0) ? 0 : 1;
516 dbgprintf("IsBadReadPtr(0x%x, 0x%x) => %d\n", ptr, count, result);
517 return result;
519 static int WINAPI expDisableThreadLibraryCalls(int module)
521 dbgprintf("DisableThreadLibraryCalls(0x%x) => 0\n", module);
522 return 0;
525 static HMODULE WINAPI expGetDriverModuleHandle(DRVR* pdrv)
527 HMODULE result;
528 if (pdrv==NULL)
529 result=0;
530 else
531 result=pdrv->hDriverModule;
532 dbgprintf("GetDriverModuleHandle(%p) => %p\n", pdrv, result);
533 return result;
536 #define MODULE_HANDLE_kernel32 ((HMODULE)0x120)
537 #define MODULE_HANDLE_user32 ((HMODULE)0x121)
538 #ifdef CONFIG_QTX_CODECS
539 #define MODULE_HANDLE_wininet ((HMODULE)0x122)
540 #define MODULE_HANDLE_ddraw ((HMODULE)0x123)
541 #define MODULE_HANDLE_advapi32 ((HMODULE)0x124)
542 #endif
543 #define MODULE_HANDLE_comdlg32 ((HMODULE)0x125)
544 #define MODULE_HANDLE_msvcrt ((HMODULE)0x126)
545 #define MODULE_HANDLE_ole32 ((HMODULE)0x127)
546 #define MODULE_HANDLE_winmm ((HMODULE)0x128)
547 #define MODULE_HANDLE_psapi ((HMODULE)0x129)
549 // Fake PE header, since some software (and the Microsoft CRT v8 and newer)
550 // assume GetModuleHandle(NULL) returns a pointer to a PE header.
551 // We simulate a very simple header with only one section.
553 // NOTE: If you have a section called .mixcrt, the Microsoft CRT will assume
554 // it's running in a POSIX binary, and stop using EncodePointer/DecodePointer.
555 static const struct {
556 IMAGE_DOS_HEADER doshdr;
557 IMAGE_NT_HEADERS nthdr;
558 IMAGE_SECTION_HEADER opthdr;
559 } __attribute__((__packed__)) mp_exe = {
560 .doshdr.e_lfanew = sizeof(IMAGE_DOS_HEADER),
561 .nthdr.FileHeader.NumberOfSections = 1,
562 .nthdr.FileHeader.SizeOfOptionalHeader =
563 sizeof(IMAGE_NT_HEADERS) - FIELD_OFFSET(IMAGE_NT_HEADERS, OptionalHeader), /* 0xe0 */
564 .opthdr.Name = ".text"
567 static HMODULE WINAPI expGetModuleHandleA(const char* name)
569 WINE_MODREF* wm;
570 HMODULE result;
571 if(!name)
572 result=(HMODULE)&mp_exe.doshdr;
573 else
575 wm=MODULE_FindModule(name);
576 if(wm==0)result=0;
577 else
578 result=(HMODULE)(wm->module);
580 if(!result)
582 if(name && (strcasecmp(name, "kernel32")==0 || !strcasecmp(name, "kernel32.dll")))
583 result=MODULE_HANDLE_kernel32;
584 #ifdef CONFIG_QTX_CODECS
585 if(name && strcasecmp(name, "user32")==0)
586 result=MODULE_HANDLE_user32;
587 #endif
589 dbgprintf("GetModuleHandleA('%s') => 0x%x\n", name, result);
590 return result;
593 static HMODULE WINAPI expGetModuleHandleW(const uint16_t* name)
595 char aname[256];
596 int pos = 0;
597 while (*name) {
598 if (*name > 256 || pos >= sizeof(aname) - 1)
599 return NULL;
600 aname[pos++] = *name++;
602 aname[pos] = 0;
603 return expGetModuleHandleA(aname);
606 static void* WINAPI expCreateThread(void* pSecAttr, long dwStackSize,
607 void* lpStartAddress, void* lpParameter,
608 long dwFlags, long* dwThreadId)
610 pthread_t *pth;
611 // printf("CreateThread:");
612 pth = (pthread_t*) my_mreq(sizeof(pthread_t), 0);
613 pthread_create(pth, NULL, (void*(*)(void*))lpStartAddress, lpParameter);
614 if(dwFlags)
615 printf( "WARNING: CreateThread flags not supported\n");
616 if(dwThreadId)
617 *dwThreadId=(long)pth;
618 pthread_mutex_lock(&list_lock);
619 if(list==NULL)
621 list=my_mreq(sizeof(th_list), 1);
622 list->next=list->prev=NULL;
624 else
626 list->next=my_mreq(sizeof(th_list), 0);
627 list->next->prev=list;
628 list->next->next=NULL;
629 list=list->next;
631 list->thread=pth;
632 pthread_mutex_unlock(&list_lock);
633 dbgprintf("CreateThread(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x) => 0x%x\n",
634 pSecAttr, dwStackSize, lpStartAddress, lpParameter, dwFlags, dwThreadId, pth);
635 return pth;
638 static DWORD WINAPI expResumeThread(HANDLE hThread)
640 int ret = 1;
641 dbgprintf("ResumeThread(0x%x) => 0x%x\n", hThread, ret);
642 return ret;
645 struct mutex_list_t;
647 struct mutex_list_t
649 char type;
650 pthread_mutex_t *pm;
651 pthread_cond_t *pc;
652 char state;
653 char reset;
654 char name[128];
655 int semaphore;
656 int lock_count;
657 pthread_t owner;
658 struct mutex_list_t* next;
659 struct mutex_list_t* prev;
661 typedef struct mutex_list_t mutex_list;
662 static mutex_list* mlist=NULL;
663 static pthread_mutex_t mlist_lock = PTHREAD_MUTEX_INITIALIZER;
665 void destroy_event(void* event)
667 mutex_list *pp;
668 pthread_mutex_lock(&mlist_lock);
669 pp=mlist;
670 // printf("garbage collector: destroy_event(%x)\n", event);
671 while(pp)
673 if(pp==(mutex_list*)event)
675 if(pp->next)
676 pp->next->prev=pp->prev;
677 if(pp->prev)
678 pp->prev->next=pp->next;
679 if(mlist==(mutex_list*)event)
680 mlist=mlist->prev;
682 pp=mlist;
683 while(pp)
685 printf("%x => ", pp);
686 pp=pp->prev;
688 printf("0\n");
690 pthread_mutex_unlock(&mlist_lock);
691 return;
693 pp=pp->prev;
695 pthread_mutex_unlock(&mlist_lock);
698 static void* WINAPI expCreateEventA(void* pSecAttr, char bManualReset,
699 char bInitialState, const char* name)
701 pthread_mutex_t *pm;
702 pthread_cond_t *pc;
703 void *ret;
705 mutex_list* pp;
706 pp=mlist;
707 while(pp)
709 printf("%x => ", pp);
710 pp=pp->prev;
712 printf("0\n");
714 pthread_mutex_lock(&mlist_lock);
715 if(mlist!=NULL)
717 mutex_list* pp=mlist;
718 if(name!=NULL)
721 if((strcmp(pp->name, name)==0) && (pp->type==0))
723 dbgprintf("CreateEventA(0x%x, 0x%x, 0x%x, 0x%x='%s') => 0x%x\n",
724 pSecAttr, bManualReset, bInitialState, name, name, pp->pm);
725 pthread_mutex_unlock(&mlist_lock);
726 return pp->pm;
728 }while((pp=pp->prev) != NULL);
730 pm=mreq_private(sizeof(pthread_mutex_t), 0, AREATYPE_MUTEX);
731 pthread_mutex_init(pm, NULL);
732 pc=mreq_private(sizeof(pthread_cond_t), 0, AREATYPE_COND);
733 pthread_cond_init(pc, NULL);
734 if(mlist==NULL)
736 mlist=mreq_private(sizeof(mutex_list), 00, AREATYPE_EVENT);
737 mlist->next=mlist->prev=NULL;
739 else
741 mlist->next=mreq_private(sizeof(mutex_list), 00, AREATYPE_EVENT);
742 mlist->next->prev=mlist;
743 mlist->next->next=NULL;
744 mlist=mlist->next;
746 mlist->type=0; /* Type Event */
747 mlist->pm=pm;
748 mlist->pc=pc;
749 mlist->state=bInitialState;
750 mlist->reset=!bManualReset;
751 if(name)
752 strncpy(mlist->name, name, 127);
753 else
754 mlist->name[0]=0;
755 if(pm==NULL)
756 dbgprintf("ERROR::: CreateEventA failure\n");
758 if(bInitialState)
759 pthread_mutex_lock(pm);
761 if(name)
762 dbgprintf("CreateEventA(0x%x, 0x%x, 0x%x, 0x%x='%s') => 0x%x\n",
763 pSecAttr, bManualReset, bInitialState, name, name, mlist);
764 else
765 dbgprintf("CreateEventA(0x%x, 0x%x, 0x%x, NULL) => 0x%x\n",
766 pSecAttr, bManualReset, bInitialState, mlist);
767 ret = mlist;
768 pthread_mutex_unlock(&mlist_lock);
769 return ret;
772 static void* WINAPI expCreateEventW(void* pSecAttr, char bManualReset,
773 char bInitialState, const WCHAR* name)
775 char ascii_name[256];
776 char *aname = NULL;
777 if (name) {
778 WideCharToMultiByte(65001, 0x0, name, -1, ascii_name, 256, NULL, NULL);
779 aname = ascii_name;
781 return expCreateEventA(pSecAttr, bManualReset, bInitialState, aname);
784 static void* WINAPI expSetEvent(void* event)
786 mutex_list *ml = (mutex_list *)event;
787 dbgprintf("SetEvent(%x) => 0x1\n", event);
788 pthread_mutex_lock(ml->pm);
789 if (ml->state == 0) {
790 ml->state = 1;
791 pthread_cond_signal(ml->pc);
793 pthread_mutex_unlock(ml->pm);
795 return (void *)1;
797 static void* WINAPI expResetEvent(void* event)
799 mutex_list *ml = (mutex_list *)event;
800 dbgprintf("ResetEvent(0x%x) => 0x1\n", event);
801 pthread_mutex_lock(ml->pm);
802 ml->state = 0;
803 pthread_mutex_unlock(ml->pm);
805 return (void *)1;
808 static void* WINAPI expWaitForSingleObject(void* object, int duration)
810 mutex_list *ml = (mutex_list *)object;
811 // FIXME FIXME FIXME - this value is sometime unititialize !!!
812 int ret = WAIT_FAILED;
813 mutex_list* pp;
814 th_list* tp;
815 if(object == (void*)0xcfcf9898)
818 From GetCurrentThread() documentation:
819 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.
821 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.
823 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.
825 dbgprintf("WaitForSingleObject(thread_handle) called\n");
826 return (void*)WAIT_FAILED;
828 dbgprintf("WaitForSingleObject(0x%x, duration %d) =>\n",object, duration);
830 // See if this is a thread.
831 pthread_mutex_lock(&list_lock);
832 tp=list;
833 while (tp && (tp->thread != object))
834 tp = tp->prev;
835 pthread_mutex_unlock(&list_lock);
836 if (tp) {
837 if (pthread_join(*(pthread_t*)object, NULL) == 0) {
838 return (void*)WAIT_OBJECT_0;
839 } else {
840 return (void*)WAIT_FAILED;
844 // loop below was slightly fixed - its used just for checking if
845 // this object really exists in our list
846 if (!ml)
847 return (void*) ret;
848 pthread_mutex_lock(&mlist_lock);
849 pp=mlist;
850 while (pp && (pp->pm != ml->pm))
851 pp = pp->prev;
852 pthread_mutex_unlock(&mlist_lock);
853 if (!pp) {
854 dbgprintf("WaitForSingleObject: NotFound\n");
855 return (void*)ret;
858 pthread_mutex_lock(ml->pm);
860 switch(ml->type) {
861 case 0: /* Event */
862 if (duration == 0) { /* Check Only */
863 if (ml->state == 1) ret = WAIT_OBJECT_0;
864 else ret = WAIT_FAILED;
866 if (duration == -1) { /* INFINITE */
867 if (ml->state == 0)
868 pthread_cond_wait(ml->pc,ml->pm);
869 if (ml->reset)
870 ml->state = 0;
871 ret = WAIT_OBJECT_0;
873 if (duration > 0) { /* Timed Wait */
874 struct timespec abstime;
875 struct timeval now;
876 gettimeofday(&now, 0);
877 abstime.tv_sec = now.tv_sec + (now.tv_usec+duration)/1000000;
878 abstime.tv_nsec = ((now.tv_usec+duration)%1000000)*1000;
879 if (ml->state == 0)
880 ret=pthread_cond_timedwait(ml->pc,ml->pm,&abstime);
881 if (ret == ETIMEDOUT) ret = WAIT_TIMEOUT;
882 else ret = WAIT_OBJECT_0;
883 if (ml->reset)
884 ml->state = 0;
886 break;
887 case 1: /* Semaphore */
888 if (duration == 0) {
889 if(ml->semaphore==0) ret = WAIT_FAILED;
890 else {
891 ml->semaphore--;
892 ret = WAIT_OBJECT_0;
895 if (duration == -1) {
896 if (ml->semaphore==0)
897 pthread_cond_wait(ml->pc,ml->pm);
898 ml->semaphore--;
899 ret = WAIT_OBJECT_0;
901 break;
902 case 2: /* Mutex */
903 if (duration == 0) {
904 if(ml->lock_count > 0 && ml->owner != pthread_self()) ret = WAIT_FAILED;
905 else {
906 ml->lock_count++;
907 ml->owner = pthread_self();
908 ret = WAIT_OBJECT_0;
911 if (duration == -1) {
912 if (ml->lock_count > 0 && ml->owner != pthread_self()) {
913 pthread_cond_wait(ml->pc,ml->pm);
915 ml->lock_count++;
916 ml->owner = pthread_self();
917 ret = WAIT_OBJECT_0;
919 break;
921 pthread_mutex_unlock(ml->pm);
923 dbgprintf("WaitForSingleObject(0x%x, %d): 0x%x => 0x%x \n",object,duration,ml,ret);
924 return (void *)ret;
927 #ifdef CONFIG_QTX_CODECS
928 static void* WINAPI expWaitForMultipleObjects(int count, const void** objects,
929 int WaitAll, int duration)
931 int i;
932 void *object;
933 void *ret;
935 dbgprintf("WaitForMultipleObjects(%d, 0x%x, %d, duration %d) =>\n",
936 count, objects, WaitAll, duration);
938 for (i = 0; i < count; i++)
940 object = (void *)objects[i];
941 ret = expWaitForSingleObject(object, duration);
942 if (WaitAll)
943 dbgprintf("WaitAll flag not yet supported...\n");
944 else
945 return ret;
947 return NULL;
950 static void WINAPI expExitThread(int retcode)
952 dbgprintf("ExitThread(%d)\n", retcode);
953 pthread_exit(&retcode);
955 #endif
957 static int pf_set = 0;
958 static BYTE PF[64] = {0,};
960 static void DumpSystemInfo(const SYSTEM_INFO* si)
962 dbgprintf(" Processor architecture %d\n", si->u.s.wProcessorArchitecture);
963 dbgprintf(" Page size: %d\n", si->dwPageSize);
964 dbgprintf(" Minimum app address: %d\n", si->lpMinimumApplicationAddress);
965 dbgprintf(" Maximum app address: %d\n", si->lpMaximumApplicationAddress);
966 dbgprintf(" Active processor mask: 0x%x\n", si->dwActiveProcessorMask);
967 dbgprintf(" Number of processors: %d\n", si->dwNumberOfProcessors);
968 dbgprintf(" Processor type: 0x%x\n", si->dwProcessorType);
969 dbgprintf(" Allocation granularity: 0x%x\n", si->dwAllocationGranularity);
970 dbgprintf(" Processor level: 0x%x\n", si->wProcessorLevel);
971 dbgprintf(" Processor revision: 0x%x\n", si->wProcessorRevision);
974 static void WINAPI expGetSystemInfo(SYSTEM_INFO* si)
976 /* FIXME: better values for the two entries below... */
977 static int cache = 0;
978 static SYSTEM_INFO cachedsi;
979 dbgprintf("GetSystemInfo(%p) =>\n", si);
981 if (cache) {
982 goto exit;
984 memset(PF,0,sizeof(PF));
985 pf_set = 1;
987 cachedsi.u.s.wProcessorArchitecture = PROCESSOR_ARCHITECTURE_INTEL;
988 cachedsi.dwPageSize = getpagesize();
990 /* FIXME: better values for the two entries below... */
991 cachedsi.lpMinimumApplicationAddress = (void *)0x00000000;
992 cachedsi.lpMaximumApplicationAddress = (void *)0x7FFFFFFF;
993 cachedsi.dwActiveProcessorMask = 1;
994 cachedsi.dwNumberOfProcessors = 1;
995 cachedsi.dwProcessorType = PROCESSOR_INTEL_386;
996 cachedsi.dwAllocationGranularity = 0x10000;
997 cachedsi.wProcessorLevel = 5; /* pentium */
998 cachedsi.wProcessorRevision = 0x0101;
1000 /* mplayer's way to detect PF's */
1002 #include "cpudetect.h"
1004 if (gCpuCaps.hasMMX)
1005 PF[PF_MMX_INSTRUCTIONS_AVAILABLE] = TRUE;
1006 if (gCpuCaps.hasSSE)
1007 PF[PF_XMMI_INSTRUCTIONS_AVAILABLE] = TRUE;
1008 if (gCpuCaps.hasSSE2)
1009 PF[PF_XMMI64_INSTRUCTIONS_AVAILABLE] = TRUE;
1010 if (gCpuCaps.has3DNow)
1011 PF[PF_AMD3D_INSTRUCTIONS_AVAILABLE] = TRUE;
1013 if (gCpuCaps.cpuType == 4)
1015 cachedsi.dwProcessorType = PROCESSOR_INTEL_486;
1016 cachedsi.wProcessorLevel = 4;
1018 else if (gCpuCaps.cpuType >= 5)
1020 cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
1021 cachedsi.wProcessorLevel = 5;
1023 else
1025 cachedsi.dwProcessorType = PROCESSOR_INTEL_386;
1026 cachedsi.wProcessorLevel = 3;
1028 cachedsi.wProcessorRevision = gCpuCaps.cpuStepping;
1029 cachedsi.dwNumberOfProcessors = 1; /* hardcoded */
1032 /* MPlayer: linux detection enabled (based on proc/cpuinfo) for checking
1033 fdiv_bug and fpu emulation flags -- alex/MPlayer */
1034 #ifdef __linux__
1036 char buf[20];
1037 char line[200];
1038 FILE *f = fopen ("/proc/cpuinfo", "r");
1040 if (!f)
1042 mp_msg(MSGT_WIN32, MSGL_WARN, "expGetSystemInfo: "
1043 "/proc/cpuinfo not readable! "
1044 "Expect bad performance and/or weird behaviour\n");
1045 goto exit;
1047 while (fgets(line,200,f)!=NULL) {
1048 char *s,*value;
1050 /* NOTE: the ':' is the only character we can rely on */
1051 if (!(value = strchr(line,':')))
1052 continue;
1053 /* terminate the valuename */
1054 *value++ = '\0';
1055 /* skip any leading spaces */
1056 while (*value==' ') value++;
1057 if ((s=strchr(value,'\n')))
1058 *s='\0';
1060 /* 2.1 method */
1061 if (!lstrncmpiA(line, "cpu family",strlen("cpu family"))) {
1062 if (isdigit (value[0])) {
1063 switch (value[0] - '0') {
1064 case 3: cachedsi.dwProcessorType = PROCESSOR_INTEL_386;
1065 cachedsi.wProcessorLevel= 3;
1066 break;
1067 case 4: cachedsi.dwProcessorType = PROCESSOR_INTEL_486;
1068 cachedsi.wProcessorLevel= 4;
1069 break;
1070 case 5: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
1071 cachedsi.wProcessorLevel= 5;
1072 break;
1073 case 6: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
1074 cachedsi.wProcessorLevel= 5;
1075 break;
1076 default:cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
1077 cachedsi.wProcessorLevel= 5;
1078 break;
1081 /* set the CPU type of the current processor */
1082 sprintf(buf,"CPU %ld",cachedsi.dwProcessorType);
1083 continue;
1085 /* old 2.0 method */
1086 if (!lstrncmpiA(line, "cpu",strlen("cpu"))) {
1087 if ( isdigit (value[0]) && value[1] == '8' &&
1088 value[2] == '6' && value[3] == 0
1090 switch (value[0] - '0') {
1091 case 3: cachedsi.dwProcessorType = PROCESSOR_INTEL_386;
1092 cachedsi.wProcessorLevel= 3;
1093 break;
1094 case 4: cachedsi.dwProcessorType = PROCESSOR_INTEL_486;
1095 cachedsi.wProcessorLevel= 4;
1096 break;
1097 case 5: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
1098 cachedsi.wProcessorLevel= 5;
1099 break;
1100 case 6: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
1101 cachedsi.wProcessorLevel= 5;
1102 break;
1103 default:cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
1104 cachedsi.wProcessorLevel= 5;
1105 break;
1108 /* set the CPU type of the current processor */
1109 sprintf(buf,"CPU %ld",cachedsi.dwProcessorType);
1110 continue;
1112 if (!lstrncmpiA(line,"fdiv_bug",strlen("fdiv_bug"))) {
1113 if (!lstrncmpiA(value,"yes",3))
1114 PF[PF_FLOATING_POINT_PRECISION_ERRATA] = TRUE;
1116 continue;
1118 if (!lstrncmpiA(line,"fpu",strlen("fpu"))) {
1119 if (!lstrncmpiA(value,"no",2))
1120 PF[PF_FLOATING_POINT_EMULATED] = TRUE;
1122 continue;
1124 if (!lstrncmpiA(line,"processor",strlen("processor"))) {
1125 /* processor number counts up...*/
1126 unsigned int x;
1128 if (sscanf(value,"%d",&x))
1129 if (x+1>cachedsi.dwNumberOfProcessors)
1130 cachedsi.dwNumberOfProcessors=x+1;
1132 /* Create a new processor subkey on a multiprocessor
1133 * system
1135 sprintf(buf,"%d",x);
1137 if (!lstrncmpiA(line,"stepping",strlen("stepping"))) {
1138 int x;
1140 if (sscanf(value,"%d",&x))
1141 cachedsi.wProcessorRevision = x;
1144 ( (!lstrncmpiA(line,"flags",strlen("flags")))
1145 || (!lstrncmpiA(line,"features",strlen("features"))) )
1147 if (strstr(value,"cx8"))
1148 PF[PF_COMPARE_EXCHANGE_DOUBLE] = TRUE;
1149 if (strstr(value,"mmx"))
1150 PF[PF_MMX_INSTRUCTIONS_AVAILABLE] = TRUE;
1151 if (strstr(value,"tsc"))
1152 PF[PF_RDTSC_INSTRUCTION_AVAILABLE] = TRUE;
1153 if (strstr(value,"xmm") || strstr(value,"sse"))
1154 PF[PF_XMMI_INSTRUCTIONS_AVAILABLE] = TRUE;
1155 if (strstr(value,"sse2"))
1156 PF[PF_XMMI64_INSTRUCTIONS_AVAILABLE] = TRUE;
1157 if (strstr(value,"3dnow"))
1158 PF[PF_AMD3D_INSTRUCTIONS_AVAILABLE] = TRUE;
1161 fclose (f);
1163 #endif /* __linux__ */
1164 cache = 1;
1165 exit:
1166 memcpy(si,&cachedsi,sizeof(*si));
1167 DumpSystemInfo(si);
1170 // avoid undefined expGetSystemInfo
1171 static WIN_BOOL WINAPI expIsProcessorFeaturePresent(DWORD v)
1173 WIN_BOOL result = 0;
1174 if (!pf_set)
1176 SYSTEM_INFO si;
1177 expGetSystemInfo(&si);
1179 if(v<64) result=PF[v];
1180 dbgprintf("IsProcessorFeaturePresent(0x%x) => 0x%x\n", v, result);
1181 return result;
1184 static WIN_BOOL WINAPI expIsDebuggerPresent(void)
1186 return 0;
1189 static long WINAPI expGetVersion(void)
1191 dbgprintf("GetVersion() => 0xC0000004\n");
1192 return 0xC0000004;//Windows 95
1195 static HANDLE WINAPI expHeapCreate(long flags, long init_size, long max_size)
1197 // printf("HeapCreate:");
1198 HANDLE result;
1199 if(init_size==0)
1200 result=(HANDLE)my_mreq(0x110000, 0);
1201 else
1202 result=(HANDLE)my_mreq((init_size + 0xfff) & 0x7ffff000 , 0);
1203 dbgprintf("HeapCreate(flags 0x%x, initial size %d, maximum size %d) => 0x%x\n", flags, init_size, max_size, result);
1204 return result;
1207 // this is another dirty hack
1208 // VP31 is releasing one allocated Heap chunk twice
1209 // we will silently ignore this second call...
1210 static void* heapfreehack = 0;
1211 static int heapfreehackshown = 0;
1212 //void trapbug(void);
1213 static void* WINAPI expHeapAlloc(HANDLE heap, int flags, int size)
1215 void* z;
1217 Morgan's m3jpeg32.dll v. 2.0 encoder expects that request for
1218 HeapAlloc returns area larger than size argument :-/
1220 actually according to M$ Doc HeapCreate size should be rounded
1221 to page boundaries thus we should simulate this
1223 //if (size == 22276) trapbug();
1224 z=my_mreq((size + 0xfff) & 0x7ffff000, (flags & HEAP_ZERO_MEMORY));
1225 if(z==0)
1226 printf("HeapAlloc failure\n");
1227 dbgprintf("HeapAlloc(heap 0x%x, flags 0x%x, size %d) => 0x%x\n", heap, flags, size, z);
1228 heapfreehack = 0; // reset
1229 return z;
1231 static long WINAPI expHeapDestroy(void* heap)
1233 dbgprintf("HeapDestroy(heap 0x%x) => 1\n", heap);
1234 my_release(heap);
1235 return 1;
1238 static long WINAPI expHeapFree(HANDLE heap, DWORD dwFlags, LPVOID lpMem)
1240 dbgprintf("HeapFree(0x%x, 0x%x, pointer 0x%x) => 1\n", heap, dwFlags, lpMem);
1241 if (heapfreehack != lpMem && lpMem != (void*)0xffffffff
1242 && lpMem != (void*)0xbdbdbdbd)
1243 // 0xbdbdbdbd is for i263_drv.drv && libefence
1244 // it seems to be reading from relased memory
1245 // EF_PROTECT_FREE doens't show any probleme
1246 my_release(lpMem);
1247 else
1249 if (!heapfreehackshown++)
1250 printf("Info: HeapFree deallocating same memory twice! (%p)\n", lpMem);
1252 heapfreehack = lpMem;
1253 return 1;
1255 static long WINAPI expHeapSize(int heap, int flags, void* pointer)
1257 long result=my_size(pointer);
1258 dbgprintf("HeapSize(heap 0x%x, flags 0x%x, pointer 0x%x) => %d\n", heap, flags, pointer, result);
1259 return result;
1261 static void* WINAPI expHeapReAlloc(HANDLE heap,int flags,void *lpMem,int size)
1263 long orgsize = my_size(lpMem);
1264 dbgprintf("HeapReAlloc() Size %ld org %d\n",orgsize,size);
1265 return my_realloc(lpMem, size);
1267 static long WINAPI expGetProcessHeap(void)
1269 dbgprintf("GetProcessHeap() => 1\n");
1270 return 1;
1272 static void* WINAPI expVirtualAlloc(void* v1, long v2, long v3, long v4)
1274 void* z = VirtualAlloc(v1, v2, v3, v4);
1275 if(z==0)
1276 printf("VirtualAlloc failure\n");
1277 dbgprintf("VirtualAlloc(0x%x, %d, %d, %d) => 0x%x \n",v1,v2,v3,v4, z);
1278 return z;
1280 static int WINAPI expVirtualFree(void* v1, int v2, int v3)
1282 int result = VirtualFree(v1,v2,v3);
1283 dbgprintf("VirtualFree(0x%x, %d, %d) => %d\n",v1,v2,v3, result);
1284 return result;
1287 /* we're building a table of critical sections. cs_win pointer uses the DLL
1288 cs_unix is the real structure, we're using cs_win only to identifying cs_unix */
1289 struct critsecs_list_t
1291 CRITICAL_SECTION *cs_win;
1292 struct CRITSECT *cs_unix;
1295 /* 'NEWTYPE' is working with VIVO, 3ivX and QTX dll (no more segfaults) -- alex */
1296 #undef CRITSECS_NEWTYPE
1297 //#define CRITSECS_NEWTYPE 1
1299 #ifdef CRITSECS_NEWTYPE
1300 /* increased due to ucod needs more than 32 entries */
1301 /* and 64 should be enough for everything */
1302 #define CRITSECS_LIST_MAX 64
1303 static struct critsecs_list_t critsecs_list[CRITSECS_LIST_MAX];
1305 static int critsecs_get_pos(CRITICAL_SECTION *cs_win)
1307 int i;
1309 for (i=0; i < CRITSECS_LIST_MAX; i++)
1310 if (critsecs_list[i].cs_win == cs_win)
1311 return i;
1312 return -1;
1315 static int critsecs_get_unused(void)
1317 int i;
1319 for (i=0; i < CRITSECS_LIST_MAX; i++)
1320 if (critsecs_list[i].cs_win == NULL)
1321 return i;
1322 return -1;
1325 struct CRITSECT *critsecs_get_unix(CRITICAL_SECTION *cs_win)
1327 int i;
1329 for (i=0; i < CRITSECS_LIST_MAX; i++)
1330 if (critsecs_list[i].cs_win == cs_win && critsecs_list[i].cs_unix)
1331 return critsecs_list[i].cs_unix;
1332 return NULL;
1334 #endif
1336 static void WINAPI expInitializeCriticalSection(CRITICAL_SECTION* c)
1338 dbgprintf("InitializeCriticalSection(0x%x)\n", c);
1339 /* if(sizeof(pthread_mutex_t)>sizeof(CRITICAL_SECTION))
1341 printf(" ERROR:::: sizeof(pthread_mutex_t) is %d, expected <=%d!\n",
1342 sizeof(pthread_mutex_t), sizeof(CRITICAL_SECTION));
1343 return;
1345 /* pthread_mutex_init((pthread_mutex_t*)c, NULL); */
1346 #ifdef CRITSECS_NEWTYPE
1348 struct CRITSECT *cs;
1349 int i = critsecs_get_unused();
1351 if (i < 0)
1353 printf("InitializeCriticalSection(%p) - no more space in list\n", c);
1354 return;
1356 dbgprintf("got unused space at %d\n", i);
1357 cs = malloc(sizeof(struct CRITSECT));
1358 if (!cs)
1360 printf("InitializeCriticalSection(%p) - out of memory\n", c);
1361 return;
1363 pthread_mutex_init(&cs->mutex, NULL);
1364 pthread_cond_init(&cs->unlocked, NULL);
1365 cs->lock_count = 0;
1366 critsecs_list[i].cs_win = c;
1367 critsecs_list[i].cs_unix = cs;
1368 dbgprintf("InitializeCriticalSection -> itemno=%d, cs_win=%p, cs_unix=%p\n",
1369 i, c, cs);
1371 #else
1373 struct CRITSECT* cs = mreq_private(sizeof(struct CRITSECT) + sizeof(CRITICAL_SECTION),
1374 0, AREATYPE_CRITSECT);
1375 pthread_mutex_init(&cs->mutex, NULL);
1376 pthread_cond_init(&cs->unlocked, NULL);
1377 cs->lock_count = 0;
1378 cs->deadbeef = 0xdeadbeef;
1379 *(void**)c = cs;
1381 #endif
1382 return;
1385 static WIN_BOOL WINAPI expInitializeCriticalSectionAndSpinCount(CRITICAL_SECTION* c, DWORD spin)
1387 expInitializeCriticalSection(c);
1388 return 1;
1391 static void WINAPI expEnterCriticalSection(CRITICAL_SECTION* c)
1393 #ifdef CRITSECS_NEWTYPE
1394 struct CRITSECT* cs = critsecs_get_unix(c);
1395 #else
1396 struct CRITSECT* cs = (*(struct CRITSECT**)c);
1397 #endif
1398 dbgprintf("EnterCriticalSection(0x%x) %p\n",c, cs);
1399 if (!cs)
1401 dbgprintf("entered uninitialized critisec!\n");
1402 expInitializeCriticalSection(c);
1403 #ifdef CRITSECS_NEWTYPE
1404 cs=critsecs_get_unix(c);
1405 #else
1406 cs = (*(struct CRITSECT**)c);
1407 #endif
1408 dbgprintf("Win32 Warning: Accessed uninitialized Critical Section (%p)!\n", c);
1410 pthread_mutex_lock(&(cs->mutex));
1411 if (cs->lock_count > 0 && cs->id == pthread_self()) {
1412 cs->lock_count++;
1413 } else {
1414 while (cs->lock_count != 0) {
1415 pthread_cond_wait(&(cs->unlocked), &(cs->mutex));
1417 cs->lock_count = 1;
1418 cs->id = pthread_self();
1420 pthread_mutex_unlock(&(cs->mutex));
1421 return;
1423 static void WINAPI expLeaveCriticalSection(CRITICAL_SECTION* c)
1425 #ifdef CRITSECS_NEWTYPE
1426 struct CRITSECT* cs = critsecs_get_unix(c);
1427 #else
1428 struct CRITSECT* cs = (*(struct CRITSECT**)c);
1429 #endif
1430 // struct CRITSECT* cs=(struct CRITSECT*)c;
1431 dbgprintf("LeaveCriticalSection(0x%x) 0x%x\n",c, cs);
1432 if (!cs)
1434 dbgprintf("Win32 Warning: Leaving uninitialized Critical Section %p!!\n", c);
1435 return;
1437 pthread_mutex_lock(&(cs->mutex));
1438 if (cs->lock_count == 0) {
1439 dbgprintf("Win32 Warning: Unlocking unlocked Critical Section %p!!\n", c);
1440 } else {
1441 cs->lock_count--;
1443 if (cs->lock_count == 0) {
1444 pthread_cond_signal(&(cs->unlocked));
1446 pthread_mutex_unlock(&(cs->mutex));
1447 return;
1450 static void expfree(void* mem); /* forward declaration */
1452 static void WINAPI expDeleteCriticalSection(CRITICAL_SECTION *c)
1454 #ifdef CRITSECS_NEWTYPE
1455 struct CRITSECT* cs = critsecs_get_unix(c);
1456 #else
1457 struct CRITSECT* cs= (*(struct CRITSECT**)c);
1458 #endif
1459 // struct CRITSECT* cs=(struct CRITSECT*)c;
1460 dbgprintf("DeleteCriticalSection(0x%x)\n",c);
1462 if (!cs)
1464 dbgprintf("Win32 Warning: Deleting uninitialized Critical Section %p!!\n", c);
1465 return;
1468 pthread_mutex_lock(&(cs->mutex));
1469 if (cs->lock_count > 0)
1471 dbgprintf("Win32 Warning: Deleting locked Critical Section %p!!\n", c);
1473 pthread_mutex_unlock(&(cs->mutex));
1475 #ifndef GARBAGE
1476 pthread_mutex_destroy(&(cs->mutex));
1477 pthread_cond_destroy(&(cs->unlocked));
1478 // released by GarbageCollector in my_relase otherwise
1479 #endif
1480 my_release(cs);
1481 #ifdef CRITSECS_NEWTYPE
1483 int i = critsecs_get_pos(c);
1485 if (i < 0)
1487 printf("DeleteCriticalSection(%p) error (critsec not found)\n", c);
1488 return;
1491 critsecs_list[i].cs_win = NULL;
1492 expfree(critsecs_list[i].cs_unix);
1493 critsecs_list[i].cs_unix = NULL;
1494 dbgprintf("DeleteCriticalSection -> itemno=%d\n", i);
1496 #endif
1497 return;
1499 static int WINAPI expGetCurrentThreadId(void)
1501 dbgprintf("GetCurrentThreadId() => %d\n", pthread_self());
1502 return pthread_self();
1504 static int WINAPI expGetCurrentProcess(void)
1506 dbgprintf("GetCurrentProcess() => %d\n", getpid());
1507 return getpid();
1510 #ifdef CONFIG_QTX_CODECS
1511 // this version is required for Quicktime codecs (.qtx/.qts) to work.
1512 // (they assume some pointers at FS: segment)
1514 extern void* fs_seg;
1516 //static int tls_count;
1517 static int tls_use_map[64];
1518 static int WINAPI expTlsAlloc(void)
1520 int i;
1521 for(i=0; i<64; i++)
1522 if(tls_use_map[i]==0)
1524 tls_use_map[i]=1;
1525 dbgprintf("TlsAlloc() => %d\n",i);
1526 return i;
1528 dbgprintf("TlsAlloc() => -1 (ERROR)\n");
1529 return -1;
1532 //static int WINAPI expTlsSetValue(DWORD index, void* value)
1533 static int WINAPI expTlsSetValue(int index, void* value)
1535 dbgprintf("TlsSetValue(%d,0x%x) => 1\n",index,value);
1536 // if((index<0) || (index>64))
1537 if((index>=64))
1538 return 0;
1539 *(void**)((char*)fs_seg+0x88+4*index) = value;
1540 return 1;
1543 static void* WINAPI expTlsGetValue(DWORD index)
1545 dbgprintf("TlsGetValue(%d)\n",index);
1546 // if((index<0) || (index>64))
1547 if((index>=64)) return NULL;
1548 return *(void**)((char*)fs_seg+0x88+4*index);
1551 static int WINAPI expTlsFree(int idx)
1553 int index = (int) idx;
1554 dbgprintf("TlsFree(%d)\n",index);
1555 if((index<0) || (index>64))
1556 return 0;
1557 tls_use_map[index]=0;
1558 return 1;
1561 #else
1562 struct tls_s {
1563 void* value;
1564 int used;
1565 struct tls_s* prev;
1566 struct tls_s* next;
1569 static void* WINAPI expTlsAlloc(void)
1571 if (g_tls == NULL)
1573 g_tls=my_mreq(sizeof(tls_t), 0);
1574 g_tls->next=g_tls->prev=NULL;
1576 else
1578 g_tls->next=my_mreq(sizeof(tls_t), 0);
1579 g_tls->next->prev=g_tls;
1580 g_tls->next->next=NULL;
1581 g_tls=g_tls->next;
1583 dbgprintf("TlsAlloc() => 0x%x\n", g_tls);
1584 if (g_tls)
1585 g_tls->value=0; /* XXX For Divx.dll */
1586 return g_tls;
1589 static int WINAPI expTlsSetValue(void* idx, void* value)
1591 tls_t* index = (tls_t*) idx;
1592 int result;
1593 if(index==0)
1594 result=0;
1595 else
1597 index->value=value;
1598 result=1;
1600 dbgprintf("TlsSetValue(index 0x%x, value 0x%x) => %d \n", index, value, result );
1601 return result;
1603 static void* WINAPI expTlsGetValue(void* idx)
1605 tls_t* index = (tls_t*) idx;
1606 void* result;
1607 if(index==0)
1608 result=0;
1609 else
1610 result=index->value;
1611 dbgprintf("TlsGetValue(index 0x%x) => 0x%x\n", index, result);
1612 return result;
1614 static int WINAPI expTlsFree(void* idx)
1616 tls_t* index = (tls_t*) idx;
1617 int result;
1618 if(index==0)
1619 result=0;
1620 else
1622 if(index->next)
1623 index->next->prev=index->prev;
1624 if(index->prev)
1625 index->prev->next=index->next;
1626 if (g_tls == index)
1627 g_tls = index->prev;
1628 my_release((void*)index);
1629 result=1;
1631 dbgprintf("TlsFree(index 0x%x) => %d\n", index, result);
1632 return result;
1634 #endif
1636 static void* WINAPI expLocalAlloc(int flags, int size)
1638 void* z = my_mreq(size, (flags & GMEM_ZEROINIT));
1639 if (z == 0)
1640 printf("LocalAlloc() failed\n");
1641 dbgprintf("LocalAlloc(%d, flags 0x%x) => 0x%x\n", size, flags, z);
1642 return z;
1645 static void* WINAPI expLocalReAlloc(int handle,int size, int flags)
1647 void *newpointer;
1648 int oldsize;
1650 newpointer=NULL;
1651 if (flags & LMEM_MODIFY) {
1652 dbgprintf("LocalReAlloc MODIFY\n");
1653 return (void *)handle;
1655 oldsize = my_size((void *)handle);
1656 newpointer = my_realloc((void *)handle,size);
1657 dbgprintf("LocalReAlloc(%x %d(old %d), flags 0x%x) => 0x%x\n", handle,size,oldsize, flags,newpointer);
1659 return newpointer;
1662 static void* WINAPI expLocalLock(void* z)
1664 dbgprintf("LocalLock(0x%x) => 0x%x\n", z, z);
1665 return z;
1668 static void* WINAPI expGlobalAlloc(int flags, int size)
1670 void* z;
1671 dbgprintf("GlobalAlloc(%d, flags 0x%X)\n", size, flags);
1673 z=my_mreq(size, (flags & GMEM_ZEROINIT));
1674 //z=calloc(size, 1);
1675 //z=malloc(size);
1676 if(z==0)
1677 printf("GlobalAlloc() failed\n");
1678 dbgprintf("GlobalAlloc(%d, flags 0x%x) => 0x%x\n", size, flags, z);
1679 return z;
1681 static void* WINAPI expGlobalLock(void* z)
1683 dbgprintf("GlobalLock(0x%x) => 0x%x\n", z, z);
1684 return z;
1686 // pvmjpg20 - but doesn't work anyway
1687 static int WINAPI expGlobalSize(void* amem)
1689 int size = 100000;
1690 #ifdef GARBAGE
1691 alloc_header* header = last_alloc;
1692 alloc_header* mem = (alloc_header*) amem - 1;
1693 if (amem == 0)
1694 return 0;
1695 pthread_mutex_lock(&memmut);
1696 while (header)
1698 if (header->deadbeef != 0xdeadbeef)
1700 dbgprintf("FATAL found corrupted memory! %p 0x%lx (%d)\n", header, header->deadbeef, alccnt);
1701 break;
1704 if (header == mem)
1706 size = header->size;
1707 break;
1710 header = header->prev;
1712 pthread_mutex_unlock(&memmut);
1713 #endif
1715 dbgprintf("GlobalSize(0x%x)\n", amem);
1716 return size;
1719 static int WINAPI expLoadIconA( long hinstance, char *name )
1721 dbgprintf("LoadIconA( %ld, 0x%x ) => 1\n",hinstance,name);
1722 return 1;
1725 static int WINAPI expLoadStringA(long instance, long id, void* buf, long size)
1727 int result=LoadStringA(instance, id, buf, size);
1728 // if(buf)
1729 dbgprintf("LoadStringA(instance 0x%x, id 0x%x, buffer 0x%x, size %d) => %d ( %s )\n",
1730 instance, id, buf, size, result, buf);
1731 // else
1732 // dbgprintf("LoadStringA(instance 0x%x, id 0x%x, buffer 0x%x, size %d) => %d\n",
1733 // instance, id, buf, size, result);
1734 return result;
1737 static long WINAPI expMultiByteToWideChar(long v1, long v2, char* s1, long siz1, short* s2, int siz2)
1739 #warning FIXME
1740 int i;
1741 int result;
1742 if(s2==0)
1743 result=1;
1744 else
1746 if(siz1>siz2/2)siz1=siz2/2;
1747 for(i=1; i<=siz1; i++)
1749 *s2=*s1;
1750 if(!*s1)break;
1751 s2++;
1752 s1++;
1754 result=i;
1756 if(s1)
1757 dbgprintf("MultiByteToWideChar(codepage %d, flags 0x%x, string 0x%x='%s',"
1758 "size %d, dest buffer 0x%x, dest size %d) => %d\n",
1759 v1, v2, s1, s1, siz1, s2, siz2, result);
1760 else
1761 dbgprintf("MultiByteToWideChar(codepage %d, flags 0x%x, string NULL,"
1762 "size %d, dest buffer 0x%x, dest size %d) =>\n",
1763 v1, v2, siz1, s2, siz2, result);
1764 return result;
1766 static void wch_print(const short* str)
1768 dbgprintf(" src: ");
1769 while(*str)dbgprintf("%c", *str++);
1770 dbgprintf("\n");
1772 static long WINAPI expWideCharToMultiByte(long v1, long v2, short* s1, long siz1,
1773 char* s2, int siz2, char* c3, int* siz3)
1775 int result;
1776 dbgprintf("WideCharToMultiByte(codepage %d, flags 0x%x, src 0x%x, src size %d, "
1777 "dest 0x%x, dest size %d, defch 0x%x, used_defch 0x%x)", v1, v2, s1, siz1, s2, siz2, c3, siz3);
1778 result=WideCharToMultiByte(v1, v2, s1, siz1, s2, siz2, c3, siz3);
1779 dbgprintf("=> %d\n", result);
1780 //if(s1)wch_print(s1);
1781 if(s2)dbgprintf(" dest: %s\n", s2);
1782 return result;
1785 static long WINAPI expGetVersionExA(OSVERSIONINFOA* c)
1787 dbgprintf("GetVersionExA(0x%x) => 1\n", c);
1788 c->dwOSVersionInfoSize=sizeof(*c);
1789 c->dwMajorVersion=5;
1790 c->dwMinorVersion=1;
1791 c->dwBuildNumber=0x5010a28;
1792 c->dwPlatformId=VER_PLATFORM_WIN32_NT;
1793 strcpy(c->szCSDVersion, "Service Pack 2");
1794 dbgprintf(" Major version: 5\n Minor version: 1\n Build number: 0x5010a28\n"
1795 " Platform Id: VER_PLATFORM_WIN32_NT\n Version string: 'Service Pack 2'\n");
1796 return 1;
1799 static long WINAPI expGetVersionExW(OSVERSIONINFOW* c)
1801 char CSDVersion[128];
1802 dbgprintf("GetVersionExW(0x%x) => 1\n", c);
1803 c->dwOSVersionInfoSize=sizeof(*c);
1804 c->dwMajorVersion=5;
1805 c->dwMinorVersion=1;
1806 c->dwBuildNumber=0x5010a28;
1807 c->dwPlatformId=VER_PLATFORM_WIN32_NT;
1808 strcpy(CSDVersion, "Service Pack 2");
1809 MultiByteToWideChar(65001, 0x0, CSDVersion, -1, c->szCSDVersion, 128);
1810 dbgprintf(" Major version: 5\n Minor version: 1\n Build number: 0x5010a28\n"
1811 " Platform Id: VER_PLATFORM_WIN32_NT\n Version string: 'Service Pack 2'\n");
1812 return 1;
1815 static HANDLE WINAPI expCreateSemaphoreA(char* v1, long init_count,
1816 long max_count, char* name)
1818 pthread_mutex_t *pm;
1819 pthread_cond_t *pc;
1820 HANDLE ret;
1822 mutex_list* pp;
1823 printf("CreateSemaphoreA(%p = %s)\n", name, (name ? name : "<null>"));
1824 pp=mlist;
1825 while(pp)
1827 printf("%p => ", pp);
1828 pp=pp->prev;
1830 printf("0\n");
1832 pthread_mutex_lock(&mlist_lock);
1833 if(mlist!=NULL)
1835 mutex_list* pp=mlist;
1836 if(name!=NULL)
1839 if((strcmp(pp->name, name)==0) && (pp->type==1))
1841 dbgprintf("CreateSemaphoreA(0x%x, init_count %d, max_count %d, name 0x%x='%s') => 0x%x\n",
1842 v1, init_count, max_count, name, name, mlist);
1843 ret = (HANDLE)mlist;
1844 pthread_mutex_unlock(&mlist_lock);
1845 return ret;
1847 }while((pp=pp->prev) != NULL);
1849 pm=mreq_private(sizeof(pthread_mutex_t), 0, AREATYPE_MUTEX);
1850 pthread_mutex_init(pm, NULL);
1851 pc=mreq_private(sizeof(pthread_cond_t), 0, AREATYPE_COND);
1852 pthread_cond_init(pc, NULL);
1853 if(mlist==NULL)
1855 mlist=mreq_private(sizeof(mutex_list), 00, AREATYPE_EVENT);
1856 mlist->next=mlist->prev=NULL;
1858 else
1860 mlist->next=mreq_private(sizeof(mutex_list), 00, AREATYPE_EVENT);
1861 mlist->next->prev=mlist;
1862 mlist->next->next=NULL;
1863 mlist=mlist->next;
1864 // printf("new semaphore %p\n", mlist);
1866 mlist->type=1; /* Type Semaphore */
1867 mlist->pm=pm;
1868 mlist->pc=pc;
1869 mlist->state=0;
1870 mlist->reset=0;
1871 mlist->semaphore=init_count;
1872 if(name!=NULL)
1873 strncpy(mlist->name, name, 64);
1874 else
1875 mlist->name[0]=0;
1876 if(pm==NULL)
1877 dbgprintf("ERROR::: CreateSemaphoreA failure\n");
1878 if(name)
1879 dbgprintf("CreateSemaphoreA(0x%x, init_count %d, max_count %d, name 0x%x='%s') => 0x%x\n",
1880 v1, init_count, max_count, name, name, mlist);
1881 else
1882 dbgprintf("CreateSemaphoreA(0x%x, init_count %d, max_count %d, name 0) => 0x%x\n",
1883 v1, init_count, max_count, mlist);
1884 ret = (HANDLE)mlist;
1885 pthread_mutex_unlock(&mlist_lock);
1886 return ret;
1889 static HANDLE WINAPI expCreateSemaphoreW(char* v1, long init_count,
1890 long max_count, const WCHAR* name)
1892 char ascii_name[256];
1893 char *aname = NULL;
1894 if (name) {
1895 WideCharToMultiByte(65001, 0x0, name, -1, ascii_name, 256, NULL, NULL);
1896 aname = ascii_name;
1898 return expCreateSemaphoreA(v1, init_count, max_count, aname);
1901 static long WINAPI expReleaseSemaphore(long hsem, long increment, long* prev_count)
1903 // The state of a semaphore object is signaled when its count
1904 // is greater than zero and nonsignaled when its count is equal to zero
1905 // Each time a waiting thread is released because of the semaphore's signaled
1906 // state, the count of the semaphore is decreased by one.
1907 mutex_list *ml = (mutex_list *)hsem;
1909 pthread_mutex_lock(ml->pm);
1910 if (prev_count != 0) *prev_count = ml->semaphore;
1911 if (ml->semaphore == 0) pthread_cond_signal(ml->pc);
1912 ml->semaphore += increment;
1913 pthread_mutex_unlock(ml->pm);
1914 dbgprintf("ReleaseSemaphore(semaphore 0x%x, increment %d, prev_count 0x%x) => 1\n",
1915 hsem, increment, prev_count);
1916 return 1;
1919 static HANDLE WINAPI expCreateMutexA(void *pSecAttr,
1920 char bInitialOwner, const char *name)
1922 pthread_mutex_t *pm;
1923 pthread_cond_t *pc;
1924 HANDLE ret;
1925 pthread_mutex_lock(&mlist_lock);
1926 if(mlist!=NULL)
1928 mutex_list* pp=mlist;
1929 if(name!=NULL)
1932 if((strcmp(pp->name, name)==0) && (pp->type==2))
1934 dbgprintf("CreateMutexA(0x%x, %d, '%s') => 0x%x\n", pSecAttr, bInitialOwner, name, mlist);
1935 ret = (HANDLE)mlist;
1936 pthread_mutex_unlock(&mlist_lock);
1937 return ret;
1939 }while((pp=pp->prev) != NULL);
1941 pm=mreq_private(sizeof(pthread_mutex_t), 0, AREATYPE_MUTEX);
1942 pthread_mutex_init(pm, NULL);
1943 pc=mreq_private(sizeof(pthread_cond_t), 0, AREATYPE_COND);
1944 pthread_cond_init(pc, NULL);
1945 if(mlist==NULL)
1947 mlist=mreq_private(sizeof(mutex_list), 00, AREATYPE_EVENT);
1948 mlist->next=mlist->prev=NULL;
1950 else
1952 mlist->next=mreq_private(sizeof(mutex_list), 00, AREATYPE_EVENT);
1953 mlist->next->prev=mlist;
1954 mlist->next->next=NULL;
1955 mlist=mlist->next;
1957 mlist->type=2; /* Type Mutex */
1958 mlist->pm=pm;
1959 mlist->pc=pc;
1960 mlist->state=0;
1961 mlist->reset=0;
1962 mlist->semaphore=0;
1963 if (bInitialOwner) {
1964 mlist->owner = pthread_self();
1965 mlist->lock_count = 1;
1966 } else {
1967 mlist->owner = (pthread_t)0;
1968 mlist->lock_count = 0;
1970 if(name!=NULL)
1971 strncpy(mlist->name, name, 64);
1972 else
1973 mlist->name[0]=0;
1974 if(pm==NULL)
1975 dbgprintf("ERROR::: CreateMutexA failure\n");
1976 if(name)
1977 dbgprintf("CreateMutexA(0x%x, %d, '%s') => 0x%x\n",
1978 pSecAttr, bInitialOwner, name, mlist);
1979 else
1980 dbgprintf("CreateMutexA(0x%x, %d, NULL) => 0x%x\n",
1981 pSecAttr, bInitialOwner, mlist);
1982 ret = (HANDLE)mlist;
1983 pthread_mutex_unlock(&mlist_lock);
1984 return ret;
1987 static HANDLE WINAPI expCreateMutexW(void *pSecAttr, char bInitialOwner, const WCHAR *name)
1989 char ascii_name[256];
1990 char *aname = NULL;
1991 if (name) {
1992 WideCharToMultiByte(65001, 0x0, name, -1, ascii_name, 256, NULL, NULL);
1993 aname = ascii_name;
1995 return expCreateMutexA(pSecAttr, bInitialOwner, aname);
1998 static int WINAPI expReleaseMutex(HANDLE hMutex)
2000 mutex_list *ml = (mutex_list *)hMutex;
2002 pthread_mutex_lock(ml->pm);
2003 if (--ml->lock_count == 0) pthread_cond_signal(ml->pc);
2004 pthread_mutex_unlock(ml->pm);
2005 return 1;
2008 static DWORD WINAPI expSignalObjectAndWait(HANDLE hObjectToSignal,
2009 HANDLE hObjectToWaitOn,
2010 DWORD dwMilliseconds,
2011 WIN_BOOL bAlertable) {
2012 mutex_list* mlist = (mutex_list*)hObjectToSignal;
2014 switch (mlist->type) {
2015 case 0: // Event
2016 expSetEvent(mlist);
2017 break;
2018 case 1: // Semaphore
2019 expReleaseSemaphore(mlist, 1, NULL);
2020 break;
2021 case 2: // Mutex
2022 expReleaseMutex(mlist);
2023 break;
2024 default:
2025 dbgprintf("Signalling unknown object type %d!\n", hObjectToSignal);
2027 return expWaitForSingleObject(hObjectToWaitOn, dwMilliseconds);
2030 static long WINAPI expRegOpenKeyExA(long key, const char* subkey, long reserved, long access, int* newkey)
2032 long result=RegOpenKeyExA(key, subkey, reserved, access, newkey);
2033 dbgprintf("RegOpenKeyExA(key 0x%x, subkey %s, reserved %d, access 0x%x, pnewkey 0x%x) => %d\n",
2034 key, subkey, reserved, access, newkey, result);
2035 if(newkey)dbgprintf(" New key: 0x%x\n", *newkey);
2036 return result;
2038 static long WINAPI expRegCloseKey(long key)
2040 long result=RegCloseKey(key);
2041 dbgprintf("RegCloseKey(0x%x) => %d\n", key, result);
2042 return result;
2044 static long WINAPI expRegQueryValueExA(long key, const char* value, int* reserved, int* type, int* data, int* count)
2046 long result=RegQueryValueExA(key, value, reserved, type, data, count);
2047 dbgprintf("RegQueryValueExA(key 0x%x, value %s, reserved 0x%x, data 0x%x, count 0x%x)"
2048 " => 0x%x\n", key, value, reserved, data, count, result);
2049 if(data && count)dbgprintf(" read %d bytes: '%s'\n", *count, data);
2050 return result;
2053 //from wine source dlls/advapi32/registry.c
2054 static long WINAPI expRegCreateKeyA(long hkey, const char* name, int *retkey)
2056 dbgprintf("RegCreateKeyA(key 0x%x, name 0x%x='%s',newkey=0x%x)\n",hkey,name,retkey);
2057 return RegCreateKeyExA( hkey, name, 0, NULL,REG_OPTION_NON_VOLATILE,
2058 KEY_ALL_ACCESS , NULL, retkey, NULL );
2061 static long WINAPI expRegCreateKeyExA(long key, const char* name, long reserved,
2062 void* classs, long options, long security,
2063 void* sec_attr, int* newkey, int* status)
2065 long result=RegCreateKeyExA(key, name, reserved, classs, options, security, sec_attr, newkey, status);
2066 dbgprintf("RegCreateKeyExA(key 0x%x, name 0x%x='%s', reserved=0x%x,"
2067 " 0x%x, 0x%x, 0x%x, newkey=0x%x, status=0x%x) => %d\n",
2068 key, name, name, reserved, classs, options, security, sec_attr, newkey, status, result);
2069 if(!result && newkey) dbgprintf(" New key: 0x%x\n", *newkey);
2070 if(!result && status) dbgprintf(" New key status: 0x%x\n", *status);
2071 return result;
2073 static long WINAPI expRegSetValueExA(long key, const char* name, long v1, long v2, void* data, long size)
2075 long result=RegSetValueExA(key, name, v1, v2, data, size);
2076 dbgprintf("RegSetValueExA(key 0x%x, name '%s', 0x%x, 0x%x, data 0x%x -> 0x%x '%s', size=%d) => %d",
2077 key, name, v1, v2, data, *(int*)data, data, size, result);
2078 return result;
2081 static long WINAPI expRegOpenKeyA (long hKey, LPCSTR lpSubKey, int* phkResult)
2083 long result=RegOpenKeyExA(hKey, lpSubKey, 0, 0, phkResult);
2084 dbgprintf("RegOpenKeyExA(key 0x%x, subkey '%s', 0x%x) => %d\n",
2085 hKey, lpSubKey, phkResult, result);
2086 if(!result && phkResult) dbgprintf(" New key: 0x%x\n", *phkResult);
2087 return result;
2090 static DWORD WINAPI expRegEnumValueA(HKEY hkey, DWORD index, LPSTR value, LPDWORD val_count,
2091 LPDWORD reserved, LPDWORD type, LPBYTE data, LPDWORD count)
2093 return RegEnumValueA(hkey, index, value, val_count,
2094 reserved, type, data, count);
2097 static DWORD WINAPI expRegEnumKeyExA(HKEY hKey, DWORD dwIndex, LPSTR lpName, LPDWORD lpcbName,
2098 LPDWORD lpReserved, LPSTR lpClass, LPDWORD lpcbClass,
2099 LPFILETIME lpftLastWriteTime)
2101 return RegEnumKeyExA(hKey, dwIndex, lpName, lpcbName, lpReserved, lpClass,
2102 lpcbClass, lpftLastWriteTime);
2105 static long WINAPI expQueryPerformanceCounter(long long* z)
2107 longcount(z);
2108 dbgprintf("QueryPerformanceCounter(0x%x) => 1 ( %Ld )\n", z, *z);
2109 return 1;
2113 * dummy function RegQueryInfoKeyA(), required by vss codecs
2115 static DWORD WINAPI expRegQueryInfoKeyA( HKEY hkey, LPSTR class, LPDWORD class_len, LPDWORD reserved,
2116 LPDWORD subkeys, LPDWORD max_subkey, LPDWORD max_class,
2117 LPDWORD values, LPDWORD max_value, LPDWORD max_data,
2118 LPDWORD security, FILETIME *modif )
2120 return ERROR_SUCCESS;
2124 * return CPU clock (in kHz), using linux's /proc filesystem (/proc/cpuinfo)
2126 static double linux_cpuinfo_freq(void)
2128 double freq=-1;
2129 FILE *f;
2130 char line[200];
2131 char *s,*value;
2133 f = fopen ("/proc/cpuinfo", "r");
2134 if (f != NULL) {
2135 while (fgets(line,sizeof(line),f)!=NULL) {
2136 /* NOTE: the ':' is the only character we can rely on */
2137 if (!(value = strchr(line,':')))
2138 continue;
2139 /* terminate the valuename */
2140 *value++ = '\0';
2141 /* skip any leading spaces */
2142 while (*value==' ') value++;
2143 if ((s=strchr(value,'\n')))
2144 *s='\0';
2146 if (!strncasecmp(line, "cpu MHz",strlen("cpu MHz"))
2147 && sscanf(value, "%lf", &freq) == 1) {
2148 freq*=1000;
2149 break;
2152 fclose(f);
2154 return freq;
2158 static double solaris_kstat_freq(void)
2160 #if defined(HAVE_LIBKSTAT) && defined(KSTAT_DATA_INT32)
2162 * try to extract the CPU speed from the solaris kernel's kstat data
2164 kstat_ctl_t *kc;
2165 kstat_t *ksp;
2166 kstat_named_t *kdata;
2167 int mhz = 0;
2169 kc = kstat_open();
2170 if (kc != NULL)
2172 ksp = kstat_lookup(kc, "cpu_info", 0, "cpu_info0");
2174 /* kstat found and name/value pairs? */
2175 if (ksp != NULL && ksp->ks_type == KSTAT_TYPE_NAMED)
2177 /* read the kstat data from the kernel */
2178 if (kstat_read(kc, ksp, NULL) != -1)
2181 * lookup desired "clock_MHz" entry, check the expected
2182 * data type
2184 kdata = (kstat_named_t *)kstat_data_lookup(ksp, "clock_MHz");
2185 if (kdata != NULL && kdata->data_type == KSTAT_DATA_INT32)
2186 mhz = kdata->value.i32;
2189 kstat_close(kc);
2192 if (mhz > 0)
2193 return mhz * 1000.;
2194 #endif /* HAVE_LIBKSTAT */
2195 return -1; // kstat stuff is not available, CPU freq is unknown
2199 * Measure CPU freq using the pentium's time stamp counter register (TSC)
2201 static double tsc_freq(void)
2203 static double ofreq=0.0;
2204 int i;
2205 int x,y;
2206 i=time(NULL);
2207 if (ofreq != 0.0) return ofreq;
2208 while(i==time(NULL));
2209 x=localcount();
2210 i++;
2211 while(i==time(NULL));
2212 y=localcount();
2213 ofreq = (double)(y-x)/1000.;
2214 return ofreq;
2217 static double CPU_Freq(void)
2219 double freq;
2221 if ((freq = linux_cpuinfo_freq()) > 0)
2222 return freq;
2224 if ((freq = solaris_kstat_freq()) > 0)
2225 return freq;
2227 return tsc_freq();
2230 static long WINAPI expQueryPerformanceFrequency(long long* z)
2232 *z=(long long)CPU_Freq();
2233 dbgprintf("QueryPerformanceFrequency(0x%x) => 1 ( %Ld )\n", z, *z);
2234 return 1;
2236 static long WINAPI exptimeGetTime(void)
2238 struct timeval t;
2239 long result;
2240 gettimeofday(&t, 0);
2241 result=1000*t.tv_sec+t.tv_usec/1000;
2242 dbgprintf("timeGetTime() => %d\n", result);
2243 return result;
2245 static void* WINAPI expLocalHandle(void* v)
2247 dbgprintf("LocalHandle(0x%x) => 0x%x\n", v, v);
2248 return v;
2251 static void* WINAPI expGlobalHandle(void* v)
2253 dbgprintf("GlobalHandle(0x%x) => 0x%x\n", v, v);
2254 return v;
2256 static int WINAPI expGlobalUnlock(void* v)
2258 dbgprintf("GlobalUnlock(0x%x) => 1\n", v);
2259 return 1;
2261 static void* WINAPI expGlobalFree(void* v)
2263 dbgprintf("GlobalFree(0x%x) => 0\n", v);
2264 my_release(v);
2265 //free(v);
2266 return 0;
2269 static void* WINAPI expGlobalReAlloc(void* v, int size, int flags)
2271 void* result=my_realloc(v, size);
2272 //void* result=realloc(v, size);
2273 dbgprintf("GlobalReAlloc(0x%x, size %d, flags 0x%x) => 0x%x\n", v,size,flags,result);
2274 return result;
2277 static int WINAPI expLocalUnlock(void* v)
2279 dbgprintf("LocalUnlock(0x%x) => 1\n", v);
2280 return 1;
2283 static void* WINAPI expLocalFree(void* v)
2285 dbgprintf("LocalFree(0x%x) => 0\n", v);
2286 my_release(v);
2287 return 0;
2289 static HRSRC WINAPI expFindResourceA(HMODULE module, char* name, char* type)
2291 HRSRC result;
2293 result=FindResourceA(module, name, type);
2294 dbgprintf("FindResourceA(module 0x%x, name 0x%x(%s), type 0x%x(%s)) => 0x%x\n",
2295 module, name, HIWORD(name) ? name : "UNICODE", type, HIWORD(type) ? type : "UNICODE", result);
2296 return result;
2299 static HGLOBAL WINAPI expLoadResource(HMODULE module, HRSRC res)
2301 HGLOBAL result=LoadResource(module, res);
2302 dbgprintf("LoadResource(module 0x%x, resource 0x%x) => 0x%x\n", module, res, result);
2303 return result;
2305 static void* WINAPI expLockResource(long res)
2307 void* result=LockResource(res);
2308 dbgprintf("LockResource(0x%x) => 0x%x\n", res, result);
2309 return result;
2311 static int WINAPI expFreeResource(long res)
2313 int result=FreeResource(res);
2314 dbgprintf("FreeResource(0x%x) => %d\n", res, result);
2315 return result;
2317 //bool fun(HANDLE)
2318 //!0 on success
2319 static int WINAPI expCloseHandle(long v1)
2321 dbgprintf("CloseHandle(0x%x) => 1\n", v1);
2322 /* do not close stdin,stdout and stderr */
2323 if (v1 > 2)
2324 if (!close(v1))
2325 return 0;
2326 return 1;
2329 static const char* WINAPI expGetCommandLineA(void)
2331 dbgprintf("GetCommandLineA() => \"c:\\aviplay.exe\"\n");
2332 return "c:\\aviplay.exe";
2334 static short envs[]={'p', 'a', 't', 'h', ' ', 'c', ':', '\\', 0, 0};
2335 static LPWSTR WINAPI expGetEnvironmentStringsW(void)
2337 dbgprintf("GetEnvironmentStringsW() => 0\n", envs);
2338 return 0;
2340 static void * WINAPI expRtlZeroMemory(void *p, size_t len)
2342 void* result=memset(p,0,len);
2343 dbgprintf("RtlZeroMemory(0x%x, len %d) => 0x%x\n",p,len,result);
2344 return result;
2346 static void * WINAPI expRtlMoveMemory(void *dst, void *src, size_t len)
2348 void* result=memmove(dst,src,len);
2349 dbgprintf("RtlMoveMemory (dest 0x%x, src 0x%x, len %d) => 0x%x\n",dst,src,len,result);
2350 return result;
2353 static void * WINAPI expRtlFillMemory(void *p, int ch, size_t len)
2355 void* result=memset(p,ch,len);
2356 dbgprintf("RtlFillMemory(0x%x, char 0x%x, len %d) => 0x%x\n",p,ch,len,result);
2357 return result;
2359 static int WINAPI expFreeEnvironmentStringsW(short* strings)
2361 dbgprintf("FreeEnvironmentStringsW(0x%x) => 1\n", strings);
2362 return 1;
2364 static int WINAPI expFreeEnvironmentStringsA(char* strings)
2366 dbgprintf("FreeEnvironmentStringsA(0x%x) => 1\n", strings);
2367 return 1;
2370 static const char ch_envs[]=
2371 "__MSVCRT_HEAP_SELECT=__GLOBAL_HEAP_SELECTED,1\r\n"
2372 "PATH=C:\\;C:\\windows\\;C:\\windows\\system\r\n";
2373 static LPCSTR WINAPI expGetEnvironmentStrings(void)
2375 dbgprintf("GetEnvironmentStrings() => 0x%x\n", ch_envs);
2376 return (LPCSTR)ch_envs;
2377 // dbgprintf("GetEnvironmentStrings() => 0\n");
2378 // return 0;
2381 static int WINAPI expGetStartupInfoA(STARTUPINFOA *s)
2383 dbgprintf("GetStartupInfoA(0x%x) => 1\n");
2384 memset(s, 0, sizeof(*s));
2385 s->cb=sizeof(*s);
2386 // s->lpReserved="Reserved";
2387 // s->lpDesktop="Desktop";
2388 // s->lpTitle="Title";
2389 // s->dwX=s->dwY=0;
2390 // s->dwXSize=s->dwYSize=200;
2391 s->dwFlags=s->wShowWindow=1;
2392 // s->hStdInput=s->hStdOutput=s->hStdError=0x1234;
2393 dbgprintf(" cb=%d\n", s->cb);
2394 dbgprintf(" lpReserved='%s'\n", s->lpReserved);
2395 dbgprintf(" lpDesktop='%s'\n", s->lpDesktop);
2396 dbgprintf(" lpTitle='%s'\n", s->lpTitle);
2397 dbgprintf(" dwX=%d dwY=%d dwXSize=%d dwYSize=%d\n",
2398 s->dwX, s->dwY, s->dwXSize, s->dwYSize);
2399 dbgprintf(" dwXCountChars=%d dwYCountChars=%d dwFillAttribute=%d\n",
2400 s->dwXCountChars, s->dwYCountChars, s->dwFillAttribute);
2401 dbgprintf(" dwFlags=0x%x wShowWindow=0x%x cbReserved2=0x%x\n",
2402 s->dwFlags, s->wShowWindow, s->cbReserved2);
2403 dbgprintf(" lpReserved2=0x%x hStdInput=0x%x hStdOutput=0x%x hStdError=0x%x\n",
2404 s->lpReserved2, s->hStdInput, s->hStdOutput, s->hStdError);
2405 return 1;
2408 static int WINAPI expGetStdHandle(int z)
2410 dbgprintf("GetStdHandle(0x%x) => 0x%x\n", z+0x1234);
2411 return z+0x1234;
2414 #ifdef CONFIG_QTX_CODECS
2415 #define FILE_HANDLE_quicktimeqts ((HANDLE)0x444)
2416 #define FILE_HANDLE_quicktimeqtx ((HANDLE)0x445)
2417 #endif
2419 static int WINAPI expGetFileType(int handle)
2421 dbgprintf("GetFileType(0x%x) => 0x3 = pipe\n", handle);
2422 return 0x3;
2424 #ifdef CONFIG_QTX_CODECS
2425 static int WINAPI expGetFileAttributesA(char *filename)
2427 dbgprintf("GetFileAttributesA(%s) => FILE_ATTR_NORMAL\n", filename);
2428 if (strstr(filename, "QuickTime.qts"))
2429 return FILE_ATTRIBUTE_SYSTEM;
2430 return FILE_ATTRIBUTE_NORMAL;
2432 #endif
2433 static int WINAPI expSetHandleCount(int count)
2435 dbgprintf("SetHandleCount(0x%x) => 1\n", count);
2436 return 1;
2438 static int WINAPI expGetACP(void)
2440 dbgprintf("GetACP() => 0\n");
2441 return 0;
2443 static int WINAPI expGetModuleFileNameA(int module, char* s, int len)
2445 WINE_MODREF *mr;
2446 int result;
2447 //printf("File name of module %X (%s) requested\n", module, s);
2449 if (module == 0 && len >= 12)
2451 /* return caller program name */
2452 strcpy(s, "aviplay.dll");
2453 result=1;
2455 else if(s==0)
2456 result=0;
2457 else
2458 if(len<35)
2459 result=0;
2460 else
2462 result=1;
2463 strcpy(s, "c:\\windows\\system\\");
2464 mr=MODULE32_LookupHMODULE(module);
2465 if(mr==0)//oops
2466 strcat(s, "aviplay.dll");
2467 else
2468 if(strrchr(mr->filename, '/')==NULL)
2469 strcat(s, mr->filename);
2470 else
2471 strcat(s, strrchr(mr->filename, '/')+1);
2473 if(!s)
2474 dbgprintf("GetModuleFileNameA(0x%x, 0x%x, %d) => %d\n",
2475 module, s, len, result);
2476 else
2477 dbgprintf("GetModuleFileNameA(0x%x, 0x%x, %d) => %d ( '%s' )\n",
2478 module, s, len, result, s);
2479 return result;
2482 static int WINAPI expGetModuleBaseNameA(int process, int module, char* s, int len)
2484 int result = 0;
2486 if (s && len) {
2487 av_strlcpy(s, "aviplay.dll", len);
2488 result = strlen(s);
2491 dbgprintf("GetModuleBaseNameA(0x%x, 0x%x, 0x%x, %d) => %d\n",
2492 process, module, s, len, result);
2494 return result;
2497 static int WINAPI expSetUnhandledExceptionFilter(void* filter)
2499 dbgprintf("SetUnhandledExceptionFilter(0x%x) => 1\n", filter);
2500 return 1;//unsupported and probably won't ever be supported
2503 static int WINAPI expLoadLibraryA(char* name)
2505 int result = 0;
2506 char* lastbc;
2507 if (!name)
2508 return -1;
2509 // we skip to the last backslash
2510 // this is effectively eliminating weird characters in
2511 // the text output windows
2513 lastbc = strrchr(name, '\\');
2514 if (lastbc)
2516 int i;
2517 lastbc++;
2518 for (i = 0; 1 ;i++)
2520 name[i] = *lastbc++;
2521 if (!name[i])
2522 break;
2525 if(strncmp(name, "c:\\windows\\", 11)==0) name += 11;
2526 if(strncmp(name, ".\\", 2)==0) name += 2;
2528 dbgprintf("Entering LoadLibraryA(%s)\n", name);
2530 // PIMJ and VIVO audio are loading kernel32.dll
2531 if (strcasecmp(name, "kernel32.dll") == 0 || strcasecmp(name, "kernel32") == 0)
2532 return MODULE_HANDLE_kernel32;
2533 // return ERROR_SUCCESS; /* yeah, we have also the kernel32 calls */
2534 /* exported -> do not return failed! */
2536 if (strcasecmp(name, "user32.dll") == 0 || strcasecmp(name, "user32") == 0)
2537 // return MODULE_HANDLE_kernel32;
2538 return MODULE_HANDLE_user32;
2540 #ifdef CONFIG_QTX_CODECS
2541 if (strcasecmp(name, "wininet.dll") == 0 || strcasecmp(name, "wininet") == 0)
2542 return MODULE_HANDLE_wininet;
2543 if (strcasecmp(name, "ddraw.dll") == 0 || strcasecmp(name, "ddraw") == 0)
2544 return MODULE_HANDLE_ddraw;
2545 if (strcasecmp(name, "advapi32.dll") == 0 || strcasecmp(name, "advapi32") == 0)
2546 return MODULE_HANDLE_advapi32;
2547 #endif
2549 if (strcasecmp(name, "comdlg32.dll") == 0 || strcasecmp(name, "comdlg32") == 0)
2550 return MODULE_HANDLE_comdlg32;
2551 if (strcasecmp(name, "msvcrt.dll") == 0 || strcasecmp(name, "msvcrt") == 0)
2552 return MODULE_HANDLE_msvcrt;
2553 if (strcasecmp(name, "ole32.dll") == 0 || strcasecmp(name, "ole32") == 0)
2554 return MODULE_HANDLE_ole32;
2555 if (strcasecmp(name, "winmm.dll") == 0 || strcasecmp(name, "winmm") == 0)
2556 return MODULE_HANDLE_winmm;
2557 if (strcasecmp(name, "psapi.dll") == 0 || strcasecmp(name, "psapi") == 0)
2558 return MODULE_HANDLE_psapi;
2560 result=LoadLibraryA(name);
2561 dbgprintf("Returned LoadLibraryA(0x%x='%s'), codec_path=%s => 0x%x\n",
2562 name, name, codec_path, result);
2564 return result;
2567 static int WINAPI expFreeLibrary(int module)
2569 #ifdef CONFIG_QTX_CODECS
2570 int result=0; /* FIXME:XXX: qtx svq3 frees up qt.qts */
2571 #else
2572 int result=FreeLibrary(module);
2573 #endif
2574 dbgprintf("FreeLibrary(0x%x) => %d\n", module, result);
2575 return result;
2578 static void* WINAPI expGetProcAddress(HMODULE mod, char* name)
2580 void* result;
2581 switch(mod){
2582 case MODULE_HANDLE_kernel32:
2583 result=LookupExternalByName("kernel32.dll", name); break;
2584 case MODULE_HANDLE_user32:
2585 result=LookupExternalByName("user32.dll", name); break;
2586 #ifdef CONFIG_QTX_CODECS
2587 case MODULE_HANDLE_wininet:
2588 result=LookupExternalByName("wininet.dll", name); break;
2589 case MODULE_HANDLE_ddraw:
2590 result=LookupExternalByName("ddraw.dll", name); break;
2591 case MODULE_HANDLE_advapi32:
2592 result=LookupExternalByName("advapi32.dll", name); break;
2593 #endif
2594 case MODULE_HANDLE_comdlg32:
2595 result=LookupExternalByName("comdlg32.dll", name); break;
2596 case MODULE_HANDLE_msvcrt:
2597 result=LookupExternalByName("msvcrt.dll", name); break;
2598 case MODULE_HANDLE_ole32:
2599 result=LookupExternalByName("ole32.dll", name); break;
2600 case MODULE_HANDLE_winmm:
2601 result=LookupExternalByName("winmm.dll", name); break;
2602 case MODULE_HANDLE_psapi:
2603 result=LookupExternalByName("psapi.dll", name); break;
2604 default:
2605 result=GetProcAddress(mod, name);
2607 if((unsigned int)name > 0xffff)
2608 dbgprintf("GetProcAddress(0x%x, '%s') => 0x%x\n", mod, name, result);
2609 else
2610 dbgprintf("GetProcAddress(0x%x, '%d') => 0x%x\n", mod, (int)name, result);
2611 return result;
2614 static long WINAPI expCreateFileMappingA(int hFile, void* lpAttr,
2615 long flProtect, long dwMaxHigh,
2616 long dwMaxLow, const char* name)
2618 long result=CreateFileMappingA(hFile, lpAttr, flProtect, dwMaxHigh, dwMaxLow, name);
2619 if(!name)
2620 dbgprintf("CreateFileMappingA(file 0x%x, lpAttr 0x%x,"
2621 "flProtect 0x%x, dwMaxHigh 0x%x, dwMaxLow 0x%x, name 0) => %d\n",
2622 hFile, lpAttr, flProtect, dwMaxHigh, dwMaxLow, result);
2623 else
2624 dbgprintf("CreateFileMappingA(file 0x%x, lpAttr 0x%x,"
2625 "flProtect 0x%x, dwMaxHigh 0x%x, dwMaxLow 0x%x, name 0x%x='%s') => %d\n",
2626 hFile, lpAttr, flProtect, dwMaxHigh, dwMaxLow, name, name, result);
2627 return result;
2630 static long WINAPI expOpenFileMappingA(long hFile, long hz, const char* name)
2632 long result=OpenFileMappingA(hFile, hz, name);
2633 if(!name)
2634 dbgprintf("OpenFileMappingA(0x%x, 0x%x, 0) => %d\n",
2635 hFile, hz, result);
2636 else
2637 dbgprintf("OpenFileMappingA(0x%x, 0x%x, 0x%x='%s') => %d\n",
2638 hFile, hz, name, name, result);
2639 return result;
2642 static void* WINAPI expMapViewOfFile(HANDLE file, DWORD mode, DWORD offHigh,
2643 DWORD offLow, DWORD size)
2645 dbgprintf("MapViewOfFile(0x%x, 0x%x, 0x%x, 0x%x, size %d) => 0x%x\n",
2646 file,mode,offHigh,offLow,size,(char*)file+offLow);
2647 return (char*)file+offLow;
2650 static void* WINAPI expUnmapViewOfFile(void* view)
2652 dbgprintf("UnmapViewOfFile(0x%x) => 0\n", view);
2653 return 0;
2656 static void* WINAPI expSleep(int time)
2658 #if HAVE_NANOSLEEP
2659 /* solaris doesn't have thread safe usleep */
2660 struct timespec tsp;
2661 tsp.tv_sec = time / 1000000;
2662 tsp.tv_nsec = (time % 1000000) * 1000;
2663 nanosleep(&tsp, NULL);
2664 #else
2665 usleep(time);
2666 #endif
2667 dbgprintf("Sleep(%d) => 0\n", time);
2668 return 0;
2671 // why does IV32 codec want to call this? I don't know ...
2672 static int WINAPI expCreateCompatibleDC(int hdc)
2674 int dc = 0;//0x81;
2675 //dbgprintf("CreateCompatibleDC(%d) => 0x81\n", hdc);
2676 dbgprintf("CreateCompatibleDC(%d) => %d\n", hdc, dc);
2677 return dc;
2680 static int WINAPI expGetDeviceCaps(int hdc, int unk)
2682 dbgprintf("GetDeviceCaps(0x%x, %d) => 0\n", hdc, unk);
2683 #ifdef CONFIG_QTX_CODECS
2684 #define BITSPIXEL 12
2685 #define PLANES 14
2686 if (unk == BITSPIXEL)
2687 return 24;
2688 if (unk == PLANES)
2689 return 1;
2690 #endif
2691 return 1;
2694 static WIN_BOOL WINAPI expDeleteDC(int hdc)
2696 dbgprintf("DeleteDC(0x%x) => 0\n", hdc);
2697 if (hdc == 0x81)
2698 return 1;
2699 return 0;
2702 static WIN_BOOL WINAPI expDeleteObject(int hdc)
2704 dbgprintf("DeleteObject(0x%x) => 1\n", hdc);
2705 /* FIXME - implement code here */
2706 return 1;
2709 /* btvvc32.drv wants this one */
2710 static void* WINAPI expGetWindowDC(int hdc)
2712 dbgprintf("GetWindowDC(%d) => 0x0\n", hdc);
2713 return 0;
2716 #ifdef CONFIG_QTX_CODECS
2717 static int WINAPI expGetWindowRect(HWND win, RECT *r)
2719 dbgprintf("GetWindowRect(0x%x, 0x%x) => 1\n", win, r);
2720 /* (win == 0) => desktop */
2721 r->right = PSEUDO_SCREEN_WIDTH;
2722 r->left = 0;
2723 r->bottom = PSEUDO_SCREEN_HEIGHT;
2724 r->top = 0;
2725 return 1;
2728 static int WINAPI expMonitorFromWindow(HWND win, int flags)
2730 dbgprintf("MonitorFromWindow(0x%x, 0x%x) => 0\n", win, flags);
2731 return 0;
2734 static int WINAPI expMonitorFromRect(RECT *r, int flags)
2736 dbgprintf("MonitorFromRect(0x%x, 0x%x) => 0\n", r, flags);
2737 return 0;
2740 static int WINAPI expMonitorFromPoint(void *p, int flags)
2742 dbgprintf("MonitorFromPoint(0x%x, 0x%x) => 0\n", p, flags);
2743 return 0;
2746 static int WINAPI expEnumDisplayMonitors(void *dc, RECT *r,
2747 int WINAPI (*callback_proc)(HMONITOR, HDC, LPRECT, LPARAM), void *callback_param)
2749 dbgprintf("EnumDisplayMonitors(0x%x, 0x%x, 0x%x, 0x%x) => ?\n",
2750 dc, r, callback_proc, callback_param);
2751 return callback_proc(0, dc, r, callback_param);
2754 #if 0
2755 typedef struct tagMONITORINFO {
2756 DWORD cbSize;
2757 RECT rcMonitor;
2758 RECT rcWork;
2759 DWORD dwFlags;
2760 } MONITORINFO, *LPMONITORINFO;
2761 #endif
2763 #define CCHDEVICENAME 8
2764 typedef struct tagMONITORINFOEX {
2765 DWORD cbSize;
2766 RECT rcMonitor;
2767 RECT rcWork;
2768 DWORD dwFlags;
2769 TCHAR szDevice[CCHDEVICENAME];
2770 } MONITORINFOEX, *LPMONITORINFOEX;
2772 static int WINAPI expGetMonitorInfoA(void *mon, LPMONITORINFO lpmi)
2774 dbgprintf("GetMonitorInfoA(0x%x, 0x%x) => 1\n", mon, lpmi);
2776 lpmi->rcMonitor.right = lpmi->rcWork.right = PSEUDO_SCREEN_WIDTH;
2777 lpmi->rcMonitor.left = lpmi->rcWork.left = 0;
2778 lpmi->rcMonitor.bottom = lpmi->rcWork.bottom = PSEUDO_SCREEN_HEIGHT;
2779 lpmi->rcMonitor.top = lpmi->rcWork.top = 0;
2781 lpmi->dwFlags = 1; /* primary monitor */
2783 if (lpmi->cbSize == sizeof(MONITORINFOEX))
2785 LPMONITORINFOEX lpmiex = (LPMONITORINFOEX)lpmi;
2786 dbgprintf("MONITORINFOEX!\n");
2787 strncpy(lpmiex->szDevice, "Monitor1", CCHDEVICENAME);
2790 return 1;
2793 static int WINAPI expEnumDisplayDevicesA(const char *device, int devnum,
2794 void *dispdev, int flags)
2796 dbgprintf("EnumDisplayDevicesA(0x%x = %s, %d, 0x%x, %x) => 1\n",
2797 device, device, devnum, dispdev, flags);
2798 return 1;
2801 static int WINAPI expIsWindowVisible(HWND win)
2803 dbgprintf("IsWindowVisible(0x%x) => 1\n", win);
2804 return 1;
2807 static HWND WINAPI expGetActiveWindow(void)
2809 dbgprintf("GetActiveWindow() => 0\n");
2810 return (HWND)0;
2813 static int WINAPI expGetClassNameA(HWND win, LPTSTR classname, int maxcount)
2815 strncat(classname, "QuickTime", maxcount);
2816 dbgprintf("GetClassNameA(0x%x, 0x%x, %d) => %d\n",
2817 win, classname, maxcount, strlen(classname));
2818 return strlen(classname);
2821 #define LPWNDCLASS void *
2822 static int WINAPI expGetClassInfoA(HINSTANCE inst, LPCSTR classname, LPWNDCLASS wndclass)
2824 dbgprintf("GetClassInfoA(0x%x, 0x%x = %s, 0x%x) => 1\n", inst,
2825 classname, classname, wndclass);
2826 return 1;
2829 static int WINAPI expGetWindowLongA(HWND win, int index)
2831 dbgprintf("GetWindowLongA(0x%x, %d) => 0\n", win, index);
2832 return 1;
2835 static int WINAPI expGetObjectA(HGDIOBJ hobj, int objsize, LPVOID obj)
2837 dbgprintf("GetObjectA(0x%x, %d, 0x%x) => %d\n", hobj, objsize, obj, objsize);
2838 return objsize;
2841 static int WINAPI expCreateRectRgn(int x, int y, int width, int height)
2843 dbgprintf("CreateRectRgn(%d, %d, %d, %d) => 0\n", x, y, width, height);
2844 return 0;
2847 static int WINAPI expEnumWindows(int (*callback_func)(HWND, LPARAM), void *callback_param)
2849 int i, i2;
2850 dbgprintf("EnumWindows(0x%x, 0x%x) => 1\n", callback_func, callback_param);
2851 i = callback_func(0, callback_param);
2852 i2 = callback_func(1, callback_param);
2853 return i && i2;
2856 static int WINAPI expGetWindowThreadProcessId(HWND win, int *pid_data)
2858 int tid = pthread_self();
2859 dbgprintf("GetWindowThreadProcessId(0x%x, 0x%x) => %d\n",
2860 win, pid_data, tid);
2861 if (pid_data)
2862 *(int*)pid_data = tid;
2863 return tid;
2866 //HWND WINAPI CreateWindowExA(DWORD,LPCSTR,LPCSTR,DWORD,INT,INT,
2867 // INT,INT,HWND,HMENU,HINSTANCE,LPVOID);
2869 static HWND WINAPI expCreateWindowExA(int exstyle, const char *classname,
2870 const char *winname, int style, int x, int y, int w, int h,
2871 HWND parent, HMENU menu, HINSTANCE inst, LPVOID param)
2873 printf("CreateWindowEx() called\n");
2874 dbgprintf("CreateWindowEx(%d, 0x%x = %s, 0x%x = %s, %d, %d, %d, %d, %d, 0x%x, 0x%x, 0x%x, 0x%x) => 1\n",
2875 exstyle, classname, classname, winname, winname, style, x, y, w, h,
2876 parent, menu, inst, param);
2877 printf("CreateWindowEx() called okey\n");
2878 return 1;
2881 static int WINAPI expwaveOutGetNumDevs(void)
2883 dbgprintf("waveOutGetNumDevs() => 0\n");
2884 return 0;
2886 #endif
2889 * Returns the number of milliseconds, modulo 2^32, since the start
2890 * of the wineserver.
2892 static int WINAPI expGetTickCount(void)
2894 static int tcstart = 0;
2895 struct timeval t;
2896 int tc;
2897 gettimeofday( &t, NULL );
2898 tc = ((t.tv_sec * 1000) + (t.tv_usec / 1000)) - tcstart;
2899 if (tcstart == 0)
2901 tcstart = 0;
2902 tc = 0;
2904 dbgprintf("GetTickCount() => %d\n", tc);
2905 return tc;
2908 static int WINAPI expCreateFontA(void)
2910 dbgprintf("CreateFontA() => 0x0\n");
2911 return 1;
2914 /* tried to get pvmjpg work in a different way - no success */
2915 static int WINAPI expDrawTextA(int hDC, char* lpString, int nCount,
2916 LPRECT lpRect, unsigned int uFormat)
2918 dbgprintf("expDrawTextA(%p,...) => 8\n", hDC);
2919 return 8;
2922 static int WINAPI expGetPrivateProfileIntA(const char* appname,
2923 const char* keyname,
2924 int default_value,
2925 const char* filename)
2927 int size=255;
2928 char buffer[256];
2929 char* fullname;
2930 int result;
2932 buffer[255]=0;
2933 if(!(appname && keyname && filename) )
2935 dbgprintf("GetPrivateProfileIntA('%s', '%s', %d, '%s') => %d\n", appname, keyname, default_value, filename, default_value );
2936 return default_value;
2938 fullname=malloc(50+strlen(appname)+strlen(keyname)+strlen(filename));
2939 strcpy(fullname, "Software\\IniFileMapping\\");
2940 strcat(fullname, appname);
2941 strcat(fullname, "\\");
2942 strcat(fullname, keyname);
2943 strcat(fullname, "\\");
2944 strcat(fullname, filename);
2945 result=RegQueryValueExA(HKEY_LOCAL_MACHINE, fullname, NULL, NULL, (int*)buffer, &size);
2946 if((size>=0)&&(size<256))
2947 buffer[size]=0;
2948 // printf("GetPrivateProfileIntA(%s, %s, %s) -> %s\n", appname, keyname, filename, buffer);
2949 free(fullname);
2950 if(result)
2951 result=default_value;
2952 else
2953 result=atoi(buffer);
2954 dbgprintf("GetPrivateProfileIntA('%s', '%s', %d, '%s') => %d\n", appname, keyname, default_value, filename, result);
2955 return result;
2957 static int WINAPI expGetProfileIntA(const char* appname,
2958 const char* keyname,
2959 int default_value)
2961 dbgprintf("GetProfileIntA -> ");
2962 return expGetPrivateProfileIntA(appname, keyname, default_value, "default");
2965 static int WINAPI expGetPrivateProfileStringA(const char* appname,
2966 const char* keyname,
2967 const char* def_val,
2968 char* dest, unsigned int len,
2969 const char* filename)
2971 int result;
2972 int size;
2973 char* fullname;
2974 dbgprintf("GetPrivateProfileStringA('%s', '%s', def_val '%s', 0x%x, 0x%x, '%s')", appname, keyname, def_val, dest, len, filename );
2975 if(!(appname && keyname && filename) ) return 0;
2976 fullname=malloc(50+strlen(appname)+strlen(keyname)+strlen(filename));
2977 strcpy(fullname, "Software\\IniFileMapping\\");
2978 strcat(fullname, appname);
2979 strcat(fullname, "\\");
2980 strcat(fullname, keyname);
2981 strcat(fullname, "\\");
2982 strcat(fullname, filename);
2983 size=len;
2984 result=RegQueryValueExA(HKEY_LOCAL_MACHINE, fullname, NULL, NULL, (int*)dest, &size);
2985 free(fullname);
2986 if(result)
2988 strncpy(dest, def_val, size);
2989 if (strlen(def_val)< size) size = strlen(def_val);
2991 dbgprintf(" => %d ( '%s' )\n", size, dest);
2992 return size;
2994 static int WINAPI expWritePrivateProfileStringA(const char* appname,
2995 const char* keyname,
2996 const char* string,
2997 const char* filename)
2999 char* fullname;
3000 dbgprintf("WritePrivateProfileStringA('%s', '%s', '%s', '%s')", appname, keyname, string, filename );
3001 if(!(appname && keyname && filename) )
3003 dbgprintf(" => -1\n");
3004 return -1;
3006 fullname=malloc(50+strlen(appname)+strlen(keyname)+strlen(filename));
3007 strcpy(fullname, "Software\\IniFileMapping\\");
3008 strcat(fullname, appname);
3009 strcat(fullname, "\\");
3010 strcat(fullname, keyname);
3011 strcat(fullname, "\\");
3012 strcat(fullname, filename);
3013 RegSetValueExA(HKEY_LOCAL_MACHINE, fullname, 0, REG_SZ, (int*)string, strlen(string));
3014 // printf("RegSetValueExA(%s,%d)\n", string, strlen(string));
3015 // printf("WritePrivateProfileStringA(%s, %s, %s, %s)\n", appname, keyname, string, filename );
3016 free(fullname);
3017 dbgprintf(" => 0\n");
3018 return 0;
3021 unsigned int GetPrivateProfileIntA_(const char* appname, const char* keyname, INT default_value, const char* filename)
3023 return expGetPrivateProfileIntA(appname, keyname, default_value, filename);
3025 int GetPrivateProfileStringA_(const char* appname, const char* keyname,
3026 const char* def_val, char* dest, unsigned int len, const char* filename)
3028 return expGetPrivateProfileStringA(appname, keyname, def_val, dest, len, filename);
3030 int WritePrivateProfileStringA_(const char* appname, const char* keyname,
3031 const char* string, const char* filename)
3033 return expWritePrivateProfileStringA(appname, keyname, string, filename);
3038 static int WINAPI expDefDriverProc(int private, int id, int msg, int arg1, int arg2)
3040 dbgprintf("DefDriverProc(0x%x, 0x%x, 0x%x, 0x%x, 0x%x) => 0\n", private, id, msg, arg1, arg2);
3041 return 0;
3044 static int WINAPI expSizeofResource(int v1, int v2)
3046 int result=SizeofResource(v1, v2);
3047 dbgprintf("SizeofResource(0x%x, 0x%x) => %d\n", v1, v2, result);
3048 return result;
3051 static int WINAPI expGetLastError(void)
3053 int result=GetLastError();
3054 dbgprintf("GetLastError() => 0x%x\n", result);
3055 return result;
3058 static void WINAPI expSetLastError(int error)
3060 dbgprintf("SetLastError(0x%x)\n", error);
3061 SetLastError(error);
3064 static int WINAPI expStringFromGUID2(GUID* guid, char* str, int cbMax)
3066 int result=snprintf(str, cbMax, "%.8x-%.4x-%.4x-%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x",
3067 guid->f1, guid->f2, guid->f3,
3068 (unsigned char)guid->f4[0], (unsigned char)guid->f4[1],
3069 (unsigned char)guid->f4[2], (unsigned char)guid->f4[3],
3070 (unsigned char)guid->f4[4], (unsigned char)guid->f4[5],
3071 (unsigned char)guid->f4[6], (unsigned char)guid->f4[7]);
3072 dbgprintf("StringFromGUID2(0x%x, 0x%x='%s', %d) => %d\n", guid, str, str, cbMax, result);
3073 return result;
3077 static int WINAPI expGetFileVersionInfoSizeA(const char* name, int* lpHandle)
3079 dbgprintf("GetFileVersionInfoSizeA(0x%x='%s', 0x%X) => 0\n", name, name, lpHandle);
3080 return 0;
3083 static int WINAPI expIsBadStringPtrW(const short* string, int nchars)
3085 int result;
3086 if(string==0)result=1; else result=0;
3087 dbgprintf("IsBadStringPtrW(0x%x, %d) => %d", string, nchars, result);
3088 if(string)wch_print(string);
3089 return result;
3091 static int WINAPI expIsBadStringPtrA(const char* string, int nchars)
3093 return expIsBadStringPtrW((const short*)string, nchars);
3095 static long WINAPI expInterlockedExchangeAdd( long* dest, long incr )
3097 long ret;
3098 __asm__ volatile
3100 "lock; xaddl %0,(%1)"
3101 : "=r" (ret)
3102 : "r" (dest), "0" (incr)
3103 : "memory"
3105 return ret;
3108 static long WINAPI expInterlockedCompareExchange( unsigned long* dest, unsigned long exchange, unsigned long comperand)
3110 unsigned long retval = *dest;
3111 if(*dest == comperand)
3112 *dest = exchange;
3113 return retval;
3116 static long WINAPI expInterlockedIncrement( long* dest )
3118 long result=expInterlockedExchangeAdd( dest, 1 ) + 1;
3119 dbgprintf("InterlockedIncrement(0x%x => %d) => %d\n", dest, *dest, result);
3120 return result;
3122 static long WINAPI expInterlockedDecrement( long* dest )
3124 long result=expInterlockedExchangeAdd( dest, -1 ) - 1;
3125 dbgprintf("InterlockedDecrement(0x%x => %d) => %d\n", dest, *dest, result);
3126 return result;
3129 static void WINAPI expOutputDebugStringA( const char* string )
3131 dbgprintf("OutputDebugStringA(0x%x='%s')\n", string);
3132 fprintf(stderr, "DEBUG: %s\n", string);
3135 static int WINAPI expGetDC(int hwnd)
3137 dbgprintf("GetDC(0x%x) => 1\n", hwnd);
3138 return 1;
3141 static int WINAPI expReleaseDC(int hwnd, int hdc)
3143 dbgprintf("ReleaseDC(0x%x, 0x%x) => 1\n", hwnd, hdc);
3144 return 1;
3147 static int WINAPI expGetDesktopWindow(void)
3149 dbgprintf("GetDesktopWindow() => 0\n");
3150 return 0;
3153 static int cursor[100];
3155 static int WINAPI expLoadCursorA(int handle,LPCSTR name)
3157 dbgprintf("LoadCursorA(%d, 0x%x='%s') => 0x%x\n", handle, name, (int)&cursor[0]);
3158 return (int)&cursor[0];
3160 static int WINAPI expSetCursor(void *cursor)
3162 dbgprintf("SetCursor(0x%x) => 0x%x\n", cursor, cursor);
3163 return (int)cursor;
3165 static int WINAPI expGetCursorPos(void *cursor)
3167 dbgprintf("GetCursorPos(0x%x) => 0x%x\n", cursor, cursor);
3168 return 1;
3170 #ifdef CONFIG_QTX_CODECS
3171 static int show_cursor = 0;
3172 static int WINAPI expShowCursor(int show)
3174 dbgprintf("ShowCursor(%d) => %d\n", show, show);
3175 if (show)
3176 show_cursor++;
3177 else
3178 show_cursor--;
3179 return show_cursor;
3181 #endif
3182 static int WINAPI expRegisterWindowMessageA(char *message)
3184 dbgprintf("RegisterWindowMessageA(%s)\n", message);
3185 return 1;
3187 static int WINAPI expGetProcessVersion(int pid)
3189 dbgprintf("GetProcessVersion(%d)\n", pid);
3190 return 1;
3192 static int WINAPI expGetCurrentThread(void)
3194 #warning FIXME!
3195 dbgprintf("GetCurrentThread() => %x\n", 0xcfcf9898);
3196 return 0xcfcf9898;
3198 static int WINAPI expGetOEMCP(void)
3200 dbgprintf("GetOEMCP()\n");
3201 return 1;
3203 static int WINAPI expGetCPInfo(int cp,void *info)
3205 dbgprintf("GetCPInfo()\n");
3206 return 0;
3208 #ifdef CONFIG_QTX_CODECS
3209 #define SM_CXSCREEN 0
3210 #define SM_CYSCREEN 1
3211 #define SM_XVIRTUALSCREEN 76
3212 #define SM_YVIRTUALSCREEN 77
3213 #define SM_CXVIRTUALSCREEN 78
3214 #define SM_CYVIRTUALSCREEN 79
3215 #define SM_CMONITORS 80
3216 #endif
3217 static int WINAPI expGetSystemMetrics(int index)
3219 dbgprintf("GetSystemMetrics(%d)\n", index);
3220 #ifdef CONFIG_QTX_CODECS
3221 switch(index)
3223 case SM_XVIRTUALSCREEN:
3224 case SM_YVIRTUALSCREEN:
3225 return 0;
3226 case SM_CXSCREEN:
3227 case SM_CXVIRTUALSCREEN:
3228 return PSEUDO_SCREEN_WIDTH;
3229 case SM_CYSCREEN:
3230 case SM_CYVIRTUALSCREEN:
3231 return PSEUDO_SCREEN_HEIGHT;
3232 case SM_CMONITORS:
3233 return 1;
3235 #endif
3236 return 1;
3238 static int WINAPI expGetSysColor(int index)
3240 dbgprintf("GetSysColor(%d) => 1\n", index);
3241 return 1;
3243 static int WINAPI expGetSysColorBrush(int index)
3245 dbgprintf("GetSysColorBrush(%d)\n", index);
3246 return 1;
3251 static int WINAPI expGetSystemPaletteEntries(int hdc, int iStartIndex, int nEntries, void* lppe)
3253 dbgprintf("GetSystemPaletteEntries(0x%x, 0x%x, 0x%x, 0x%x) => 0\n",
3254 hdc, iStartIndex, nEntries, lppe);
3255 return 0;
3259 typedef struct TIME_ZONE_INFORMATION {
3260 long Bias;
3261 char StandardName[32];
3262 SYSTEMTIME StandardDate;
3263 long StandardBias;
3264 char DaylightName[32];
3265 SYSTEMTIME DaylightDate;
3266 long DaylightBias;
3267 } TIME_ZONE_INFORMATION, *LPTIME_ZONE_INFORMATION;
3270 static int WINAPI expGetTimeZoneInformation(LPTIME_ZONE_INFORMATION lpTimeZoneInformation)
3272 const short name[]={'C', 'e', 'n', 't', 'r', 'a', 'l', ' ', 'S', 't', 'a',
3273 'n', 'd', 'a', 'r', 'd', ' ', 'T', 'i', 'm', 'e', 0};
3274 const short pname[]={'C', 'e', 'n', 't', 'r', 'a', 'l', ' ', 'D', 'a', 'y',
3275 'l', 'i', 'g', 'h', 't', ' ', 'T', 'i', 'm', 'e', 0};
3276 dbgprintf("GetTimeZoneInformation(0x%x) => TIME_ZONE_ID_STANDARD\n");
3277 memset(lpTimeZoneInformation, 0, sizeof(TIME_ZONE_INFORMATION));
3278 lpTimeZoneInformation->Bias=360;//GMT-6
3279 memcpy(lpTimeZoneInformation->StandardName, name, sizeof(name));
3280 lpTimeZoneInformation->StandardDate.wMonth=10;
3281 lpTimeZoneInformation->StandardDate.wDay=5;
3282 lpTimeZoneInformation->StandardDate.wHour=2;
3283 lpTimeZoneInformation->StandardBias=0;
3284 memcpy(lpTimeZoneInformation->DaylightName, pname, sizeof(pname));
3285 lpTimeZoneInformation->DaylightDate.wMonth=4;
3286 lpTimeZoneInformation->DaylightDate.wDay=1;
3287 lpTimeZoneInformation->DaylightDate.wHour=2;
3288 lpTimeZoneInformation->DaylightBias=-60;
3289 return TIME_ZONE_ID_STANDARD;
3292 static void WINAPI expGetLocalTime(SYSTEMTIME* systime)
3294 time_t local_time;
3295 struct tm *local_tm;
3296 struct timeval tv;
3298 dbgprintf("GetLocalTime(0x%x)\n");
3299 gettimeofday(&tv, NULL);
3300 local_time=tv.tv_sec;
3301 local_tm=localtime(&local_time);
3303 systime->wYear = local_tm->tm_year + 1900;
3304 systime->wMonth = local_tm->tm_mon + 1;
3305 systime->wDayOfWeek = local_tm->tm_wday;
3306 systime->wDay = local_tm->tm_mday;
3307 systime->wHour = local_tm->tm_hour;
3308 systime->wMinute = local_tm->tm_min;
3309 systime->wSecond = local_tm->tm_sec;
3310 systime->wMilliseconds = (tv.tv_usec / 1000) % 1000;
3311 dbgprintf(" Year: %d\n Month: %d\n Day of week: %d\n"
3312 " Day: %d\n Hour: %d\n Minute: %d\n Second: %d\n"
3313 " Milliseconds: %d\n",
3314 systime->wYear, systime->wMonth, systime->wDayOfWeek, systime->wDay,
3315 systime->wHour, systime->wMinute, systime->wSecond, systime->wMilliseconds);
3318 static int WINAPI expGetSystemTime(SYSTEMTIME* systime)
3320 time_t local_time;
3321 struct tm *local_tm;
3322 struct timeval tv;
3324 dbgprintf("GetSystemTime(0x%x)\n", systime);
3325 gettimeofday(&tv, NULL);
3326 local_time=tv.tv_sec;
3327 local_tm=gmtime(&local_time);
3329 systime->wYear = local_tm->tm_year + 1900;
3330 systime->wMonth = local_tm->tm_mon + 1;
3331 systime->wDayOfWeek = local_tm->tm_wday;
3332 systime->wDay = local_tm->tm_mday;
3333 systime->wHour = local_tm->tm_hour;
3334 systime->wMinute = local_tm->tm_min;
3335 systime->wSecond = local_tm->tm_sec;
3336 systime->wMilliseconds = (tv.tv_usec / 1000) % 1000;
3337 dbgprintf(" Year: %d\n Month: %d\n Day of week: %d\n"
3338 " Day: %d\n Hour: %d\n Minute: %d\n Second: %d\n"
3339 " Milliseconds: %d\n",
3340 systime->wYear, systime->wMonth, systime->wDayOfWeek, systime->wDay,
3341 systime->wHour, systime->wMinute, systime->wSecond, systime->wMilliseconds);
3342 return 0;
3345 #define SECS_1601_TO_1970 ((369 * 365 + 89) * 86400ULL)
3346 static void WINAPI expGetSystemTimeAsFileTime(FILETIME* systime)
3348 struct timeval tv;
3349 unsigned long long secs;
3351 dbgprintf("GetSystemTime(0x%x)\n", systime);
3352 gettimeofday(&tv, NULL);
3353 secs = (tv.tv_sec + SECS_1601_TO_1970) * 10000000;
3354 secs += tv.tv_usec * 10;
3355 systime->dwLowDateTime = secs & 0xffffffff;
3356 systime->dwHighDateTime = (secs >> 32);
3359 static int WINAPI expGetEnvironmentVariableA(const char* name, char* field, int size)
3361 //char *p;
3362 // printf("%s %x %x\n", name, field, size);
3363 if(field)field[0]=0;
3365 p = getenv(name);
3366 if (p) strncpy(field,p,size);
3368 if (strcmp(name,"__MSVCRT_HEAP_SELECT")==0)
3369 strcpy(field,"__GLOBAL_HEAP_SELECTED,1");
3370 dbgprintf("GetEnvironmentVariableA(0x%x='%s', 0x%x, %d) => %d\n", name, name, field, size, strlen(field));
3371 return strlen(field);
3374 static int WINAPI expSetEnvironmentVariableA(const char *name, const char *value)
3376 dbgprintf("SetEnvironmentVariableA(%s, %s)\n", name, value);
3377 return 0;
3380 static void* WINAPI expCoTaskMemAlloc(ULONG cb)
3382 return my_mreq(cb, 0);
3384 static void WINAPI expCoTaskMemFree(void* cb)
3386 my_release(cb);
3392 void* CoTaskMemAlloc(unsigned long cb)
3394 return expCoTaskMemAlloc(cb);
3396 void CoTaskMemFree(void* cb)
3398 expCoTaskMemFree(cb);
3401 struct COM_OBJECT_INFO
3403 GUID clsid;
3404 long (*GetClassObject) (GUID* clsid, const GUID* iid, void** ppv);
3407 static struct COM_OBJECT_INFO* com_object_table=0;
3408 static int com_object_size=0;
3409 int RegisterComClass(const GUID* clsid, GETCLASSOBJECT gcs)
3411 if(!clsid || !gcs)
3412 return -1;
3413 com_object_table=realloc(com_object_table, sizeof(struct COM_OBJECT_INFO)*(++com_object_size));
3414 com_object_table[com_object_size-1].clsid=*clsid;
3415 com_object_table[com_object_size-1].GetClassObject=gcs;
3416 return 0;
3419 int UnregisterComClass(const GUID* clsid, GETCLASSOBJECT gcs)
3421 int found = 0;
3422 int i = 0;
3423 if(!clsid || !gcs)
3424 return -1;
3426 if (com_object_table == 0)
3427 printf("Warning: UnregisterComClass() called without any registered class\n");
3428 while (i < com_object_size)
3430 if (found && i > 0)
3432 memcpy(&com_object_table[i - 1].clsid,
3433 &com_object_table[i].clsid, sizeof(GUID));
3434 com_object_table[i - 1].GetClassObject =
3435 com_object_table[i].GetClassObject;
3437 else if (memcmp(&com_object_table[i].clsid, clsid, sizeof(GUID)) == 0
3438 && com_object_table[i].GetClassObject == gcs)
3440 found++;
3442 i++;
3444 if (found)
3446 if (--com_object_size == 0)
3448 free(com_object_table);
3449 com_object_table = 0;
3452 return 0;
3456 const GUID IID_IUnknown =
3458 0x00000000, 0x0000, 0x0000,
3459 {0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}
3461 const GUID IID_IClassFactory =
3463 0x00000001, 0x0000, 0x0000,
3464 {0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}
3467 static long WINAPI expCoCreateInstance(GUID* rclsid, struct IUnknown* pUnkOuter,
3468 long dwClsContext, const GUID* riid, void** ppv)
3470 int i;
3471 struct COM_OBJECT_INFO* ci=0;
3472 for(i=0; i<com_object_size; i++)
3473 if(!memcmp(rclsid, &com_object_table[i].clsid, sizeof(GUID)))
3474 ci=&com_object_table[i];
3475 if(!ci)return REGDB_E_CLASSNOTREG;
3476 // in 'real' world we should mess with IClassFactory here
3477 i=ci->GetClassObject(rclsid, riid, ppv);
3478 return i;
3481 long CoCreateInstance(GUID* rclsid, struct IUnknown* pUnkOuter,
3482 long dwClsContext, const GUID* riid, void** ppv)
3484 return expCoCreateInstance(rclsid, pUnkOuter, dwClsContext, riid, ppv);
3487 static int WINAPI expIsRectEmpty(CONST RECT *lprc)
3489 int r = 0;
3490 int w,h;
3491 //trapbug();
3492 if (lprc)
3494 w = lprc->right - lprc->left;
3495 h = lprc->bottom - lprc->top;
3496 if (w <= 0 || h <= 0)
3497 r = 1;
3499 else
3500 r = 1;
3502 dbgprintf("IsRectEmpty(%p) => %s\n", lprc, (r) ? "TRUE" : "FALSE");
3503 //printf("Rect: left: %d, top: %d, right: %d, bottom: %d\n", lprc->left, lprc->top, lprc->right, lprc->bottom);
3504 // return 0; // wmv9?
3505 return r; // TM20
3508 static int _adjust_fdiv=0; //what's this? - used to adjust division
3509 static int _winver = 0x510; // windows version
3514 static unsigned int WINAPI expGetTempPathA(unsigned int len, char* path)
3516 dbgprintf("GetTempPathA(%d, 0x%x)", len, path);
3517 if(len<5)
3519 dbgprintf(" => 0\n");
3520 return 0;
3522 strcpy(path, "/tmp");
3523 dbgprintf(" => 5 ( '/tmp' )\n");
3524 return 5;
3527 FYI:
3528 typedef struct
3530 DWORD dwFileAttributes;
3531 FILETIME ftCreationTime;
3532 FILETIME ftLastAccessTime;
3533 FILETIME ftLastWriteTime;
3534 DWORD nFileSizeHigh;
3535 DWORD nFileSizeLow;
3536 DWORD dwReserved0;
3537 DWORD dwReserved1;
3538 CHAR cFileName[260];
3539 CHAR cAlternateFileName[14];
3540 } WIN32_FIND_DATAA, *LPWIN32_FIND_DATAA;
3543 static DIR* qtx_dir=NULL;
3545 static WIN_BOOL WINAPI expFindNextFileA(HANDLE h,LPWIN32_FIND_DATAA lpfd)
3547 #ifdef CONFIG_QTX_CODECS
3548 dbgprintf("FindNextFileA(0x%x, 0x%x) => 0\n", h, lpfd);
3549 if(h==FILE_HANDLE_quicktimeqtx){
3550 struct dirent* d;
3551 if(!qtx_dir) return 0;
3552 while((d=readdir(qtx_dir))){
3553 char* x=strrchr(d->d_name,'.');
3554 if(!x) continue;
3555 if(strcmp(x,".qtx")) continue;
3556 strcpy(lpfd->cFileName,d->d_name);
3557 // sprintf(lpfd->cAlternateFileName,"%-8s.qtx",d->d_name);
3558 strcpy(lpfd->cAlternateFileName,"foobar.qtx");
3559 dbgprintf("### FindNext: %s\n",lpfd->cFileName);
3560 return 1;
3562 closedir(qtx_dir); qtx_dir=NULL;
3563 return 0;
3565 #endif
3566 return 0;
3569 static HANDLE WINAPI expFindFirstFileA(LPCSTR s, LPWIN32_FIND_DATAA lpfd)
3571 dbgprintf("FindFirstFileA(0x%x='%s', 0x%x) => 0\n", s, s, lpfd);
3572 // printf("\n### FindFirstFileA('%s')...\n",s);
3573 #ifdef CONFIG_QTX_CODECS
3574 if(strstr(s, "quicktime\\*.QTX")){
3575 dbgprintf("FindFirstFileA(0x%x='%s', 0x%x) => QTX\n", s, s, lpfd);
3576 dbgprintf("\n### Searching for QuickTime plugins (*.qtx) at %s...\n",
3577 codec_path);
3578 qtx_dir = opendir(codec_path);
3579 if(!qtx_dir) return (HANDLE)-1;
3580 memset(lpfd,0,sizeof(*lpfd));
3581 if(expFindNextFileA(FILE_HANDLE_quicktimeqtx,lpfd))
3582 return FILE_HANDLE_quicktimeqtx;
3583 printf("loader: Couldn't find the QuickTime plugins (.qtx files) at %s\n",
3584 codec_path);
3585 return (HANDLE)-1;
3587 #if 0
3588 if(strstr(s, "QuickTime.qts")){
3589 dbgprintf("FindFirstFileA(0x%x='%s', 0x%x) => QTS\n", s, s, lpfd);
3590 // if(!strcmp(s,"C:\\windows\\QuickTime.qts\\QuickTime.qts\\*.QTX"))
3591 // return (HANDLE)-1;
3592 strcpy(lpfd->cFileName, "QuickTime.qts");
3593 strcpy(lpfd->cAlternateFileName, "QuickT~1.qts");
3594 return FILE_HANDLE_quicktimeqts;
3596 #endif
3597 #endif
3598 if(strstr(s, "*.vwp")){
3599 // hack for VoxWare codec plugins:
3600 strcpy(lpfd->cFileName, "msms001.vwp");
3601 strcpy(lpfd->cAlternateFileName, "msms001.vwp");
3602 return (HANDLE)0;
3604 // return 'file not found'
3605 return (HANDLE)-1;
3608 static WIN_BOOL WINAPI expFindClose(HANDLE h)
3610 dbgprintf("FindClose(0x%x) => 0\n", h);
3611 #ifdef CONFIG_QTX_CODECS
3612 // if(h==FILE_HANDLE_quicktimeqtx && qtx_dir){
3613 // closedir(qtx_dir);
3614 // qtx_dir=NULL;
3615 // }
3616 #endif
3617 return 0;
3619 static UINT WINAPI expSetErrorMode(UINT i)
3621 dbgprintf("SetErrorMode(%d) => 0\n", i);
3622 return 0;
3624 static UINT WINAPI expGetWindowsDirectoryA(LPSTR s,UINT c)
3626 char windir[]="c:\\windows";
3627 int result;
3628 strncpy(s, windir, c);
3629 result=1+((c<strlen(windir))?c:strlen(windir));
3630 dbgprintf("GetWindowsDirectoryA(0x%x, %d) => %d\n", s, c, result);
3631 return result;
3633 #ifdef CONFIG_QTX_CODECS
3634 static UINT WINAPI expGetCurrentDirectoryA(UINT c, LPSTR s)
3636 char curdir[]="c:\\";
3637 int result;
3638 strncpy(s, curdir, c);
3639 result=1+((c<strlen(curdir))?c:strlen(curdir));
3640 dbgprintf("GetCurrentDirectoryA(0x%x, %d) => %d\n", s, c, result);
3641 return result;
3644 static int WINAPI expSetCurrentDirectoryA(const char *pathname)
3646 dbgprintf("SetCurrentDirectoryA(0x%x = %s) => 1\n", pathname, pathname);
3647 #if 0
3648 if (strrchr(pathname, '\\'))
3649 chdir(strcat(strrchr(pathname, '\\')+1, '/'));
3650 else
3651 chdir(pathname);
3652 #endif
3653 return 1;
3656 static int WINAPI expCreateDirectoryA(const char *pathname, void *sa)
3658 dbgprintf("CreateDirectory(0x%x = %s, 0x%x) => 1\n",
3659 pathname, pathname, sa);
3660 #if 0
3661 p = strrchr(pathname, '\\')+1;
3662 strcpy(&buf[0], p); /* should be strncpy */
3663 if (!strlen(p))
3665 buf[0] = '.';
3666 buf[1] = 0;
3668 #if 0
3669 if (strrchr(pathname, '\\'))
3670 mkdir(strcat(strrchr(pathname, '\\')+1, '/'), 666);
3671 else
3672 mkdir(pathname, 666);
3673 #endif
3674 mkdir(&buf);
3675 #endif
3676 return 1;
3678 #endif
3679 static WIN_BOOL WINAPI expDeleteFileA(LPCSTR s)
3681 dbgprintf("DeleteFileA(0x%x='%s') => 0\n", s, s);
3682 return 0;
3684 static WIN_BOOL WINAPI expFileTimeToLocalFileTime(const FILETIME* cpf, LPFILETIME pf)
3686 dbgprintf("FileTimeToLocalFileTime(0x%x, 0x%x) => 0\n", cpf, pf);
3687 return 0;
3690 static UINT WINAPI expGetTempFileNameA(LPCSTR cs1,LPCSTR cs2,UINT i,LPSTR ps)
3692 char mask[16]="/tmp/AP_XXXXXX";
3693 int result;
3694 dbgprintf("GetTempFileNameA(0x%x='%s', 0x%x='%s', %d, 0x%x)", cs1, cs1, cs2, cs2, i, ps);
3695 if(i && i<10)
3697 dbgprintf(" => -1\n");
3698 return -1;
3700 result=mkstemp(mask);
3701 sprintf(ps, "AP%d", result);
3702 dbgprintf(" => %d\n", strlen(ps));
3703 return strlen(ps);
3706 // This func might need proper implementation if we want AngelPotion codec.
3707 // They try to open APmpeg4v1.apl with it.
3708 // DLL will close opened file with CloseHandle().
3710 static HANDLE WINAPI expCreateFileA(LPCSTR cs1,DWORD i1,DWORD i2,
3711 LPSECURITY_ATTRIBUTES p1, DWORD i3,DWORD i4,HANDLE i5)
3713 dbgprintf("CreateFileA(0x%x='%s', %d, %d, 0x%x, %d, %d, 0x%x)\n", cs1, cs1, i1,
3714 i2, p1, i3, i4, i5);
3715 if((!cs1) || (strlen(cs1)<2))return -1;
3717 #ifdef CONFIG_QTX_CODECS
3718 if(strstr(cs1, "QuickTime.qts"))
3720 int result;
3721 char* tmp = malloc(strlen(codec_path) + 50);
3722 strcpy(tmp, codec_path);
3723 strcat(tmp, "/");
3724 strcat(tmp, "QuickTime.qts");
3725 result=open(tmp, O_RDONLY);
3726 free(tmp);
3727 return result;
3729 if(strstr(cs1, ".qtx"))
3731 int result;
3732 char* tmp = malloc(strlen(codec_path) + 250);
3733 char* x=strrchr(cs1,'\\');
3734 sprintf(tmp, "%s/%s", codec_path, x ? (x + 1) : cs1);
3735 // printf("### Open: %s -> %s\n",cs1,tmp);
3736 result=open(tmp, O_RDONLY);
3737 free(tmp);
3738 return result;
3740 #endif
3742 if(strncmp(cs1, "AP", 2) == 0)
3744 int result;
3745 char* tmp = malloc(strlen(codec_path) + 50);
3746 strcpy(tmp, codec_path);
3747 strcat(tmp, "/");
3748 strcat(tmp, "APmpg4v1.apl");
3749 result=open(tmp, O_RDONLY);
3750 free(tmp);
3751 return result;
3753 if (strstr(cs1, "vp3") || strstr(cs1, ".fpf") || strstr(cs1, ".col"))
3755 int r;
3756 int flg = 0;
3757 char* tmp=malloc(20 + strlen(cs1));
3758 strcpy(tmp, "/tmp/");
3759 strcat(tmp, cs1);
3760 r = 4;
3761 while (tmp[r])
3763 if (tmp[r] == ':' || tmp[r] == '\\')
3764 tmp[r] = '_';
3765 r++;
3767 if (GENERIC_READ & i1)
3768 flg |= O_RDONLY;
3769 else if (GENERIC_WRITE & i1)
3771 flg |= O_WRONLY | O_CREAT;
3772 printf("Warning: openning filename %s %d (flags; 0x%x) for write\n", tmp, r, flg);
3774 r=open(tmp, flg, S_IRWXU);
3775 free(tmp);
3776 return r;
3779 // Needed by wnvplay1.dll
3780 if (strstr(cs1, "WINNOV.bmp"))
3782 int r;
3783 r=open("/dev/null", O_RDONLY);
3784 return r;
3787 #if 0
3788 /* we need this for some virtualdub filters */
3790 int r;
3791 int flg = 0;
3792 if (GENERIC_READ & i1)
3793 flg |= O_RDONLY;
3794 else if (GENERIC_WRITE & i1)
3796 flg |= O_WRONLY;
3797 printf("Warning: openning filename %s %d (flags; 0x%x) for write\n", cs1, r, flg);
3799 r=open(cs1, flg);
3800 return r;
3802 #endif
3804 return atoi(cs1+2);
3806 static UINT WINAPI expGetSystemDirectoryA(
3807 char* lpBuffer, // address of buffer for system directory
3808 UINT uSize // size of directory buffer
3810 dbgprintf("GetSystemDirectoryA(%p,%d)\n", lpBuffer,uSize);
3811 if(!lpBuffer) strcpy(lpBuffer,".");
3812 return 1;
3815 static char sysdir[]=".";
3816 static LPCSTR WINAPI expGetSystemDirectoryA(void)
3818 dbgprintf("GetSystemDirectoryA() => 0x%x='%s'\n", sysdir, sysdir);
3819 return sysdir;
3822 static DWORD WINAPI expGetFullPathNameA
3824 LPCTSTR lpFileName,
3825 DWORD nBufferLength,
3826 LPTSTR lpBuffer,
3827 LPTSTR lpFilePart
3829 if(!lpFileName) return 0;
3830 dbgprintf("GetFullPathNameA('%s',%d,%p,%p)\n",lpFileName,nBufferLength,
3831 lpBuffer, lpFilePart);
3832 #if 0
3833 #ifdef CONFIG_QTX_CODECS
3834 strcpy(lpFilePart, "Quick123.qts");
3835 #else
3836 strcpy(lpFilePart, lpFileName);
3837 #endif
3838 #else
3839 if (strrchr(lpFileName, '\\'))
3840 lpFilePart = strrchr(lpFileName, '\\');
3841 else
3842 lpFilePart = (LPTSTR)lpFileName;
3843 #endif
3844 strcpy(lpBuffer, lpFileName);
3845 // strncpy(lpBuffer, lpFileName, rindex(lpFileName, '\\')-lpFileName);
3846 return strlen(lpBuffer);
3849 static DWORD WINAPI expGetShortPathNameA
3851 LPCSTR longpath,
3852 LPSTR shortpath,
3853 DWORD shortlen
3855 if(!longpath) return 0;
3856 dbgprintf("GetShortPathNameA('%s',%p,%d)\n",longpath,shortpath,shortlen);
3857 strcpy(shortpath,longpath);
3858 return strlen(shortpath);
3861 static WIN_BOOL WINAPI expReadFile(HANDLE h,LPVOID pv,DWORD size,LPDWORD rd,LPOVERLAPPED unused)
3863 int result;
3864 dbgprintf("ReadFile(%d, 0x%x, %d -> 0x%x)\n", h, pv, size, rd);
3865 result=read(h, pv, size);
3866 if(rd)*rd=result;
3867 if(!result)return 0;
3868 return 1;
3871 static WIN_BOOL WINAPI expWriteFile(HANDLE h,LPCVOID pv,DWORD size,LPDWORD wr,LPOVERLAPPED unused)
3873 int result;
3874 dbgprintf("WriteFile(%d, 0x%x, %d -> 0x%x)\n", h, pv, size, wr);
3875 if(h==1234)h=1;
3876 result=write(h, pv, size);
3877 if(wr)*wr=result;
3878 if(!result)return 0;
3879 return 1;
3881 static DWORD WINAPI expSetFilePointer(HANDLE h, LONG val, LPLONG ext, DWORD whence)
3883 int wh;
3884 dbgprintf("SetFilePointer(%d, 0x%x, 0x%x = %d, %d)\n", h, val, ext, ext ? *ext : 0, whence);
3885 //why would DLL want temporary file with >2Gb size?
3886 switch(whence)
3888 case FILE_BEGIN:
3889 wh=SEEK_SET;break;
3890 case FILE_END:
3891 wh=SEEK_END;break;
3892 case FILE_CURRENT:
3893 wh=SEEK_CUR;break;
3894 default:
3895 return -1;
3897 #ifdef CONFIG_QTX_CODECS
3898 if (val == 0 && ext != 0)
3899 val = val&(*ext);
3900 #endif
3901 return lseek(h, val, wh);
3904 static HDRVR WINAPI expOpenDriverA(LPCSTR szDriverName, LPCSTR szSectionName,
3905 LPARAM lParam2)
3907 dbgprintf("OpenDriverA(0x%x='%s', 0x%x='%s', 0x%x) => -1\n", szDriverName, szDriverName, szSectionName, szSectionName, lParam2);
3908 return -1;
3910 static HDRVR WINAPI expOpenDriver(LPCSTR szDriverName, LPCSTR szSectionName,
3911 LPARAM lParam2)
3913 dbgprintf("OpenDriver(0x%x='%s', 0x%x='%s', 0x%x) => -1\n", szDriverName, szDriverName, szSectionName, szSectionName, lParam2);
3914 return -1;
3918 static WIN_BOOL WINAPI expGetProcessAffinityMask(HANDLE hProcess,
3919 LPDWORD lpProcessAffinityMask,
3920 LPDWORD lpSystemAffinityMask)
3922 dbgprintf("GetProcessAffinityMask(0x%x, 0x%x, 0x%x) => 1\n",
3923 hProcess, lpProcessAffinityMask, lpSystemAffinityMask);
3924 if(lpProcessAffinityMask)*lpProcessAffinityMask=1;
3925 if(lpSystemAffinityMask)*lpSystemAffinityMask=1;
3926 return 1;
3929 // Fake implementation: does nothing, but does it right :)
3930 static WIN_BOOL WINAPI expSetProcessAffinityMask(HANDLE hProcess,
3931 LPDWORD dwProcessAffinityMask)
3933 dbgprintf("SetProcessAffinityMask(0x%x, 0x%x) => 1\n",
3934 hProcess, dwProcessAffinityMask);
3936 return 1;
3939 static int WINAPI expMulDiv(int nNumber, int nNumerator, int nDenominator)
3941 static const long long max_int=0x7FFFFFFFLL;
3942 static const long long min_int=-0x80000000LL;
3943 long long tmp=(long long)nNumber*(long long)nNumerator;
3944 dbgprintf("expMulDiv %d * %d / %d\n", nNumber, nNumerator, nDenominator);
3945 if(!nDenominator)return 1;
3946 tmp/=nDenominator;
3947 if(tmp<min_int) return 1;
3948 if(tmp>max_int) return 1;
3949 return (int)tmp;
3952 static LONG WINAPI explstrcmpiA(const char* str1, const char* str2)
3954 LONG result=strcasecmp(str1, str2);
3955 dbgprintf("strcmpi(0x%x='%s', 0x%x='%s') => %d\n", str1, str1, str2, str2, result);
3956 return result;
3959 static LONG WINAPI explstrlenA(const char* str1)
3961 LONG result=strlen(str1);
3962 dbgprintf("strlen(0x%x='%.50s') => %d\n", str1, str1, result);
3963 return result;
3966 static LONG WINAPI explstrcpyA(char* str1, const char* str2)
3968 int result= (int) strcpy(str1, str2);
3969 dbgprintf("strcpy(0x%.50x, 0x%.50x='%.50s') => %d\n", str1, str2, str2, result);
3970 return result;
3972 static LONG WINAPI explstrcpynA(char* str1, const char* str2,int len)
3974 int result;
3975 if (strlen(str2)>len)
3976 result = (int) strncpy(str1, str2,len);
3977 else
3978 result = (int) strcpy(str1,str2);
3979 dbgprintf("strncpy(0x%x, 0x%x='%s' len %d strlen %d) => %x\n", str1, str2, str2,len, strlen(str2),result);
3980 return result;
3982 static LONG WINAPI explstrcatA(char* str1, const char* str2)
3984 int result= (int) strcat(str1, str2);
3985 dbgprintf("strcat(0x%x, 0x%x='%s') => %d\n", str1, str2, str2, result);
3986 return result;
3990 static LONG WINAPI expInterlockedExchange(long *dest, long l)
3992 long retval = *dest;
3993 *dest = l;
3994 return retval;
3997 static void WINAPI expInitCommonControls(void)
3999 dbgprintf("InitCommonControls called!\n");
4000 return;
4003 #ifdef CONFIG_QTX_CODECS
4004 /* needed by QuickTime.qts */
4005 static HWND WINAPI expCreateUpDownControl (DWORD style, INT x, INT y, INT cx, INT cy,
4006 HWND parent, INT id, HINSTANCE inst,
4007 HWND buddy, INT maxVal, INT minVal, INT curVal)
4009 dbgprintf("CreateUpDownControl(...)\n");
4010 return 0;
4012 #endif
4014 /* alex: implement this call! needed for 3ivx */
4015 static HRESULT WINAPI expCoCreateFreeThreadedMarshaler(void *pUnkOuter, void **ppUnkInner)
4017 dbgprintf("CoCreateFreeThreadedMarshaler(%p, %p) called!\n",
4018 pUnkOuter, ppUnkInner);
4019 // return 0;
4020 return ERROR_CALL_NOT_IMPLEMENTED;
4024 static int WINAPI expDuplicateHandle(HANDLE hSourceProcessHandle, // handle to source process
4025 HANDLE hSourceHandle, // handle to duplicate
4026 HANDLE hTargetProcessHandle, // handle to target process
4027 HANDLE* lpTargetHandle, // duplicate handle
4028 DWORD dwDesiredAccess, // requested access
4029 int bInheritHandle, // handle inheritance option
4030 DWORD dwOptions // optional actions
4033 dbgprintf("DuplicateHandle(%p, %p, %p, %p, 0x%x, %d, %d) called\n",
4034 hSourceProcessHandle, hSourceHandle, hTargetProcessHandle,
4035 lpTargetHandle, dwDesiredAccess, bInheritHandle, dwOptions);
4036 *lpTargetHandle = hSourceHandle;
4037 return 1;
4040 static HRESULT WINAPI expCoInitializeEx(LPVOID lpReserved, DWORD dwCoInit)
4042 dbgprintf("CoInitializeEx(%p, %d) called\n", lpReserved, dwCoInit);
4043 return S_OK;
4046 // required by PIM1 codec (used by win98 PCTV Studio capture sw)
4047 static HRESULT WINAPI expCoInitialize(
4048 LPVOID lpReserved /* [in] pointer to win32 malloc interface
4049 (obsolete, should be NULL) */
4053 * Just delegate to the newer method.
4055 return expCoInitializeEx(lpReserved, COINIT_APARTMENTTHREADED);
4058 static void WINAPI expCoUninitialize(void)
4060 dbgprintf("CoUninitialize() called\n");
4063 /* allow static linking */
4064 HRESULT WINAPI CoInitializeEx(LPVOID lpReserved, DWORD dwCoInit)
4066 return expCoInitializeEx(lpReserved, dwCoInit);
4068 HRESULT WINAPI CoInitialize(LPVOID lpReserved)
4070 return expCoInitialize(lpReserved);
4072 void WINAPI CoUninitialize(void)
4074 expCoUninitialize();
4077 static DWORD WINAPI expSetThreadAffinityMask
4079 HANDLE hThread,
4080 DWORD dwThreadAffinityMask
4082 return 0;
4086 * no WINAPI functions - CDECL
4088 static void* expmalloc(int size)
4090 //printf("malloc");
4091 // return malloc(size);
4092 void* result=my_mreq(size,0);
4093 dbgprintf("malloc(0x%x) => 0x%x\n", size,result);
4094 if(result==0)
4095 printf("WARNING: malloc() failed\n");
4096 return result;
4098 static void expfree(void* mem)
4100 // return free(mem);
4101 dbgprintf("free(%p)\n", mem);
4102 my_release(mem);
4104 /* needed by atrac3.acm */
4105 static void *expcalloc(int num, int size)
4107 void* result=my_mreq(num*size,1);
4108 dbgprintf("calloc(%d,%d) => %p\n", num,size,result);
4109 if(result==0)
4110 printf("WARNING: calloc() failed\n");
4111 return result;
4113 static void* expnew(int size)
4115 // printf("NEW:: Call from address %08x\n STACK DUMP:\n", *(-1+(int*)&size));
4116 // printf("%08x %08x %08x %08x\n",
4117 // size, *(1+(int*)&size),
4118 // *(2+(int*)&size),*(3+(int*)&size));
4119 void* result;
4120 assert(size >= 0);
4122 result=my_mreq(size,0);
4123 dbgprintf("new(%d) => %p\n", size, result);
4124 if (result==0)
4125 printf("WARNING: new() failed\n");
4126 return result;
4129 static int expdelete(void* memory)
4131 dbgprintf("delete(%p)\n", memory);
4132 my_release(memory);
4133 return 0;
4137 * local definition - we need only the last two members at this point
4138 * otherwice we would have to introduce here GUIDs and some more types..
4140 typedef struct __attribute__((__packed__))
4142 char hay[0x40];
4143 unsigned long cbFormat; //0x40
4144 char* pbFormat; //0x44
4145 } MY_MEDIA_TYPE;
4146 static HRESULT WINAPI expMoCopyMediaType(MY_MEDIA_TYPE* dest, const MY_MEDIA_TYPE* src)
4148 if (!dest || !src)
4149 return E_POINTER;
4150 memcpy(dest, src, sizeof(MY_MEDIA_TYPE));
4151 if (dest->cbFormat)
4153 dest->pbFormat = (char*) my_mreq(dest->cbFormat, 0);
4154 if (!dest->pbFormat)
4155 return E_OUTOFMEMORY;
4156 memcpy(dest->pbFormat, src->pbFormat, dest->cbFormat);
4158 return S_OK;
4160 static HRESULT WINAPI expMoInitMediaType(MY_MEDIA_TYPE* dest, DWORD cbFormat)
4162 if (!dest)
4163 return E_POINTER;
4164 memset(dest, 0, sizeof(MY_MEDIA_TYPE));
4165 if (cbFormat)
4167 dest->pbFormat = (char*) my_mreq(cbFormat, 0);
4168 if (!dest->pbFormat)
4169 return E_OUTOFMEMORY;
4171 return S_OK;
4173 static HRESULT WINAPI expMoCreateMediaType(MY_MEDIA_TYPE** dest, DWORD cbFormat)
4175 if (!dest)
4176 return E_POINTER;
4177 *dest = my_mreq(sizeof(MY_MEDIA_TYPE), 0);
4178 return expMoInitMediaType(*dest, cbFormat);
4180 static HRESULT WINAPI expMoDuplicateMediaType(MY_MEDIA_TYPE** dest, const void* src)
4182 if (!dest)
4183 return E_POINTER;
4184 *dest = my_mreq(sizeof(MY_MEDIA_TYPE), 0);
4185 return expMoCopyMediaType(*dest, src);
4187 static HRESULT WINAPI expMoFreeMediaType(MY_MEDIA_TYPE* dest)
4189 if (!dest)
4190 return E_POINTER;
4191 if (dest->pbFormat)
4193 my_release(dest->pbFormat);
4194 dest->pbFormat = 0;
4195 dest->cbFormat = 0;
4197 return S_OK;
4199 static HRESULT WINAPI expMoDeleteMediaType(MY_MEDIA_TYPE* dest)
4201 if (!dest)
4202 return E_POINTER;
4203 expMoFreeMediaType(dest);
4204 my_release(dest);
4205 return S_OK;
4208 static int exp_snprintf( char *str, int size, const char *format, ... )
4210 int x;
4211 va_list va;
4212 va_start(va, format);
4213 x=snprintf(str,size,format,va);
4214 dbgprintf("_snprintf( 0x%x, %d, %s, ... ) => %d\n",str,size,format,x);
4215 va_end(va);
4216 return x;
4219 #if 0
4220 static int exp_initterm(int v1, int v2)
4222 dbgprintf("_initterm(0x%x, 0x%x) => 0\n", v1, v2);
4223 return 0;
4225 #else
4226 /* merged from wine - 2002.04.21 */
4227 typedef void (*INITTERMFUNC)();
4228 static int exp_initterm(INITTERMFUNC *start, INITTERMFUNC *end)
4230 dbgprintf("_initterm(0x%x, 0x%x) %p\n", start, end, *start);
4231 while (start < end)
4233 if (*start)
4235 //printf("call _initfunc: from: %p %d\n", *start);
4236 // ok this trick with push/pop is necessary as otherwice
4237 // edi/esi registers are being trashed
4238 void* p = *start;
4239 __asm__ volatile
4241 "pushl %%ebx \n\t"
4242 "pushl %%ecx \n\t"
4243 "pushl %%edx \n\t"
4244 "pushl %%edi \n\t"
4245 "pushl %%esi \n\t"
4246 "call *%%eax \n\t"
4247 "popl %%esi \n\t"
4248 "popl %%edi \n\t"
4249 "popl %%edx \n\t"
4250 "popl %%ecx \n\t"
4251 "popl %%ebx \n\t"
4253 : "a"(p)
4254 : "memory"
4256 //printf("done %p %d:%d\n", end);
4258 start++;
4260 return 0;
4262 #endif
4264 /* Fake _initterm_e from msvcr80.dll, needed by sirenacm.dll
4265 * NOTE: If I make this an alias for _initterm, then sirenacm.dll tries to call
4266 other uninmplemented functions; keep this in mind if some future codec needs
4267 a real implementation of this function */
4268 static int exp_initterm_e(INITTERMFUNC *start, INITTERMFUNC *end)
4270 dbgprintf("_initterm_e(0x%x, 0x%x)\n", start, end);
4271 return 0;
4274 static void* exp__dllonexit(void)
4276 // FIXME extract from WINE
4277 return NULL;
4280 static int expwsprintfA(char* string, const char* format, ...)
4282 va_list va;
4283 int result;
4284 va_start(va, format);
4285 result = vsprintf(string, format, va);
4286 dbgprintf("wsprintfA(0x%x, '%s', ...) => %d\n", string, format, result);
4287 va_end(va);
4288 return result;
4291 static int expsprintf(char* str, const char* format, ...)
4293 va_list args;
4294 int r;
4295 dbgprintf("sprintf(0x%x, %s)\n", str, format);
4296 va_start(args, format);
4297 r = vsprintf(str, format, args);
4298 va_end(args);
4299 return r;
4301 static int expsscanf(const char* str, const char* format, ...)
4303 va_list args;
4304 int r;
4305 dbgprintf("sscanf(%s, %s)\n", str, format);
4306 va_start(args, format);
4307 r = vsscanf(str, format, args);
4308 va_end(args);
4309 return r;
4311 static void* expfopen(const char* path, const char* mode)
4313 printf("fopen: \"%s\" mode:%s\n", path, mode);
4314 //return fopen(path, mode);
4315 return fdopen(0, mode); // everything on screen
4317 static int expfprintf(void* stream, const char* format, ...)
4319 va_list args;
4320 int r = 0;
4321 dbgprintf("fprintf(%p, %s, ...)\n", stream, format);
4322 va_start(args, format);
4323 r = vfprintf((FILE*) stream, format, args);
4324 va_end(args);
4325 return r;
4328 static int expprintf(const char* format, ...)
4330 va_list args;
4331 int r;
4332 dbgprintf("printf(%s, ...)\n", format);
4333 va_start(args, format);
4334 r = vprintf(format, args);
4335 va_end(args);
4336 return r;
4339 static char* expgetenv(const char* varname)
4341 char* v = getenv(varname);
4342 dbgprintf("getenv(%s) => %s\n", varname, v);
4343 return v;
4346 static void* expwcscpy(WCHAR* dst, const WCHAR* src)
4348 WCHAR* p = dst;
4349 while ((*p++ = *src++))
4351 return dst;
4354 static char* expstrrchr(char* string, int value)
4356 char* result=strrchr(string, value);
4357 if(result)
4358 dbgprintf("strrchr(0x%x='%s', %d) => 0x%x='%s'", string, string, value, result, result);
4359 else
4360 dbgprintf("strrchr(0x%x='%s', %d) => 0", string, string, value);
4361 return result;
4364 static char* expstrchr(char* string, int value)
4366 char* result=strchr(string, value);
4367 if(result)
4368 dbgprintf("strchr(0x%x='%s', %d) => 0x%x='%s'", string, string, value, result, result);
4369 else
4370 dbgprintf("strchr(0x%x='%s', %d) => 0", string, string, value);
4371 return result;
4373 static int expstrlen(char* str)
4375 int result=strlen(str);
4376 dbgprintf("strlen(0x%x='%s') => %d\n", str, str, result);
4377 return result;
4379 static char* expstrcpy(char* str1, const char* str2)
4381 char* result= strcpy(str1, str2);
4382 dbgprintf("strcpy(0x%x, 0x%x='%s') => %p\n", str1, str2, str2, result);
4383 return result;
4385 static char* expstrncpy(char* str1, const char* str2, size_t count)
4387 char* result= strncpy(str1, str2, count);
4388 dbgprintf("strncpy(0x%x, 0x%x='%s', %d) => %p\n", str1, str2, str2, count, result);
4389 return result;
4391 static int expstrcmp(const char* str1, const char* str2)
4393 int result=strcmp(str1, str2);
4394 dbgprintf("strcmp(0x%x='%s', 0x%x='%s') => %d\n", str1, str1, str2, str2, result);
4395 return result;
4397 static int expstrncmp(const char* str1, const char* str2,int x)
4399 int result=strncmp(str1, str2,x);
4400 dbgprintf("strcmp(0x%x='%s', 0x%x='%s') => %d\n", str1, str1, str2, str2, result);
4401 return result;
4403 static char* expstrcat(char* str1, const char* str2)
4405 char* result = strcat(str1, str2);
4406 dbgprintf("strcat(0x%x='%s', 0x%x='%s') => %p\n", str1, str1, str2, str2, result);
4407 return result;
4409 static char* exp_strdup(const char* str1)
4411 int l = strlen(str1);
4412 char* result = (char*) my_mreq(l + 1,0);
4413 if (result)
4414 strcpy(result, str1);
4415 dbgprintf("_strdup(0x%x='%s') => %p\n", str1, str1, result);
4416 return result;
4418 static int expisalnum(int c)
4420 int result= (int) isalnum(c);
4421 dbgprintf("isalnum(0x%x='%c' => %d\n", c, c, result);
4422 return result;
4424 static int expisspace(int c)
4426 int result= (int) isspace(c);
4427 dbgprintf("isspace(0x%x='%c' => %d\n", c, c, result);
4428 return result;
4430 static int expisalpha(int c)
4432 int result= (int) isalpha(c);
4433 dbgprintf("isalpha(0x%x='%c' => %d\n", c, c, result);
4434 return result;
4436 static int expisdigit(int c)
4438 int result= (int) isdigit(c);
4439 dbgprintf("isdigit(0x%x='%c' => %d\n", c, c, result);
4440 return result;
4442 static void* expmemmove(void* dest, void* src, int n)
4444 void* result = memmove(dest, src, n);
4445 dbgprintf("memmove(0x%x, 0x%x, %d) => %p\n", dest, src, n, result);
4446 return result;
4448 static int expmemcmp(void* dest, void* src, int n)
4450 int result = memcmp(dest, src, n);
4451 dbgprintf("memcmp(0x%x, 0x%x, %d) => %d\n", dest, src, n, result);
4452 return result;
4454 static void* expmemcpy(void* dest, void* src, int n)
4456 void *result = memcpy(dest, src, n);
4457 dbgprintf("memcpy(0x%x, 0x%x, %d) => %p\n", dest, src, n, result);
4458 return result;
4460 static void* expmemset(void* dest, int c, size_t n)
4462 void *result = memset(dest, c, n);
4463 dbgprintf("memset(0x%x, %d, %d) => %p\n", dest, c, n, result);
4464 return result;
4466 static time_t exptime(time_t* t)
4468 time_t result = time(t);
4469 dbgprintf("time(0x%x) => %d\n", t, result);
4470 return result;
4473 static int exprand(void)
4475 return rand();
4478 static void expsrand(int seed)
4480 srand(seed);
4483 #if 1
4485 // preferred compilation with -O2 -ffast-math !
4487 static double explog10(double x)
4489 /*printf("Log10 %f => %f 0x%Lx\n", x, log10(x), *((int64_t*)&x));*/
4490 return log10(x);
4493 static double expcos(double x)
4495 /*printf("Cos %f => %f 0x%Lx\n", x, cos(x), *((int64_t*)&x));*/
4496 return cos(x);
4499 #else
4501 static void explog10(void)
4503 __asm__ volatile
4505 "fldl 8(%esp) \n\t"
4506 "fldln2 \n\t"
4507 "fxch %st(1) \n\t"
4508 "fyl2x \n\t"
4512 static void expcos(void)
4514 __asm__ volatile
4516 "fldl 8(%esp) \n\t"
4517 "fcos \n\t"
4521 #endif
4523 // this seem to be the only how to make this function working properly
4524 // ok - I've spent tremendous amount of time (many many many hours
4525 // of debuging fixing & testing - it's almost unimaginable - kabi
4527 // _ftol - operated on the float value which is already on the FPU stack
4529 static void exp_ftol(void)
4531 __asm__ volatile
4533 "sub $12, %esp \n\t"
4534 "fstcw -2(%ebp) \n\t"
4535 "wait \n\t"
4536 "movw -2(%ebp), %ax \n\t"
4537 "orb $0x0C, %ah \n\t"
4538 "movw %ax, -4(%ebp) \n\t"
4539 "fldcw -4(%ebp) \n\t"
4540 "fistpl -12(%ebp) \n\t"
4541 "fldcw -2(%ebp) \n\t"
4542 "movl -12(%ebp), %eax \n\t"
4543 //Note: gcc 3.03 does not do the following op if it
4544 // knows that ebp=esp
4545 "movl %ebp, %esp \n\t"
4549 #define FPU_DOUBLES(var1,var2) double var1,var2; \
4550 __asm__ volatile( "fstpl %0;fwait" : "=m" (var2) : ); \
4551 __asm__ volatile( "fstpl %0;fwait" : "=m" (var1) : )
4553 static double exp_CIpow(void)
4555 FPU_DOUBLES(x,y);
4557 dbgprintf("_CIpow(%lf, %lf)\n", x, y);
4558 return pow(x, y);
4561 static double exppow(double x, double y)
4563 /*printf("Pow %f %f 0x%Lx 0x%Lx => %f\n", x, y, *((int64_t*)&x), *((int64_t*)&y), pow(x, y));*/
4564 return pow(x, y);
4567 static double expldexp(double x, int expo)
4569 /*printf("Cos %f => %f 0x%Lx\n", x, cos(x), *((int64_t*)&x));*/
4570 return ldexp(x, expo);
4573 static double expfrexp(double x, int* expo)
4575 /*printf("Cos %f => %f 0x%Lx\n", x, cos(x), *((int64_t*)&x));*/
4576 return frexp(x, expo);
4581 static int exp_stricmp(const char* s1, const char* s2)
4583 return strcasecmp(s1, s2);
4586 /* from declaration taken from Wine sources - this fountion seems to be
4587 * undocumented in any M$ doc */
4588 static int exp_setjmp3(void* jmpbuf, int x)
4590 //dbgprintf("!!!!UNIMPLEMENTED: setjmp3(%p, %d) => 0\n", jmpbuf, x);
4591 //return 0;
4592 __asm__ volatile
4594 //"mov 4(%%esp), %%edx \n\t"
4595 "mov (%%esp), %%eax \n\t"
4596 "mov %%eax, (%%edx) \n\t" // store ebp
4598 //"mov %%ebp, (%%edx) \n\t"
4599 "mov %%ebx, 4(%%edx) \n\t"
4600 "mov %%edi, 8(%%edx) \n\t"
4601 "mov %%esi, 12(%%edx) \n\t"
4602 "mov %%esp, 16(%%edx) \n\t"
4604 "mov 4(%%esp), %%eax \n\t"
4605 "mov %%eax, 20(%%edx) \n\t"
4607 "movl $0x56433230, 32(%%edx) \n\t" // VC20 ??
4608 "movl $0, 36(%%edx) \n\t"
4609 : // output
4610 : "d"(jmpbuf) // input
4611 : "eax"
4613 __asm__ volatile
4615 "mov %%fs:0, %%eax \n\t" // unsure
4616 "mov %%eax, 24(%%edx) \n\t"
4617 "cmp $0xffffffff, %%eax \n\t"
4618 "jnz l1 \n\t"
4619 "mov %%eax, 28(%%edx) \n\t"
4620 "l1: \n\t"
4623 : "eax"
4626 return 0;
4629 static DWORD WINAPI expGetCurrentProcessId(void)
4631 dbgprintf("GetCurrentProcessId(void) => %d\n", getpid());
4632 return getpid(); //(DWORD)NtCurrentTeb()->pid;
4636 typedef struct {
4637 UINT wPeriodMin;
4638 UINT wPeriodMax;
4639 } TIMECAPS, *LPTIMECAPS;
4641 static MMRESULT WINAPI exptimeGetDevCaps(LPTIMECAPS lpCaps, UINT wSize)
4643 dbgprintf("timeGetDevCaps(%p, %u) !\n", lpCaps, wSize);
4645 lpCaps->wPeriodMin = 1;
4646 lpCaps->wPeriodMax = 65535;
4647 return 0;
4650 static MMRESULT WINAPI exptimeBeginPeriod(UINT wPeriod)
4652 dbgprintf("timeBeginPeriod(%u) !\n", wPeriod);
4654 if (wPeriod < 1 || wPeriod > 65535) return 96+1; //TIMERR_NOCANDO;
4655 return 0;
4658 #ifdef CONFIG_QTX_CODECS
4659 static MMRESULT WINAPI exptimeEndPeriod(UINT wPeriod)
4661 dbgprintf("timeEndPeriod(%u) !\n", wPeriod);
4663 if (wPeriod < 1 || wPeriod > 65535) return 96+1; //TIMERR_NOCANDO;
4664 return 0;
4666 #endif
4668 static void WINAPI expGlobalMemoryStatus(
4669 LPMEMORYSTATUS lpmem
4671 static MEMORYSTATUS cached_memstatus;
4672 static int cache_lastchecked = 0;
4673 SYSTEM_INFO si;
4674 FILE *f;
4676 if (time(NULL)==cache_lastchecked) {
4677 memcpy(lpmem,&cached_memstatus,sizeof(MEMORYSTATUS));
4678 return;
4681 f = fopen( "/proc/meminfo", "r" );
4682 if (f)
4684 char buffer[256];
4685 int total, used, free, shared, buffers, cached;
4687 lpmem->dwLength = sizeof(MEMORYSTATUS);
4688 lpmem->dwTotalPhys = lpmem->dwAvailPhys = 0;
4689 lpmem->dwTotalPageFile = lpmem->dwAvailPageFile = 0;
4690 while (fgets( buffer, sizeof(buffer), f ))
4692 /* old style /proc/meminfo ... */
4693 if (sscanf( buffer, "Mem: %d %d %d %d %d %d", &total, &used, &free, &shared, &buffers, &cached ))
4695 lpmem->dwTotalPhys += total;
4696 lpmem->dwAvailPhys += free + buffers + cached;
4698 if (sscanf( buffer, "Swap: %d %d %d", &total, &used, &free ))
4700 lpmem->dwTotalPageFile += total;
4701 lpmem->dwAvailPageFile += free;
4704 /* new style /proc/meminfo ... */
4705 if (sscanf(buffer, "MemTotal: %d", &total))
4706 lpmem->dwTotalPhys = total*1024;
4707 if (sscanf(buffer, "MemFree: %d", &free))
4708 lpmem->dwAvailPhys = free*1024;
4709 if (sscanf(buffer, "SwapTotal: %d", &total))
4710 lpmem->dwTotalPageFile = total*1024;
4711 if (sscanf(buffer, "SwapFree: %d", &free))
4712 lpmem->dwAvailPageFile = free*1024;
4713 if (sscanf(buffer, "Buffers: %d", &buffers))
4714 lpmem->dwAvailPhys += buffers*1024;
4715 if (sscanf(buffer, "Cached: %d", &cached))
4716 lpmem->dwAvailPhys += cached*1024;
4718 fclose( f );
4720 if (lpmem->dwTotalPhys)
4722 DWORD TotalPhysical = lpmem->dwTotalPhys+lpmem->dwTotalPageFile;
4723 DWORD AvailPhysical = lpmem->dwAvailPhys+lpmem->dwAvailPageFile;
4724 lpmem->dwMemoryLoad = (TotalPhysical-AvailPhysical)
4725 / (TotalPhysical / 100);
4727 } else
4729 /* FIXME: should do something for other systems */
4730 lpmem->dwMemoryLoad = 0;
4731 lpmem->dwTotalPhys = 16*1024*1024;
4732 lpmem->dwAvailPhys = 16*1024*1024;
4733 lpmem->dwTotalPageFile = 16*1024*1024;
4734 lpmem->dwAvailPageFile = 16*1024*1024;
4736 expGetSystemInfo(&si);
4737 lpmem->dwTotalVirtual = (uint8_t *)si.lpMaximumApplicationAddress-(uint8_t *)si.lpMinimumApplicationAddress;
4738 /* FIXME: we should track down all the already allocated VM pages and substract them, for now arbitrarily remove 64KB so that it matches NT */
4739 lpmem->dwAvailVirtual = lpmem->dwTotalVirtual-64*1024;
4740 memcpy(&cached_memstatus,lpmem,sizeof(MEMORYSTATUS));
4741 cache_lastchecked = time(NULL);
4743 /* it appears some memory display programs want to divide by these values */
4744 if(lpmem->dwTotalPageFile==0)
4745 lpmem->dwTotalPageFile++;
4747 if(lpmem->dwAvailPageFile==0)
4748 lpmem->dwAvailPageFile++;
4751 static INT WINAPI expGetThreadPriority(HANDLE hthread)
4753 dbgprintf("GetThreadPriority(%p)\n",hthread);
4754 return 0;
4757 /**********************************************************************
4758 * SetThreadPriority [KERNEL32.@] Sets priority for thread.
4760 * RETURNS
4761 * Success: TRUE
4762 * Failure: FALSE
4764 static WIN_BOOL WINAPI expSetThreadPriority(
4765 HANDLE hthread, /* [in] Handle to thread */
4766 INT priority) /* [in] Thread priority level */
4768 dbgprintf("SetThreadPriority(%p,%d)\n",hthread,priority);
4769 return TRUE;
4772 static void WINAPI expTerminateProcess( DWORD process, DWORD status )
4774 printf("EXIT - process %ld code %ld\n", process, status);
4775 exit(status);
4778 static void WINAPI expExitProcess( DWORD status )
4780 printf("EXIT - code %ld\n",status);
4781 exit(status);
4784 static INT WINAPI expMessageBoxA(HWND hWnd, LPCSTR text, LPCSTR title, UINT type){
4785 printf("MSGBOX '%s' '%s' (%d)\n",text,title,type);
4786 #ifdef CONFIG_QTX_CODECS
4787 if (type == MB_ICONHAND && !strlen(text) && !strlen(title))
4788 return IDIGNORE;
4789 #endif
4790 return IDOK;
4793 /* these are needed for mss1 */
4796 * \brief this symbol is defined within exp_EH_prolog_dummy
4797 * \param dest jump target
4799 void exp_EH_prolog(void *dest);
4800 void exp_EH_prolog_dummy(void);
4801 //! just a dummy function that acts a container for the asm section
4802 void exp_EH_prolog_dummy(void) {
4803 __asm__ volatile (
4804 // take care, this "function" may not change flags or
4805 // registers besides eax (which is also why we can't use
4806 // exp_EH_prolog_dummy directly)
4807 MANGLE(exp_EH_prolog)": \n\t"
4808 "pop %eax \n\t"
4809 "push %ebp \n\t"
4810 "mov %esp, %ebp \n\t"
4811 "lea -12(%esp), %esp \n\t"
4812 "jmp *%eax \n\t"
4816 #include <netinet/in.h>
4817 static WINAPI inline unsigned long int exphtonl(unsigned long int hostlong)
4819 // dbgprintf("htonl(%x) => %x\n", hostlong, htonl(hostlong));
4820 return htonl(hostlong);
4823 static WINAPI inline unsigned long int expntohl(unsigned long int netlong)
4825 // dbgprintf("ntohl(%x) => %x\n", netlong, ntohl(netlong));
4826 return ntohl(netlong);
4829 static char* WINAPI expSysAllocStringLen(char *pch, unsigned cch)
4831 char *str;
4832 dbgprintf("SysAllocStringLen('%s', %d)\n", pch, cch);
4833 str = malloc(cch * 2 + sizeof(unsigned) + 2);
4834 *(unsigned *)str = cch;
4835 str += sizeof(unsigned);
4836 if (pch)
4837 memcpy(str, pch, cch * 2);
4838 str[cch * 2] = 0;
4839 str[cch * 2 + 1] = 0;
4840 return str;
4843 static void WINAPI expSysFreeString(char *str)
4845 if (str) {
4846 free(str - sizeof(unsigned));
4850 static void WINAPI expVariantInit(void* p)
4852 printf("InitCommonControls called!\n");
4853 return;
4856 static int WINAPI expRegisterClassA(const void/*WNDCLASSA*/ *wc)
4858 dbgprintf("RegisterClassA(%p) => random id\n", wc);
4859 return time(NULL); /* be precise ! */
4862 static int WINAPI expUnregisterClassA(const char *className, HINSTANCE hInstance)
4864 dbgprintf("UnregisterClassA(%s, %p) => 0\n", className, hInstance);
4865 return 0;
4868 #ifdef CONFIG_QTX_CODECS
4869 /* should be fixed bcs it's not fully strlen equivalent */
4870 static int expSysStringByteLen(void *str)
4872 dbgprintf("SysStringByteLen(%p) => %d\n", str, strlen(str));
4873 return strlen(str);
4876 static int expDirectDrawCreate(void)
4878 dbgprintf("DirectDrawCreate(...) => NULL\n");
4879 return 0;
4882 #if 1
4883 typedef struct tagPALETTEENTRY {
4884 BYTE peRed;
4885 BYTE peGreen;
4886 BYTE peBlue;
4887 BYTE peFlags;
4888 } PALETTEENTRY;
4890 typedef struct tagLOGPALETTE {
4891 WORD palVersion;
4892 WORD palNumEntries;
4893 PALETTEENTRY palPalEntry[1];
4894 } LOGPALETTE;
4896 static HPALETTE WINAPI expCreatePalette(CONST LOGPALETTE *lpgpl)
4898 HPALETTE test;
4899 int i;
4901 dbgprintf("CreatePalette(%x) => NULL\n", lpgpl);
4903 i = sizeof(LOGPALETTE)+((lpgpl->palNumEntries-1)*sizeof(PALETTEENTRY));
4904 test = malloc(i);
4905 memcpy((void *)test, lpgpl, i);
4907 return test;
4909 #else
4910 static int expCreatePalette(void)
4912 dbgprintf("CreatePalette(...) => NULL\n");
4913 return NULL;
4915 #endif
4917 static int WINAPI expGetClientRect(HWND win, RECT *r)
4919 dbgprintf("GetClientRect(0x%x, 0x%x) => 1\n", win, r);
4920 r->right = PSEUDO_SCREEN_WIDTH;
4921 r->left = 0;
4922 r->bottom = PSEUDO_SCREEN_HEIGHT;
4923 r->top = 0;
4924 return 1;
4927 #if 0
4928 typedef struct tagPOINT {
4929 LONG x;
4930 LONG y;
4931 } POINT, *PPOINT;
4932 #endif
4934 static int WINAPI expClientToScreen(HWND win, POINT *p)
4936 dbgprintf("ClientToScreen(0x%x, 0x%x = %d,%d) => 1\n", win, p, p->x, p->y);
4937 p->x = 0;
4938 p->y = 0;
4939 return 1;
4941 #endif
4943 /* for m3jpeg */
4944 static int WINAPI expSetThreadIdealProcessor(HANDLE thread, int proc)
4946 dbgprintf("SetThreadIdealProcessor(0x%x, %x) => 0\n", thread, proc);
4947 return 0;
4950 static int WINAPI expMessageBeep(int type)
4952 dbgprintf("MessageBeep(%d) => 1\n", type);
4953 return 1;
4956 static int WINAPI expDialogBoxParamA(void *inst, const char *name,
4957 HWND parent, void *dialog_func, void *init_param)
4959 dbgprintf("DialogBoxParamA(0x%x, 0x%x = %s, 0x%x, 0x%x, 0x%x) => 0x42424242\n",
4960 inst, name, name, parent, dialog_func, init_param);
4961 return 0x42424242;
4964 static void WINAPI expRegisterClipboardFormatA(const char *name) {
4965 dbgprintf("RegisterClipboardFormatA(0x%x = %s)\n", name, name);
4968 /* needed by imagepower mjpeg2k */
4969 static void *exprealloc(void *ptr, size_t size)
4971 dbgprintf("realloc(0x%x, %x)\n", ptr, size);
4972 if (!ptr)
4973 return my_mreq(size,0);
4974 else
4975 return my_realloc(ptr, size);
4978 /* Fake GetOpenFileNameA from comdlg32.dll for ViVD codec */
4979 static WIN_BOOL WINAPI expGetOpenFileNameA(/*LPOPENFILENAMEA*/ void* lpfn)
4981 return 1;
4984 static const char * WINAPI expPathFindExtensionA(const char *path) {
4985 const char *ext;
4986 if (!path)
4987 ext = NULL;
4988 else {
4989 ext = strrchr(path, '.');
4990 if (!ext)
4991 ext = &path[strlen(path)];
4993 dbgprintf("PathFindExtensionA(0x%x = %s) => 0x%x, %s\n", path, path, ext, ext);
4994 return ext;
4997 static const char * WINAPI expPathFindFileNameA(const char *path) {
4998 const char *name;
4999 if (!path || strlen(path) < 2)
5000 name = path;
5001 else {
5002 name = strrchr(path - 1, '\\');
5003 if (!name)
5004 name = path;
5006 dbgprintf("PathFindFileNameA(0x%x = %s) => 0x%x, %s\n", path, path, name, name);
5007 return name;
5010 static double expfloor(double x)
5012 dbgprintf("floor(%lf)\n", x);
5013 return floor(x);
5016 #define FPU_DOUBLE(var) double var; \
5017 __asm__ volatile( "fstpl %0;fwait" : "=m" (var) : )
5019 static double exp_CIcos(void)
5021 FPU_DOUBLE(x);
5023 dbgprintf("_CIcos(%lf)\n", x);
5024 return cos(x);
5027 static double exp_CIsin(void)
5029 FPU_DOUBLE(x);
5031 dbgprintf("_CIsin(%lf)\n", x);
5032 return sin(x);
5035 static double exp_CIsqrt(void)
5037 FPU_DOUBLE(x);
5039 dbgprintf("_CIsqrt(%lf)\n", x);
5040 return sqrt(x);
5043 /* Needed by rp8 sipr decoder */
5044 static LPSTR WINAPI expCharNextA(LPCSTR ptr)
5046 if (!*ptr) return (LPSTR)ptr;
5047 // dbgprintf("CharNextA(0x%08x), %s\n", ptr, ptr);
5048 return (LPSTR)(ptr + 1);
5051 // Fake implementation, needed by wvc1dmod.dll
5052 static int WINAPI expPropVariantClear(void *pvar)
5054 // dbgprintf("PropVariantclear (0x%08x), %s\n", ptr, ptr);
5055 return 1;
5058 // This define is fake, the real thing is a struct
5059 #define LPDEVMODEA void*
5060 // Dummy implementation, always return 1
5061 // Required for frapsvid.dll 2.8.1, return value does not matter
5062 static WIN_BOOL WINAPI expEnumDisplaySettingsA(LPCSTR name ,DWORD n,
5063 LPDEVMODEA devmode)
5065 dbgprintf("EnumDisplaySettingsA (dummy) => 1\n");
5066 return 1;
5069 // Fake implementation of _decode_pointer from msvcr80.dll, needed by sirenacm.dll
5070 // NOTE: undocumented function, probably the declaration is not right
5071 static int exp_decode_pointer(void *ptr)
5073 dbgprintf("_decode_pointer (0x%08x)\n", ptr);
5074 return 0;
5077 /* Fake implementation of sdt::_Lockit::_Lockit(void) from msvcp60.dll
5078 Needed by SCLS.DLL */
5079 static int exp_0Lockit_dummy(void)
5081 dbgprintf("0Lockit_dummy (??0_Lockit@std@@QAE@XZ)\n");
5082 return 0;
5085 /* Fake implementation of sdt::_Lockit::~_Lockit(void) from msvcp60.dll
5086 Needed by SCLS.DLL */
5087 static int exp_1Lockit_dummy(void)
5089 dbgprintf("1Lockit_dummy (??1_Lockit@std@@QAE@XZ)\n");
5090 return 0;
5093 static void * WINAPI expEncodePointer(void *p)
5095 return p;
5098 static void * WINAPI expDecodePointer(void *p)
5100 return p;
5103 static DWORD WINAPI expGetThreadLocale(void)
5105 return 0;
5109 * Very incomplete implementation, return an error for almost all cases.
5111 static DWORD WINAPI expGetLocaleInfoA(DWORD locale, DWORD lctype, char* lpLCData, int cchData)
5113 if (lctype == 0x1004) { // LOCALE_IDEFAULTANSICODEPAGE
5114 if (cchData < 4)
5115 return cchData == 0 ? 4 : 0;
5116 strcpy(lpLCData, "437");
5117 return 4;
5119 return 0;
5122 struct exports
5124 char name[64];
5125 int id;
5126 void* func;
5128 struct libs
5130 char name[64];
5131 int length;
5132 const struct exports* exps;
5135 #define FF(X,Y) \
5136 {#X, Y, (void*)exp##X},
5138 #define UNDEFF(X, Y) \
5139 {#X, Y, (void*)-1},
5141 static const struct exports exp_kernel32[]=
5143 FF(GetVolumeInformationA,-1)
5144 FF(GetDriveTypeA,-1)
5145 FF(GetLogicalDriveStringsA,-1)
5146 FF(IsBadWritePtr, 357)
5147 FF(IsBadReadPtr, 354)
5148 FF(IsBadStringPtrW, -1)
5149 FF(IsBadStringPtrA, -1)
5150 FF(DisableThreadLibraryCalls, -1)
5151 FF(CreateThread, -1)
5152 FF(ResumeThread, -1)
5153 FF(CreateEventA, -1)
5154 FF(CreateEventW, -1)
5155 FF(SetEvent, -1)
5156 FF(ResetEvent, -1)
5157 FF(WaitForSingleObject, -1)
5158 #ifdef CONFIG_QTX_CODECS
5159 FF(WaitForMultipleObjects, -1)
5160 FF(ExitThread, -1)
5161 #endif
5162 FF(GetSystemInfo, -1)
5163 FF(GetVersion, 332)
5164 FF(HeapCreate, 461)
5165 FF(HeapAlloc, -1)
5166 FF(HeapDestroy, -1)
5167 FF(HeapFree, -1)
5168 FF(HeapSize, -1)
5169 FF(HeapReAlloc,-1)
5170 FF(GetProcessHeap, -1)
5171 FF(VirtualAlloc, -1)
5172 FF(VirtualFree, -1)
5173 FF(InitializeCriticalSection, -1)
5174 FF(InitializeCriticalSectionAndSpinCount, -1)
5175 FF(EnterCriticalSection, -1)
5176 FF(LeaveCriticalSection, -1)
5177 FF(DeleteCriticalSection, -1)
5178 FF(TlsAlloc, -1)
5179 FF(TlsFree, -1)
5180 FF(TlsGetValue, -1)
5181 FF(TlsSetValue, -1)
5182 FF(GetCurrentThreadId, -1)
5183 FF(GetCurrentProcess, -1)
5184 FF(LocalAlloc, -1)
5185 FF(LocalReAlloc,-1)
5186 FF(LocalLock, -1)
5187 FF(GlobalAlloc, -1)
5188 FF(GlobalReAlloc, -1)
5189 FF(GlobalLock, -1)
5190 FF(GlobalSize, -1)
5191 FF(MultiByteToWideChar, 427)
5192 FF(WideCharToMultiByte, -1)
5193 FF(GetVersionExA, -1)
5194 FF(GetVersionExW, -1)
5195 FF(CreateSemaphoreA, -1)
5196 FF(CreateSemaphoreW, -1)
5197 FF(QueryPerformanceCounter, -1)
5198 FF(QueryPerformanceFrequency, -1)
5199 FF(LocalHandle, -1)
5200 FF(LocalUnlock, -1)
5201 FF(LocalFree, -1)
5202 FF(GlobalHandle, -1)
5203 FF(GlobalUnlock, -1)
5204 FF(GlobalFree, -1)
5205 FF(LoadResource, -1)
5206 FF(ReleaseSemaphore, -1)
5207 FF(CreateMutexA, -1)
5208 FF(CreateMutexW, -1)
5209 FF(ReleaseMutex, -1)
5210 FF(SignalObjectAndWait, -1)
5211 FF(FindResourceA, -1)
5212 FF(LockResource, -1)
5213 FF(FreeResource, -1)
5214 FF(SizeofResource, -1)
5215 FF(CloseHandle, -1)
5216 FF(GetCommandLineA, -1)
5217 FF(GetEnvironmentStringsW, -1)
5218 FF(FreeEnvironmentStringsW, -1)
5219 FF(FreeEnvironmentStringsA, -1)
5220 FF(GetEnvironmentStrings, -1)
5221 FF(GetStartupInfoA, -1)
5222 FF(GetStdHandle, -1)
5223 FF(GetFileType, -1)
5224 #ifdef CONFIG_QTX_CODECS
5225 FF(GetFileAttributesA, -1)
5226 #endif
5227 FF(SetHandleCount, -1)
5228 FF(GetACP, -1)
5229 FF(GetModuleFileNameA, -1)
5230 FF(SetUnhandledExceptionFilter, -1)
5231 FF(LoadLibraryA, -1)
5232 FF(GetProcAddress, -1)
5233 FF(FreeLibrary, -1)
5234 FF(CreateFileMappingA, -1)
5235 FF(OpenFileMappingA, -1)
5236 FF(MapViewOfFile, -1)
5237 FF(UnmapViewOfFile, -1)
5238 FF(Sleep, -1)
5239 FF(GetModuleHandleA, -1)
5240 FF(GetModuleHandleW, -1)
5241 FF(GetProfileIntA, -1)
5242 FF(GetPrivateProfileIntA, -1)
5243 FF(GetPrivateProfileStringA, -1)
5244 FF(WritePrivateProfileStringA, -1)
5245 FF(GetLastError, -1)
5246 FF(SetLastError, -1)
5247 FF(InterlockedIncrement, -1)
5248 FF(InterlockedDecrement, -1)
5249 FF(GetTimeZoneInformation, -1)
5250 FF(OutputDebugStringA, -1)
5251 FF(GetLocalTime, -1)
5252 FF(GetSystemTime, -1)
5253 FF(GetSystemTimeAsFileTime, -1)
5254 FF(GetEnvironmentVariableA, -1)
5255 FF(SetEnvironmentVariableA, -1)
5256 FF(RtlZeroMemory,-1)
5257 FF(RtlMoveMemory,-1)
5258 FF(RtlFillMemory,-1)
5259 FF(GetTempPathA,-1)
5260 FF(FindFirstFileA,-1)
5261 FF(FindNextFileA,-1)
5262 FF(FindClose,-1)
5263 FF(FileTimeToLocalFileTime,-1)
5264 FF(DeleteFileA,-1)
5265 FF(ReadFile,-1)
5266 FF(WriteFile,-1)
5267 FF(SetFilePointer,-1)
5268 FF(GetTempFileNameA,-1)
5269 FF(CreateFileA,-1)
5270 FF(GetSystemDirectoryA,-1)
5271 FF(GetWindowsDirectoryA,-1)
5272 #ifdef CONFIG_QTX_CODECS
5273 FF(GetCurrentDirectoryA,-1)
5274 FF(SetCurrentDirectoryA,-1)
5275 FF(CreateDirectoryA,-1)
5276 #endif
5277 FF(GetShortPathNameA,-1)
5278 FF(GetFullPathNameA,-1)
5279 FF(SetErrorMode, -1)
5280 FF(IsProcessorFeaturePresent, -1)
5281 FF(IsDebuggerPresent, -1)
5282 FF(GetProcessAffinityMask, -1)
5283 FF(InterlockedExchange, -1)
5284 FF(InterlockedCompareExchange, -1)
5285 FF(MulDiv, -1)
5286 FF(lstrcmpiA, -1)
5287 FF(lstrlenA, -1)
5288 FF(lstrcpyA, -1)
5289 FF(lstrcatA, -1)
5290 FF(lstrcpynA,-1)
5291 FF(GetProcessVersion,-1)
5292 FF(GetCurrentThread,-1)
5293 FF(GetOEMCP,-1)
5294 FF(GetCPInfo,-1)
5295 FF(DuplicateHandle,-1)
5296 FF(GetTickCount, -1)
5297 FF(SetThreadAffinityMask,-1)
5298 FF(GetCurrentProcessId,-1)
5299 FF(GlobalMemoryStatus,-1)
5300 FF(GetThreadPriority,-1)
5301 FF(SetThreadPriority,-1)
5302 FF(TerminateProcess,-1)
5303 FF(ExitProcess,-1)
5304 {"LoadLibraryExA", -1, (void*)&LoadLibraryExA},
5305 FF(SetThreadIdealProcessor,-1)
5306 FF(SetProcessAffinityMask, -1)
5307 FF(EncodePointer, -1)
5308 FF(DecodePointer, -1)
5309 FF(GetThreadLocale, -1)
5310 FF(GetLocaleInfoA, -1)
5311 UNDEFF(FlsAlloc, -1)
5312 UNDEFF(FlsGetValue, -1)
5313 UNDEFF(FlsSetValue, -1)
5314 UNDEFF(FlsFree, -1)
5317 static const struct exports exp_msvcrt[]={
5318 FF(malloc, -1)
5319 FF(_initterm, -1)
5320 FF(__dllonexit, -1)
5321 FF(_snprintf,-1)
5322 FF(free, -1)
5323 {"??3@YAXPAX@Z", -1, expdelete},
5324 {"??2@YAPAXI@Z", -1, expnew},
5325 {"_adjust_fdiv", -1, (void*)&_adjust_fdiv},
5326 {"_winver",-1,(void*)&_winver},
5327 FF(strrchr, -1)
5328 FF(strchr, -1)
5329 FF(strlen, -1)
5330 FF(strcpy, -1)
5331 FF(strncpy, -1)
5332 FF(wcscpy, -1)
5333 FF(strcmp, -1)
5334 FF(strncmp, -1)
5335 FF(strcat, -1)
5336 FF(_stricmp,-1)
5337 FF(_strdup,-1)
5338 FF(_setjmp3,-1)
5339 FF(isalnum, -1)
5340 FF(isspace, -1)
5341 FF(isalpha, -1)
5342 FF(isdigit, -1)
5343 FF(memmove, -1)
5344 FF(memcmp, -1)
5345 FF(memset, -1)
5346 FF(memcpy, -1)
5347 FF(time, -1)
5348 FF(rand, -1)
5349 FF(srand, -1)
5350 FF(log10, -1)
5351 FF(pow, -1)
5352 FF(cos, -1)
5353 FF(_ftol,-1)
5354 FF(_CIpow,-1)
5355 FF(_CIcos,-1)
5356 FF(_CIsin,-1)
5357 FF(_CIsqrt,-1)
5358 FF(ldexp,-1)
5359 FF(frexp,-1)
5360 FF(sprintf,-1)
5361 FF(sscanf,-1)
5362 FF(fopen,-1)
5363 FF(fprintf,-1)
5364 FF(printf,-1)
5365 FF(getenv,-1)
5366 FF(floor,-1)
5367 /* needed by frapsvid.dll */
5368 {"strstr",-1,(char *)&strstr},
5369 {"qsort",-1,(void *)&qsort},
5370 FF(_EH_prolog,-1)
5371 FF(calloc,-1)
5372 {"ceil",-1,(void*)&ceil},
5373 /* needed by imagepower mjpeg2k */
5374 {"clock",-1,(void*)&clock},
5375 {"memchr",-1,(void*)&memchr},
5376 {"vfprintf",-1,(void*)&vfprintf},
5377 // {"realloc",-1,(void*)&realloc},
5378 FF(realloc,-1)
5379 {"puts",-1,(void*)&puts}
5381 static const struct exports exp_winmm[]={
5382 FF(GetDriverModuleHandle, -1)
5383 FF(timeGetTime, -1)
5384 FF(DefDriverProc, -1)
5385 FF(OpenDriverA, -1)
5386 FF(OpenDriver, -1)
5387 FF(timeGetDevCaps, -1)
5388 FF(timeBeginPeriod, -1)
5389 #ifdef CONFIG_QTX_CODECS
5390 FF(timeEndPeriod, -1)
5391 FF(waveOutGetNumDevs, -1)
5392 #endif
5394 static const struct exports exp_psapi[]={
5395 FF(GetModuleBaseNameA, -1)
5397 static const struct exports exp_user32[]={
5398 FF(LoadIconA,-1)
5399 FF(LoadStringA, -1)
5400 FF(wsprintfA, -1)
5401 FF(GetDC, -1)
5402 FF(GetDesktopWindow, -1)
5403 FF(ReleaseDC, -1)
5404 FF(IsRectEmpty, -1)
5405 FF(LoadCursorA,-1)
5406 FF(SetCursor,-1)
5407 FF(GetCursorPos,-1)
5408 #ifdef CONFIG_QTX_CODECS
5409 FF(ShowCursor,-1)
5410 #endif
5411 FF(RegisterWindowMessageA,-1)
5412 FF(GetSystemMetrics,-1)
5413 FF(GetSysColor,-1)
5414 FF(GetSysColorBrush,-1)
5415 FF(GetWindowDC, -1)
5416 FF(DrawTextA, -1)
5417 FF(MessageBoxA, -1)
5418 FF(RegisterClassA, -1)
5419 FF(UnregisterClassA, -1)
5420 #ifdef CONFIG_QTX_CODECS
5421 FF(GetWindowRect, -1)
5422 FF(MonitorFromWindow, -1)
5423 FF(MonitorFromRect, -1)
5424 FF(MonitorFromPoint, -1)
5425 FF(EnumDisplayMonitors, -1)
5426 FF(GetMonitorInfoA, -1)
5427 FF(EnumDisplayDevicesA, -1)
5428 FF(GetClientRect, -1)
5429 FF(ClientToScreen, -1)
5430 FF(IsWindowVisible, -1)
5431 FF(GetActiveWindow, -1)
5432 FF(GetClassNameA, -1)
5433 FF(GetClassInfoA, -1)
5434 FF(GetWindowLongA, -1)
5435 FF(EnumWindows, -1)
5436 FF(GetWindowThreadProcessId, -1)
5437 FF(CreateWindowExA, -1)
5438 #endif
5439 FF(MessageBeep, -1)
5440 FF(DialogBoxParamA, -1)
5441 FF(RegisterClipboardFormatA, -1)
5442 FF(CharNextA, -1)
5443 FF(EnumDisplaySettingsA, -1)
5445 static const struct exports exp_advapi32[]={
5446 FF(RegCloseKey, -1)
5447 FF(RegCreateKeyA, -1)
5448 FF(RegCreateKeyExA, -1)
5449 FF(RegEnumKeyExA, -1)
5450 FF(RegEnumValueA, -1)
5451 FF(RegOpenKeyA, -1)
5452 FF(RegOpenKeyExA, -1)
5453 FF(RegQueryValueExA, -1)
5454 FF(RegSetValueExA, -1)
5455 FF(RegQueryInfoKeyA, -1)
5457 static const struct exports exp_gdi32[]={
5458 FF(CreateCompatibleDC, -1)
5459 FF(CreateFontA, -1)
5460 FF(DeleteDC, -1)
5461 FF(DeleteObject, -1)
5462 FF(GetDeviceCaps, -1)
5463 FF(GetSystemPaletteEntries, -1)
5464 #ifdef CONFIG_QTX_CODECS
5465 FF(CreatePalette, -1)
5466 FF(GetObjectA, -1)
5467 FF(CreateRectRgn, -1)
5468 #endif
5470 static const struct exports exp_version[]={
5471 FF(GetFileVersionInfoSizeA, -1)
5473 static const struct exports exp_ole32[]={
5474 FF(CoCreateFreeThreadedMarshaler,-1)
5475 FF(CoCreateInstance, -1)
5476 FF(CoInitialize, -1)
5477 FF(CoInitializeEx, -1)
5478 FF(CoUninitialize, -1)
5479 FF(CoTaskMemAlloc, -1)
5480 FF(CoTaskMemFree, -1)
5481 FF(StringFromGUID2, -1)
5482 FF(PropVariantClear, -1)
5484 // do we really need crtdll ???
5485 // msvcrt is the correct place probably...
5486 static const struct exports exp_crtdll[]={
5487 FF(memcpy, -1)
5488 FF(wcscpy, -1)
5490 static const struct exports exp_comctl32[]={
5491 FF(StringFromGUID2, -1)
5492 FF(InitCommonControls, 17)
5493 #ifdef CONFIG_QTX_CODECS
5494 FF(CreateUpDownControl, 16)
5495 #endif
5497 static const struct exports exp_wsock32[]={
5498 FF(htonl,8)
5499 FF(ntohl,14)
5501 static const struct exports exp_msdmo[]={
5502 FF(memcpy, -1) // just test
5503 FF(MoCopyMediaType, -1)
5504 FF(MoCreateMediaType, -1)
5505 FF(MoDeleteMediaType, -1)
5506 FF(MoDuplicateMediaType, -1)
5507 FF(MoFreeMediaType, -1)
5508 FF(MoInitMediaType, -1)
5510 static const struct exports exp_oleaut32[]={
5511 FF(SysAllocStringLen, 4)
5512 FF(SysFreeString, 6)
5513 FF(VariantInit, 8)
5514 #ifdef CONFIG_QTX_CODECS
5515 FF(SysStringByteLen, 149)
5516 #endif
5519 /* realplayer8:
5520 DLL Name: PNCRT.dll
5521 vma: Hint/Ord Member-Name
5522 22ff4 615 free
5523 2302e 250 _ftol
5524 22fea 666 malloc
5525 2303e 609 fprintf
5526 2305e 167 _adjust_fdiv
5527 23052 280 _initterm
5529 22ffc 176 _beginthreadex
5530 23036 284 _iob
5531 2300e 85 __CxxFrameHandler
5532 23022 411 _purecall
5534 #ifdef REALPLAYER
5535 static const struct exports exp_pncrt[]={
5536 FF(malloc, -1) // just test
5537 FF(free, -1) // just test
5538 FF(fprintf, -1) // just test
5539 {"_adjust_fdiv", -1, (void*)&_adjust_fdiv},
5540 FF(_ftol,-1)
5541 FF(_initterm, -1)
5542 {"??3@YAXPAX@Z", -1, expdelete},
5543 {"??2@YAPAXI@Z", -1, expnew},
5544 FF(__dllonexit, -1)
5545 FF(strncpy, -1)
5546 FF(_CIpow,-1)
5547 FF(calloc,-1)
5548 FF(memmove, -1)
5549 FF(ldexp, -1)
5550 FF(frexp, -1)
5552 #endif
5554 #ifdef CONFIG_QTX_CODECS
5555 static const struct exports exp_ddraw[]={
5556 FF(DirectDrawCreate, -1)
5558 #endif
5560 static const struct exports exp_comdlg32[]={
5561 FF(GetOpenFileNameA, -1)
5564 static const struct exports exp_shlwapi[]={
5565 FF(PathFindExtensionA, -1)
5566 FF(PathFindFileNameA, -1)
5569 static const struct exports exp_msvcr80[]={
5570 FF(_CIpow,-1)
5571 FF(_CIsin,-1)
5572 FF(_CIcos,-1)
5573 FF(_CIsqrt,-1)
5574 FF(memset,-1)
5575 FF(_initterm_e, -1)
5576 FF(_initterm, -1)
5577 FF(_decode_pointer, -1)
5578 /* needed by KGV1-VFW.dll */
5579 {"??2@YAPAXI@Z", -1, expnew},
5580 {"??3@YAXPAX@Z", -1, expdelete}
5583 static const struct exports exp_msvcp60[]={
5584 {"??0_Lockit@std@@QAE@XZ", -1, exp_0Lockit_dummy},
5585 {"??1_Lockit@std@@QAE@XZ", -1, exp_1Lockit_dummy}
5588 #define LL(X) \
5589 {#X".dll", sizeof(exp_##X)/sizeof(struct exports), exp_##X},
5591 static const struct libs libraries[]={
5592 LL(kernel32)
5593 LL(msvcrt)
5594 LL(winmm)
5595 LL(psapi)
5596 LL(user32)
5597 LL(advapi32)
5598 LL(gdi32)
5599 LL(version)
5600 LL(ole32)
5601 LL(oleaut32)
5602 LL(crtdll)
5603 LL(comctl32)
5604 LL(wsock32)
5605 LL(msdmo)
5606 #ifdef REALPLAYER
5607 LL(pncrt)
5608 #endif
5609 #ifdef CONFIG_QTX_CODECS
5610 LL(ddraw)
5611 #endif
5612 LL(comdlg32)
5613 LL(shlwapi)
5614 LL(msvcr80)
5615 LL(msvcp60)
5618 static WIN_BOOL WINAPI ext_stubs(void)
5620 // NOTE! these magic values will be replaced at runtime, make sure
5621 // add_stub can still find them if you change them.
5622 volatile int idx = 0x0deadabc;
5623 // make sure gcc does not do eip-relative call or something like that
5624 void (* volatile my_printf)(char *, char *) = (void *)0xdeadfbcd;
5625 my_printf("Called unk_%s\n", export_names[idx]);
5626 return 0;
5629 #define MAX_STUB_SIZE 0x60
5630 #define MAX_NUM_STUBS 200
5631 static int pos=0;
5632 static char *extcode = NULL;
5634 static void* add_stub(void)
5636 int i;
5637 int found = 0;
5638 // generated code in runtime!
5639 char* answ;
5640 if (!extcode)
5641 extcode = mmap_anon(NULL, MAX_NUM_STUBS * MAX_STUB_SIZE,
5642 PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE, 0);
5643 answ = extcode + pos * MAX_STUB_SIZE;
5644 if (pos >= MAX_NUM_STUBS) {
5645 printf("too many stubs, expect crash\n");
5646 return NULL;
5648 memcpy(answ, ext_stubs, MAX_STUB_SIZE);
5649 for (i = 0; i < MAX_STUB_SIZE - 3; i++) {
5650 int *magic = (int *)(answ + i);
5651 if (*magic == 0x0deadabc) {
5652 *magic = pos;
5653 found |= 1;
5655 if (*magic == 0xdeadfbcd) {
5656 *magic = (intptr_t)printf;
5657 found |= 2;
5660 if (found != 3) {
5661 printf("magic code not found in ext_subs, expect crash\n");
5662 return NULL;
5664 pos++;
5665 return (void*)answ;
5668 void* LookupExternal(const char* library, int ordinal)
5670 int i,j;
5671 if(library==0)
5673 printf("ERROR: library=0\n");
5674 return (void*)ext_unknown;
5676 // printf("%x %x\n", &unk_exp1, &unk_exp2);
5678 dbgprintf("External func %s:%d\n", library, ordinal);
5680 for(i=0; i<sizeof(libraries)/sizeof(struct libs); i++)
5682 if(strcasecmp(library, libraries[i].name))
5683 continue;
5684 for(j=0; j<libraries[i].length; j++)
5686 if(ordinal!=libraries[i].exps[j].id)
5687 continue;
5688 //printf("Hit: 0x%p\n", libraries[i].exps[j].func);
5689 return libraries[i].exps[j].func;
5693 #ifndef LOADLIB_TRY_NATIVE
5694 /* hack for truespeech and vssh264*/
5695 if (!strcmp(library, "tsd32.dll") || !strcmp(library,"vssh264dec.dll") || !strcmp(library,"LCMW2.dll") || !strcmp(library,"VDODEC32.dll"))
5696 #endif
5697 /* ok, this is a hack, and a big memory leak. should be fixed. - alex */
5699 int hand;
5700 WINE_MODREF *wm;
5701 void *func;
5703 hand = LoadLibraryA(library);
5704 if (!hand)
5705 goto no_dll;
5706 wm = MODULE32_LookupHMODULE(hand);
5707 if (!wm)
5709 FreeLibrary(hand);
5710 goto no_dll;
5712 func = PE_FindExportedFunction(wm, (LPCSTR) ordinal, 0);
5713 if (!func)
5715 printf("No such ordinal in external dll\n");
5716 FreeLibrary((int)hand);
5717 goto no_dll;
5720 printf("External dll loaded (offset: 0x%x, func: %p)\n",
5721 hand, func);
5722 return func;
5725 no_dll:
5726 if(pos>150)return 0;
5727 snprintf(export_names[pos], sizeof(export_names[pos]), "%s:%d", library, ordinal);
5728 return add_stub();
5731 void* LookupExternalByName(const char* library, const char* name)
5733 int i,j;
5734 // return (void*)ext_unknown;
5735 if(library==0)
5737 printf("ERROR: library=0\n");
5738 return (void*)ext_unknown;
5740 if((unsigned long)name<=0xffff)
5742 return LookupExternal(library, (int)name);
5744 dbgprintf("External func %s:%s\n", library, name);
5745 for(i=0; i<sizeof(libraries)/sizeof(struct libs); i++)
5747 if(strcasecmp(library, libraries[i].name))
5748 continue;
5749 for(j=0; j<libraries[i].length; j++)
5751 if(strcmp(name, libraries[i].exps[j].name))
5752 continue;
5753 if((unsigned int)(libraries[i].exps[j].func) == -1)
5754 return NULL; //undefined func
5755 // printf("Hit: 0x%08X\n", libraries[i].exps[j].func);
5756 return libraries[i].exps[j].func;
5760 #ifndef LOADLIB_TRY_NATIVE
5761 /* hack for vss h264 */
5762 if (!strcmp(library,"vssh264core.dll") || !strcmp(library,"3ivx.dll"))
5763 #endif
5764 /* ok, this is a hack, and a big memory leak. should be fixed. - alex */
5766 int hand;
5767 WINE_MODREF *wm;
5768 void *func;
5770 hand = LoadLibraryA(library);
5771 if (!hand)
5772 goto no_dll_byname;
5773 wm = MODULE32_LookupHMODULE(hand);
5774 if (!wm)
5776 FreeLibrary(hand);
5777 goto no_dll_byname;
5779 func = PE_FindExportedFunction(wm, name, 0);
5780 if (!func)
5782 printf("No such name in external dll\n");
5783 FreeLibrary((int)hand);
5784 goto no_dll_byname;
5787 printf("External dll loaded (offset: 0x%x, func: %p)\n",
5788 hand, func);
5789 return func;
5792 no_dll_byname:
5793 if(pos>150)return 0;// to many symbols
5794 snprintf(export_names[pos], sizeof(export_names[pos]), "%s", name);
5795 return add_stub();
5798 void my_garbagecollection(void)
5800 #ifdef GARBAGE
5801 int unfree = 0, unfreecnt = 0;
5803 int max_fatal = 8;
5804 free_registry();
5805 while (last_alloc)
5807 alloc_header* mem = last_alloc + 1;
5808 unfree += my_size(mem);
5809 unfreecnt++;
5810 if (my_release(mem) != 0)
5811 // avoid endless loop when memory is trashed
5812 if (--max_fatal < 0)
5813 break;
5815 dbgprintf("Total Unfree %d bytes cnt %d [%p,%d]\n",unfree, unfreecnt, last_alloc, alccnt);
5816 #endif
5817 g_tls = NULL;
5818 pthread_mutex_lock(&list_lock);
5819 list = NULL;
5820 pthread_mutex_unlock(&list_lock);