Merge svn changes up to r30876
[mplayer/kovensky.git] / loader / win32.c
blobd540e6dfe24a105bd32fcf5b9f0116c12f1dd22e
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"
53 #include <stdlib.h>
54 #include <assert.h>
55 #include <stdarg.h>
56 #include <ctype.h>
57 #include <pthread.h>
58 #include <errno.h>
59 #include <time.h>
60 #include <math.h>
61 #include <unistd.h>
62 #include <fcntl.h>
63 #include <sys/types.h>
64 #include <dirent.h>
65 #include <sys/time.h>
66 #include <sys/stat.h>
67 #include <sys/timeb.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"
80 char* def_path = WIN32_PATH;
82 static void do_cpuid(unsigned int ax, unsigned int *regs)
84 __asm__ volatile
86 "pushl %%ebx; pushl %%ecx; pushl %%edx;"
87 ".byte 0x0f, 0xa2;"
88 "movl %%eax, (%2);"
89 "movl %%ebx, 4(%2);"
90 "movl %%ecx, 8(%2);"
91 "movl %%edx, 12(%2);"
92 "popl %%edx; popl %%ecx; popl %%ebx;"
93 : "=a" (ax)
94 : "0" (ax), "S" (regs)
97 static unsigned int c_localcount_tsc(void)
99 int a;
100 __asm__ volatile
102 "rdtsc\n\t"
103 :"=a"(a)
105 :"edx"
107 return a;
109 static void c_longcount_tsc(long long* z)
111 __asm__ volatile
113 "pushl %%ebx\n\t"
114 "movl %%eax, %%ebx\n\t"
115 "rdtsc\n\t"
116 "movl %%eax, 0(%%ebx)\n\t"
117 "movl %%edx, 4(%%ebx)\n\t"
118 "popl %%ebx\n\t"
119 ::"a"(z)
120 :"edx"
123 static unsigned int c_localcount_notsc(void)
125 struct timeval tv;
126 unsigned limit=~0;
127 limit/=1000000;
128 gettimeofday(&tv, 0);
129 return limit*tv.tv_usec;
131 static void c_longcount_notsc(long long* z)
133 struct timeval tv;
134 unsigned long long result;
135 unsigned limit=~0;
136 if(!z)return;
137 limit/=1000000;
138 gettimeofday(&tv, 0);
139 result=tv.tv_sec;
140 result<<=32;
141 result+=limit*tv.tv_usec;
142 *z=result;
144 static unsigned int localcount_stub(void);
145 static void longcount_stub(long long*);
146 static unsigned int (*localcount)()=localcount_stub;
147 static void (*longcount)(long long*)=longcount_stub;
149 static pthread_mutex_t memmut;
151 static unsigned int localcount_stub(void)
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 return localcount();
167 static void longcount_stub(long long* z)
169 unsigned int regs[4];
170 do_cpuid(1, regs);
171 if ((regs[3] & 0x00000010) != 0)
173 localcount=c_localcount_tsc;
174 longcount=c_longcount_tsc;
176 else
178 localcount=c_localcount_notsc;
179 longcount=c_longcount_notsc;
181 longcount(z);
184 #include "mp_msg.h"
185 int LOADER_DEBUG=1; // active only if compiled with -DDETAILED_OUT
186 //#define DETAILED_OUT
187 static inline void dbgprintf(char* fmt, ...)
189 #ifdef DETAILED_OUT
190 if(LOADER_DEBUG)
192 FILE* f;
193 va_list va;
194 va_start(va, fmt);
195 f=fopen("./log", "a");
196 vprintf(fmt, va);
197 fflush(stdout);
198 if(f)
200 vfprintf(f, fmt, va);
201 fsync(fileno(f));
202 fclose(f);
204 va_end(va);
206 #endif
207 if ( mp_msg_test(MSGT_WIN32,MSGL_DBG3) )
209 va_list va;
211 va_start(va, fmt);
212 vprintf(fmt, va);
213 // mp_dbg(MSGT_WIN32, MSGL_DBG3, fmt, va);
214 va_end(va);
215 fflush(stdout);
220 char export_names[300][32]={
221 "name1",
222 //"name2",
223 //"name3"
225 //#define min(x,y) ((x)<(y)?(x):(y))
227 void destroy_event(void* event);
229 struct th_list_t;
230 typedef struct th_list_t{
231 int id;
232 void* thread;
233 struct th_list_t* next;
234 struct th_list_t* prev;
235 } th_list;
238 // have to be cleared by GARBAGE COLLECTOR
239 //static unsigned char* heap=NULL;
240 //static int heap_counter=0;
241 static tls_t* g_tls=NULL;
242 static th_list* list=NULL;
243 static pthread_mutex_t list_lock = PTHREAD_MUTEX_INITIALIZER;
245 #if 0
246 static void test_heap(void)
248 int offset=0;
249 if(heap==0)
250 return;
251 while(offset<heap_counter)
253 if(*(int*)(heap+offset)!=0x433476)
255 printf("Heap corruption at address %d\n", offset);
256 return;
258 offset+=8+*(int*)(heap+offset+4);
260 for(;offset<min(offset+1000, 20000000); offset++)
261 if(heap[offset]!=0xCC)
263 printf("Free heap corruption at address %d\n", offset);
266 #endif
267 #undef MEMORY_DEBUG
269 #ifdef MEMORY_DEBUG
271 static void* my_mreq(int size, int to_zero)
273 static int test=0;
274 test++;
275 if(test%10==0)printf("Memory: %d bytes allocated\n", heap_counter);
276 // test_heap();
277 if(heap==NULL)
279 heap=malloc(20000000);
280 memset(heap, 0xCC,20000000);
282 if(heap==0)
284 printf("No enough memory\n");
285 return 0;
287 if(heap_counter+size>20000000)
289 printf("No enough memory\n");
290 return 0;
292 *(int*)(heap+heap_counter)=0x433476;
293 heap_counter+=4;
294 *(int*)(heap+heap_counter)=size;
295 heap_counter+=4;
296 printf("Allocated %d bytes of memory: sys %d, user %d-%d\n", size, heap_counter-8, heap_counter, heap_counter+size);
297 if(to_zero)
298 memset(heap+heap_counter, 0, size);
299 else
300 memset(heap+heap_counter, 0xcc, size); // make crash reproducable
301 heap_counter+=size;
302 return heap+heap_counter-size;
304 static int my_release(char* memory)
306 // test_heap();
307 if(memory==NULL)
309 printf("ERROR: free(0)\n");
310 return 0;
312 if(*(int*)(memory-8)!=0x433476)
314 printf("MEMORY CORRUPTION !!!!!!!!!!!!!!!!!!!\n");
315 return 0;
317 printf("Freed %d bytes of memory\n", *(int*)(memory-4));
318 // memset(memory-8, *(int*)(memory-4), 0xCC);
319 return 0;
322 #else
323 #define GARBAGE
324 typedef struct alloc_header_t alloc_header;
325 struct alloc_header_t
327 // let's keep allocated data 16 byte aligned
328 alloc_header* prev;
329 alloc_header* next;
330 long deadbeef;
331 long size;
332 long type;
333 long reserved1;
334 long reserved2;
335 long reserved3;
338 #ifdef GARBAGE
339 static alloc_header* last_alloc = NULL;
340 static int alccnt = 0;
341 #endif
343 #define AREATYPE_CLIENT 0
344 #define AREATYPE_EVENT 1
345 #define AREATYPE_MUTEX 2
346 #define AREATYPE_COND 3
347 #define AREATYPE_CRITSECT 4
349 /* -- critical sections -- */
350 struct CRITSECT
352 pthread_t id;
353 pthread_mutex_t mutex;
354 pthread_cond_t unlocked;
355 int lock_count;
356 long deadbeef;
359 void* mreq_private(int size, int to_zero, int type);
360 void* mreq_private(int size, int to_zero, int type)
362 int nsize = size + sizeof(alloc_header);
363 alloc_header* header = malloc(nsize);
364 if (!header)
365 return 0;
366 if (to_zero)
367 memset(header, 0, nsize);
368 #ifdef GARBAGE
369 if (!last_alloc)
371 pthread_mutex_init(&memmut, NULL);
372 pthread_mutex_lock(&memmut);
374 else
376 pthread_mutex_lock(&memmut);
377 last_alloc->next = header; /* set next */
380 header->prev = last_alloc;
381 header->next = 0;
382 last_alloc = header;
383 alccnt++;
384 pthread_mutex_unlock(&memmut);
385 #endif
386 header->deadbeef = 0xdeadbeef;
387 header->size = size;
388 header->type = type;
390 //if (alccnt < 40000) printf("MY_REQ: %p\t%d t:%d (cnt:%d)\n", header, size, type, alccnt);
391 return header + 1;
394 static int my_release(void* memory)
396 alloc_header* header = (alloc_header*) memory - 1;
397 #ifdef GARBAGE
398 alloc_header* prevmem;
399 alloc_header* nextmem;
401 if (memory == 0)
402 return 0;
404 if (header->deadbeef != (long) 0xdeadbeef)
406 dbgprintf("FATAL releasing corrupted memory! %p 0x%lx (%d)\n", header, header->deadbeef, alccnt);
407 return 0;
410 pthread_mutex_lock(&memmut);
412 switch(header->type)
414 case AREATYPE_EVENT:
415 destroy_event(memory);
416 break;
417 case AREATYPE_COND:
418 pthread_cond_destroy((pthread_cond_t*)memory);
419 break;
420 case AREATYPE_MUTEX:
421 pthread_mutex_destroy((pthread_mutex_t*)memory);
422 break;
423 case AREATYPE_CRITSECT:
424 pthread_mutex_destroy(&((struct CRITSECT*)memory)->mutex);
425 break;
426 default:
427 //memset(memory, 0xcc, header->size);
431 header->deadbeef = 0;
432 prevmem = header->prev;
433 nextmem = header->next;
435 if (prevmem)
436 prevmem->next = nextmem;
437 if (nextmem)
438 nextmem->prev = prevmem;
440 if (header == last_alloc)
441 last_alloc = prevmem;
443 alccnt--;
445 if (last_alloc)
446 pthread_mutex_unlock(&memmut);
447 else
448 pthread_mutex_destroy(&memmut);
450 //if (alccnt < 40000) printf("MY_RELEASE: %p\t%ld (%d)\n", header, header->size, alccnt);
451 #else
452 if (memory == 0)
453 return 0;
454 #endif
455 //memset(header + 1, 0xcc, header->size);
456 free(header);
457 return 0;
459 #endif
461 static inline void* my_mreq(int size, int to_zero)
463 return mreq_private(size, to_zero, AREATYPE_CLIENT);
466 static int my_size(void* memory)
468 if(!memory) return 0;
469 return ((alloc_header*)memory)[-1].size;
472 static void* my_realloc(void* memory, int size)
474 void *ans = memory;
475 int osize;
476 if (memory == NULL)
477 return my_mreq(size, 0);
478 osize = my_size(memory);
479 if (osize < size)
481 ans = my_mreq(size, 0);
482 memcpy(ans, memory, osize);
483 my_release(memory);
485 return ans;
490 * WINE API - native implementation for several win32 libraries
494 static int WINAPI ext_unknown(void)
496 printf("Unknown func called\n");
497 return 0;
500 static int WINAPI expGetVolumeInformationA( const char *root, char *label,
501 unsigned int label_len, unsigned int *serial,
502 unsigned int *filename_len,unsigned int *flags,
503 char *fsname, unsigned int fsname_len )
505 dbgprintf("GetVolumeInformationA( %s, 0x%x, %ld, 0x%x, 0x%x, 0x%x, 0x%x, %ld) => 1\n",
506 root,label,label_len,serial,filename_len,flags,fsname,fsname_len);
507 //hack Do not return any real data - do nothing
508 return 1;
511 static unsigned int WINAPI expGetDriveTypeA( const char *root )
513 dbgprintf("GetDriveTypeA( %s ) => %d\n",root,DRIVE_FIXED);
514 // hack return as Fixed Drive Type
515 return DRIVE_FIXED;
518 static unsigned int WINAPI expGetLogicalDriveStringsA( unsigned int len, char *buffer )
520 dbgprintf("GetLogicalDriveStringsA(%d, 0x%x) => 4\n",len,buffer);
521 // hack only have one drive c:\ in this hack
522 *buffer++='c';
523 *buffer++=':';
524 *buffer++='\\';
525 *buffer++='\0';
526 *buffer= '\0';
527 return 4; // 1 drive * 4 bytes (includes null)
531 static int WINAPI expIsBadWritePtr(void* ptr, unsigned int count)
533 int result = (count == 0 || ptr != 0) ? 0 : 1;
534 dbgprintf("IsBadWritePtr(0x%x, 0x%x) => %d\n", ptr, count, result);
535 return result;
537 static int WINAPI expIsBadReadPtr(void* ptr, unsigned int count)
539 int result = (count == 0 || ptr != 0) ? 0 : 1;
540 dbgprintf("IsBadReadPtr(0x%x, 0x%x) => %d\n", ptr, count, result);
541 return result;
543 static int WINAPI expDisableThreadLibraryCalls(int module)
545 dbgprintf("DisableThreadLibraryCalls(0x%x) => 0\n", module);
546 return 0;
549 static HMODULE WINAPI expGetDriverModuleHandle(DRVR* pdrv)
551 HMODULE result;
552 if (pdrv==NULL)
553 result=0;
554 else
555 result=pdrv->hDriverModule;
556 dbgprintf("GetDriverModuleHandle(%p) => %p\n", pdrv, result);
557 return result;
560 #define MODULE_HANDLE_kernel32 ((HMODULE)0x120)
561 #define MODULE_HANDLE_user32 ((HMODULE)0x121)
562 #ifdef CONFIG_QTX_CODECS
563 #define MODULE_HANDLE_wininet ((HMODULE)0x122)
564 #define MODULE_HANDLE_ddraw ((HMODULE)0x123)
565 #define MODULE_HANDLE_advapi32 ((HMODULE)0x124)
566 #endif
567 #define MODULE_HANDLE_comdlg32 ((HMODULE)0x125)
568 #define MODULE_HANDLE_msvcrt ((HMODULE)0x126)
569 #define MODULE_HANDLE_ole32 ((HMODULE)0x127)
570 #define MODULE_HANDLE_winmm ((HMODULE)0x128)
571 #define MODULE_HANDLE_psapi ((HMODULE)0x129)
573 // Fake PE header, since some software (and the Microsoft CRT v8 and newer)
574 // assume GetModuleHandle(NULL) returns a pointer to a PE header.
575 // We simulate a very simple header with only one section.
577 // NOTE: If you have a section called .mixcrt, the Microsoft CRT will assume
578 // it's running in a POSIX binary, and stop using EncodePointer/DecodePointer.
579 static const struct {
580 IMAGE_DOS_HEADER doshdr;
581 IMAGE_NT_HEADERS nthdr;
582 IMAGE_SECTION_HEADER opthdr;
583 } __attribute__((__packed__)) mp_exe = {
584 .doshdr.e_lfanew = sizeof(IMAGE_DOS_HEADER),
585 .nthdr.FileHeader.NumberOfSections = 1,
586 .nthdr.FileHeader.SizeOfOptionalHeader =
587 sizeof(IMAGE_NT_HEADERS) - FIELD_OFFSET(IMAGE_NT_HEADERS, OptionalHeader), /* 0xe0 */
588 .opthdr.Name = ".text"
591 static HMODULE WINAPI expGetModuleHandleA(const char* name)
593 WINE_MODREF* wm;
594 HMODULE result;
595 if(!name)
596 result=(HMODULE)&mp_exe.doshdr;
597 else
599 wm=MODULE_FindModule(name);
600 if(wm==0)result=0;
601 else
602 result=(HMODULE)(wm->module);
604 if(!result)
606 if(name && (strcasecmp(name, "kernel32")==0 || !strcasecmp(name, "kernel32.dll")))
607 result=MODULE_HANDLE_kernel32;
608 #ifdef CONFIG_QTX_CODECS
609 if(name && strcasecmp(name, "user32")==0)
610 result=MODULE_HANDLE_user32;
611 #endif
613 dbgprintf("GetModuleHandleA('%s') => 0x%x\n", name, result);
614 return result;
617 static HMODULE WINAPI expGetModuleHandleW(const uint16_t* name)
619 char aname[256];
620 int pos = 0;
621 while (*name) {
622 if (*name > 256 || pos >= sizeof(aname) - 1)
623 return NULL;
624 aname[pos++] = *name++;
626 aname[pos] = 0;
627 return expGetModuleHandleA(aname);
630 static void* WINAPI expCreateThread(void* pSecAttr, long dwStackSize,
631 void* lpStartAddress, void* lpParameter,
632 long dwFlags, long* dwThreadId)
634 pthread_t *pth;
635 // printf("CreateThread:");
636 pth = (pthread_t*) my_mreq(sizeof(pthread_t), 0);
637 pthread_create(pth, NULL, (void*(*)(void*))lpStartAddress, lpParameter);
638 if(dwFlags)
639 printf( "WARNING: CreateThread flags not supported\n");
640 if(dwThreadId)
641 *dwThreadId=(long)pth;
642 pthread_mutex_lock(&list_lock);
643 if(list==NULL)
645 list=my_mreq(sizeof(th_list), 1);
646 list->next=list->prev=NULL;
648 else
650 list->next=my_mreq(sizeof(th_list), 0);
651 list->next->prev=list;
652 list->next->next=NULL;
653 list=list->next;
655 list->thread=pth;
656 pthread_mutex_unlock(&list_lock);
657 dbgprintf("CreateThread(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x) => 0x%x\n",
658 pSecAttr, dwStackSize, lpStartAddress, lpParameter, dwFlags, dwThreadId, pth);
659 return pth;
662 static DWORD WINAPI expResumeThread(HANDLE hThread)
664 int ret = 1;
665 dbgprintf("ResumeThread(0x%x) => 0x%x\n", hThread, ret);
666 return ret;
669 struct mutex_list_t;
671 struct mutex_list_t
673 char type;
674 pthread_mutex_t *pm;
675 pthread_cond_t *pc;
676 char state;
677 char reset;
678 char name[128];
679 int semaphore;
680 int lock_count;
681 pthread_t owner;
682 struct mutex_list_t* next;
683 struct mutex_list_t* prev;
685 typedef struct mutex_list_t mutex_list;
686 static mutex_list* mlist=NULL;
687 static pthread_mutex_t mlist_lock = PTHREAD_MUTEX_INITIALIZER;
689 void destroy_event(void* event)
691 pthread_mutex_lock(&mlist_lock);
692 mutex_list* pp=mlist;
693 // printf("garbage collector: destroy_event(%x)\n", event);
694 while(pp)
696 if(pp==(mutex_list*)event)
698 if(pp->next)
699 pp->next->prev=pp->prev;
700 if(pp->prev)
701 pp->prev->next=pp->next;
702 if(mlist==(mutex_list*)event)
703 mlist=mlist->prev;
705 pp=mlist;
706 while(pp)
708 printf("%x => ", pp);
709 pp=pp->prev;
711 printf("0\n");
713 pthread_mutex_unlock(&mlist_lock);
714 return;
716 pp=pp->prev;
718 pthread_mutex_unlock(&mlist_lock);
721 static void* WINAPI expCreateEventA(void* pSecAttr, char bManualReset,
722 char bInitialState, const char* name)
724 pthread_mutex_t *pm;
725 pthread_cond_t *pc;
726 void *ret;
728 mutex_list* pp;
729 pp=mlist;
730 while(pp)
732 printf("%x => ", pp);
733 pp=pp->prev;
735 printf("0\n");
737 pthread_mutex_lock(&mlist_lock);
738 if(mlist!=NULL)
740 mutex_list* pp=mlist;
741 if(name!=NULL)
744 if((strcmp(pp->name, name)==0) && (pp->type==0))
746 dbgprintf("CreateEventA(0x%x, 0x%x, 0x%x, 0x%x='%s') => 0x%x\n",
747 pSecAttr, bManualReset, bInitialState, name, name, pp->pm);
748 pthread_mutex_unlock(&mlist_lock);
749 return pp->pm;
751 }while((pp=pp->prev) != NULL);
753 pm=mreq_private(sizeof(pthread_mutex_t), 0, AREATYPE_MUTEX);
754 pthread_mutex_init(pm, NULL);
755 pc=mreq_private(sizeof(pthread_cond_t), 0, AREATYPE_COND);
756 pthread_cond_init(pc, NULL);
757 if(mlist==NULL)
759 mlist=mreq_private(sizeof(mutex_list), 00, AREATYPE_EVENT);
760 mlist->next=mlist->prev=NULL;
762 else
764 mlist->next=mreq_private(sizeof(mutex_list), 00, AREATYPE_EVENT);
765 mlist->next->prev=mlist;
766 mlist->next->next=NULL;
767 mlist=mlist->next;
769 mlist->type=0; /* Type Event */
770 mlist->pm=pm;
771 mlist->pc=pc;
772 mlist->state=bInitialState;
773 mlist->reset=!bManualReset;
774 if(name)
775 strncpy(mlist->name, name, 127);
776 else
777 mlist->name[0]=0;
778 if(pm==NULL)
779 dbgprintf("ERROR::: CreateEventA failure\n");
781 if(bInitialState)
782 pthread_mutex_lock(pm);
784 if(name)
785 dbgprintf("CreateEventA(0x%x, 0x%x, 0x%x, 0x%x='%s') => 0x%x\n",
786 pSecAttr, bManualReset, bInitialState, name, name, mlist);
787 else
788 dbgprintf("CreateEventA(0x%x, 0x%x, 0x%x, NULL) => 0x%x\n",
789 pSecAttr, bManualReset, bInitialState, mlist);
790 ret = mlist;
791 pthread_mutex_unlock(&mlist_lock);
792 return ret;
795 static void* WINAPI expSetEvent(void* event)
797 mutex_list *ml = (mutex_list *)event;
798 dbgprintf("SetEvent(%x) => 0x1\n", event);
799 pthread_mutex_lock(ml->pm);
800 if (ml->state == 0) {
801 ml->state = 1;
802 pthread_cond_signal(ml->pc);
804 pthread_mutex_unlock(ml->pm);
806 return (void *)1;
808 static void* WINAPI expResetEvent(void* event)
810 mutex_list *ml = (mutex_list *)event;
811 dbgprintf("ResetEvent(0x%x) => 0x1\n", event);
812 pthread_mutex_lock(ml->pm);
813 ml->state = 0;
814 pthread_mutex_unlock(ml->pm);
816 return (void *)1;
819 static void* WINAPI expWaitForSingleObject(void* object, int duration)
821 mutex_list *ml = (mutex_list *)object;
822 // FIXME FIXME FIXME - this value is sometime unititialize !!!
823 int ret = WAIT_FAILED;
824 mutex_list* pp;
825 th_list* tp;
826 if(object == (void*)0xcfcf9898)
829 From GetCurrentThread() documentation:
830 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.
832 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.
834 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.
836 dbgprintf("WaitForSingleObject(thread_handle) called\n");
837 return (void*)WAIT_FAILED;
839 dbgprintf("WaitForSingleObject(0x%x, duration %d) =>\n",object, duration);
841 // See if this is a thread.
842 pthread_mutex_lock(&list_lock);
843 tp=list;
844 while (tp && (tp->thread != object))
845 tp = tp->prev;
846 pthread_mutex_unlock(&list_lock);
847 if (tp) {
848 if (pthread_join(*(pthread_t*)object, NULL) == 0) {
849 return (void*)WAIT_OBJECT_0;
850 } else {
851 return (void*)WAIT_FAILED;
855 // loop below was slightly fixed - its used just for checking if
856 // this object really exists in our list
857 if (!ml)
858 return (void*) ret;
859 pthread_mutex_lock(&mlist_lock);
860 pp=mlist;
861 while (pp && (pp->pm != ml->pm))
862 pp = pp->prev;
863 pthread_mutex_unlock(&mlist_lock);
864 if (!pp) {
865 dbgprintf("WaitForSingleObject: NotFound\n");
866 return (void*)ret;
869 pthread_mutex_lock(ml->pm);
871 switch(ml->type) {
872 case 0: /* Event */
873 if (duration == 0) { /* Check Only */
874 if (ml->state == 1) ret = WAIT_OBJECT_0;
875 else ret = WAIT_FAILED;
877 if (duration == -1) { /* INFINITE */
878 if (ml->state == 0)
879 pthread_cond_wait(ml->pc,ml->pm);
880 if (ml->reset)
881 ml->state = 0;
882 ret = WAIT_OBJECT_0;
884 if (duration > 0) { /* Timed Wait */
885 struct timespec abstime;
886 struct timeval now;
887 gettimeofday(&now, 0);
888 abstime.tv_sec = now.tv_sec + (now.tv_usec+duration)/1000000;
889 abstime.tv_nsec = ((now.tv_usec+duration)%1000000)*1000;
890 if (ml->state == 0)
891 ret=pthread_cond_timedwait(ml->pc,ml->pm,&abstime);
892 if (ret == ETIMEDOUT) ret = WAIT_TIMEOUT;
893 else ret = WAIT_OBJECT_0;
894 if (ml->reset)
895 ml->state = 0;
897 break;
898 case 1: /* Semaphore */
899 if (duration == 0) {
900 if(ml->semaphore==0) ret = WAIT_FAILED;
901 else {
902 ml->semaphore--;
903 ret = WAIT_OBJECT_0;
906 if (duration == -1) {
907 if (ml->semaphore==0)
908 pthread_cond_wait(ml->pc,ml->pm);
909 ml->semaphore--;
910 ret = WAIT_OBJECT_0;
912 break;
913 case 2: /* Mutex */
914 if (duration == 0) {
915 if(ml->lock_count > 0 && ml->owner != pthread_self()) ret = WAIT_FAILED;
916 else {
917 ml->lock_count++;
918 ml->owner = pthread_self();
919 ret = WAIT_OBJECT_0;
922 if (duration == -1) {
923 if (ml->lock_count > 0 && ml->owner != pthread_self()) {
924 pthread_cond_wait(ml->pc,ml->pm);
926 ml->lock_count++;
927 ml->owner = pthread_self();
928 ret = WAIT_OBJECT_0;
930 break;
932 pthread_mutex_unlock(ml->pm);
934 dbgprintf("WaitForSingleObject(0x%x, %d): 0x%x => 0x%x \n",object,duration,ml,ret);
935 return (void *)ret;
938 #ifdef CONFIG_QTX_CODECS
939 static void* WINAPI expWaitForMultipleObjects(int count, const void** objects,
940 int WaitAll, int duration)
942 int i;
943 void *object;
944 void *ret;
946 dbgprintf("WaitForMultipleObjects(%d, 0x%x, %d, duration %d) =>\n",
947 count, objects, WaitAll, duration);
949 for (i = 0; i < count; i++)
951 object = (void *)objects[i];
952 ret = expWaitForSingleObject(object, duration);
953 if (WaitAll)
954 dbgprintf("WaitAll flag not yet supported...\n");
955 else
956 return ret;
958 return NULL;
961 static void WINAPI expExitThread(int retcode)
963 dbgprintf("ExitThread(%d)\n", retcode);
964 pthread_exit(&retcode);
966 #endif
968 static int pf_set = 0;
969 static BYTE PF[64] = {0,};
971 static void DumpSystemInfo(const SYSTEM_INFO* si)
973 dbgprintf(" Processor architecture %d\n", si->u.s.wProcessorArchitecture);
974 dbgprintf(" Page size: %d\n", si->dwPageSize);
975 dbgprintf(" Minimum app address: %d\n", si->lpMinimumApplicationAddress);
976 dbgprintf(" Maximum app address: %d\n", si->lpMaximumApplicationAddress);
977 dbgprintf(" Active processor mask: 0x%x\n", si->dwActiveProcessorMask);
978 dbgprintf(" Number of processors: %d\n", si->dwNumberOfProcessors);
979 dbgprintf(" Processor type: 0x%x\n", si->dwProcessorType);
980 dbgprintf(" Allocation granularity: 0x%x\n", si->dwAllocationGranularity);
981 dbgprintf(" Processor level: 0x%x\n", si->wProcessorLevel);
982 dbgprintf(" Processor revision: 0x%x\n", si->wProcessorRevision);
985 static void WINAPI expGetSystemInfo(SYSTEM_INFO* si)
987 /* FIXME: better values for the two entries below... */
988 static int cache = 0;
989 static SYSTEM_INFO cachedsi;
990 dbgprintf("GetSystemInfo(%p) =>\n", si);
992 if (cache) {
993 goto exit;
995 memset(PF,0,sizeof(PF));
996 pf_set = 1;
998 cachedsi.u.s.wProcessorArchitecture = PROCESSOR_ARCHITECTURE_INTEL;
999 cachedsi.dwPageSize = getpagesize();
1001 /* FIXME: better values for the two entries below... */
1002 cachedsi.lpMinimumApplicationAddress = (void *)0x00000000;
1003 cachedsi.lpMaximumApplicationAddress = (void *)0x7FFFFFFF;
1004 cachedsi.dwActiveProcessorMask = 1;
1005 cachedsi.dwNumberOfProcessors = 1;
1006 cachedsi.dwProcessorType = PROCESSOR_INTEL_386;
1007 cachedsi.dwAllocationGranularity = 0x10000;
1008 cachedsi.wProcessorLevel = 5; /* pentium */
1009 cachedsi.wProcessorRevision = 0x0101;
1011 /* mplayer's way to detect PF's */
1013 #include "cpudetect.h"
1015 if (gCpuCaps.hasMMX)
1016 PF[PF_MMX_INSTRUCTIONS_AVAILABLE] = TRUE;
1017 if (gCpuCaps.hasSSE)
1018 PF[PF_XMMI_INSTRUCTIONS_AVAILABLE] = TRUE;
1019 if (gCpuCaps.hasSSE2)
1020 PF[PF_XMMI64_INSTRUCTIONS_AVAILABLE] = TRUE;
1021 if (gCpuCaps.has3DNow)
1022 PF[PF_AMD3D_INSTRUCTIONS_AVAILABLE] = TRUE;
1024 if (gCpuCaps.cpuType == 4)
1026 cachedsi.dwProcessorType = PROCESSOR_INTEL_486;
1027 cachedsi.wProcessorLevel = 4;
1029 else if (gCpuCaps.cpuType >= 5)
1031 cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
1032 cachedsi.wProcessorLevel = 5;
1034 else
1036 cachedsi.dwProcessorType = PROCESSOR_INTEL_386;
1037 cachedsi.wProcessorLevel = 3;
1039 cachedsi.wProcessorRevision = gCpuCaps.cpuStepping;
1040 cachedsi.dwNumberOfProcessors = 1; /* hardcoded */
1043 /* MPlayer: linux detection enabled (based on proc/cpuinfo) for checking
1044 fdiv_bug and fpu emulation flags -- alex/MPlayer */
1045 #ifdef __linux__
1047 char buf[20];
1048 char line[200];
1049 FILE *f = fopen ("/proc/cpuinfo", "r");
1051 if (!f)
1053 mp_msg(MSGT_WIN32, MSGL_WARN, "expGetSystemInfo: "
1054 "/proc/cpuinfo not readable! "
1055 "Expect bad performance and/or weird behaviour\n");
1056 goto exit;
1058 while (fgets(line,200,f)!=NULL) {
1059 char *s,*value;
1061 /* NOTE: the ':' is the only character we can rely on */
1062 if (!(value = strchr(line,':')))
1063 continue;
1064 /* terminate the valuename */
1065 *value++ = '\0';
1066 /* skip any leading spaces */
1067 while (*value==' ') value++;
1068 if ((s=strchr(value,'\n')))
1069 *s='\0';
1071 /* 2.1 method */
1072 if (!lstrncmpiA(line, "cpu family",strlen("cpu family"))) {
1073 if (isdigit (value[0])) {
1074 switch (value[0] - '0') {
1075 case 3: cachedsi.dwProcessorType = PROCESSOR_INTEL_386;
1076 cachedsi.wProcessorLevel= 3;
1077 break;
1078 case 4: cachedsi.dwProcessorType = PROCESSOR_INTEL_486;
1079 cachedsi.wProcessorLevel= 4;
1080 break;
1081 case 5: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
1082 cachedsi.wProcessorLevel= 5;
1083 break;
1084 case 6: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
1085 cachedsi.wProcessorLevel= 5;
1086 break;
1087 default:cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
1088 cachedsi.wProcessorLevel= 5;
1089 break;
1092 /* set the CPU type of the current processor */
1093 sprintf(buf,"CPU %ld",cachedsi.dwProcessorType);
1094 continue;
1096 /* old 2.0 method */
1097 if (!lstrncmpiA(line, "cpu",strlen("cpu"))) {
1098 if ( isdigit (value[0]) && value[1] == '8' &&
1099 value[2] == '6' && value[3] == 0
1101 switch (value[0] - '0') {
1102 case 3: cachedsi.dwProcessorType = PROCESSOR_INTEL_386;
1103 cachedsi.wProcessorLevel= 3;
1104 break;
1105 case 4: cachedsi.dwProcessorType = PROCESSOR_INTEL_486;
1106 cachedsi.wProcessorLevel= 4;
1107 break;
1108 case 5: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
1109 cachedsi.wProcessorLevel= 5;
1110 break;
1111 case 6: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
1112 cachedsi.wProcessorLevel= 5;
1113 break;
1114 default:cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
1115 cachedsi.wProcessorLevel= 5;
1116 break;
1119 /* set the CPU type of the current processor */
1120 sprintf(buf,"CPU %ld",cachedsi.dwProcessorType);
1121 continue;
1123 if (!lstrncmpiA(line,"fdiv_bug",strlen("fdiv_bug"))) {
1124 if (!lstrncmpiA(value,"yes",3))
1125 PF[PF_FLOATING_POINT_PRECISION_ERRATA] = TRUE;
1127 continue;
1129 if (!lstrncmpiA(line,"fpu",strlen("fpu"))) {
1130 if (!lstrncmpiA(value,"no",2))
1131 PF[PF_FLOATING_POINT_EMULATED] = TRUE;
1133 continue;
1135 if (!lstrncmpiA(line,"processor",strlen("processor"))) {
1136 /* processor number counts up...*/
1137 unsigned int x;
1139 if (sscanf(value,"%d",&x))
1140 if (x+1>cachedsi.dwNumberOfProcessors)
1141 cachedsi.dwNumberOfProcessors=x+1;
1143 /* Create a new processor subkey on a multiprocessor
1144 * system
1146 sprintf(buf,"%d",x);
1148 if (!lstrncmpiA(line,"stepping",strlen("stepping"))) {
1149 int x;
1151 if (sscanf(value,"%d",&x))
1152 cachedsi.wProcessorRevision = x;
1155 ( (!lstrncmpiA(line,"flags",strlen("flags")))
1156 || (!lstrncmpiA(line,"features",strlen("features"))) )
1158 if (strstr(value,"cx8"))
1159 PF[PF_COMPARE_EXCHANGE_DOUBLE] = TRUE;
1160 if (strstr(value,"mmx"))
1161 PF[PF_MMX_INSTRUCTIONS_AVAILABLE] = TRUE;
1162 if (strstr(value,"tsc"))
1163 PF[PF_RDTSC_INSTRUCTION_AVAILABLE] = TRUE;
1164 if (strstr(value,"xmm") || strstr(value,"sse"))
1165 PF[PF_XMMI_INSTRUCTIONS_AVAILABLE] = TRUE;
1166 if (strstr(value,"sse2"))
1167 PF[PF_XMMI64_INSTRUCTIONS_AVAILABLE] = TRUE;
1168 if (strstr(value,"3dnow"))
1169 PF[PF_AMD3D_INSTRUCTIONS_AVAILABLE] = TRUE;
1172 fclose (f);
1174 * ad hoc fix for smp machines.
1175 * some problems on WaitForSingleObject,CreateEvent,SetEvent
1176 * CreateThread ...etc..
1179 cachedsi.dwNumberOfProcessors=1;
1181 #endif /* __linux__ */
1182 cache = 1;
1183 exit:
1184 memcpy(si,&cachedsi,sizeof(*si));
1185 DumpSystemInfo(si);
1188 // avoid undefined expGetSystemInfo
1189 static WIN_BOOL WINAPI expIsProcessorFeaturePresent(DWORD v)
1191 WIN_BOOL result = 0;
1192 if (!pf_set)
1194 SYSTEM_INFO si;
1195 expGetSystemInfo(&si);
1197 if(v<64) result=PF[v];
1198 dbgprintf("IsProcessorFeaturePresent(0x%x) => 0x%x\n", v, result);
1199 return result;
1202 static WIN_BOOL WINAPI expIsDebuggerPresent(void)
1204 return 0;
1207 static long WINAPI expGetVersion(void)
1209 dbgprintf("GetVersion() => 0xC0000004\n");
1210 return 0xC0000004;//Windows 95
1213 static HANDLE WINAPI expHeapCreate(long flags, long init_size, long max_size)
1215 // printf("HeapCreate:");
1216 HANDLE result;
1217 if(init_size==0)
1218 result=(HANDLE)my_mreq(0x110000, 0);
1219 else
1220 result=(HANDLE)my_mreq((init_size + 0xfff) & 0x7ffff000 , 0);
1221 dbgprintf("HeapCreate(flags 0x%x, initial size %d, maximum size %d) => 0x%x\n", flags, init_size, max_size, result);
1222 return result;
1225 // this is another dirty hack
1226 // VP31 is releasing one allocated Heap chunk twice
1227 // we will silently ignore this second call...
1228 static void* heapfreehack = 0;
1229 static int heapfreehackshown = 0;
1230 //void trapbug(void);
1231 static void* WINAPI expHeapAlloc(HANDLE heap, int flags, int size)
1233 void* z;
1235 Morgan's m3jpeg32.dll v. 2.0 encoder expects that request for
1236 HeapAlloc returns area larger than size argument :-/
1238 actually according to M$ Doc HeapCreate size should be rounded
1239 to page boundaries thus we should simulate this
1241 //if (size == 22276) trapbug();
1242 z=my_mreq((size + 0xfff) & 0x7ffff000, (flags & HEAP_ZERO_MEMORY));
1243 if(z==0)
1244 printf("HeapAlloc failure\n");
1245 dbgprintf("HeapAlloc(heap 0x%x, flags 0x%x, size %d) => 0x%x\n", heap, flags, size, z);
1246 heapfreehack = 0; // reset
1247 return z;
1249 static long WINAPI expHeapDestroy(void* heap)
1251 dbgprintf("HeapDestroy(heap 0x%x) => 1\n", heap);
1252 my_release(heap);
1253 return 1;
1256 static long WINAPI expHeapFree(HANDLE heap, DWORD dwFlags, LPVOID lpMem)
1258 dbgprintf("HeapFree(0x%x, 0x%x, pointer 0x%x) => 1\n", heap, dwFlags, lpMem);
1259 if (heapfreehack != lpMem && lpMem != (void*)0xffffffff
1260 && lpMem != (void*)0xbdbdbdbd)
1261 // 0xbdbdbdbd is for i263_drv.drv && libefence
1262 // it seems to be reading from relased memory
1263 // EF_PROTECT_FREE doens't show any probleme
1264 my_release(lpMem);
1265 else
1267 if (!heapfreehackshown++)
1268 printf("Info: HeapFree deallocating same memory twice! (%p)\n", lpMem);
1270 heapfreehack = lpMem;
1271 return 1;
1273 static long WINAPI expHeapSize(int heap, int flags, void* pointer)
1275 long result=my_size(pointer);
1276 dbgprintf("HeapSize(heap 0x%x, flags 0x%x, pointer 0x%x) => %d\n", heap, flags, pointer, result);
1277 return result;
1279 static void* WINAPI expHeapReAlloc(HANDLE heap,int flags,void *lpMem,int size)
1281 long orgsize = my_size(lpMem);
1282 dbgprintf("HeapReAlloc() Size %ld org %d\n",orgsize,size);
1283 return my_realloc(lpMem, size);
1285 static long WINAPI expGetProcessHeap(void)
1287 dbgprintf("GetProcessHeap() => 1\n");
1288 return 1;
1290 static void* WINAPI expVirtualAlloc(void* v1, long v2, long v3, long v4)
1292 void* z = VirtualAlloc(v1, v2, v3, v4);
1293 if(z==0)
1294 printf("VirtualAlloc failure\n");
1295 dbgprintf("VirtualAlloc(0x%x, %d, %d, %d) => 0x%x \n",v1,v2,v3,v4, z);
1296 return z;
1298 static int WINAPI expVirtualFree(void* v1, int v2, int v3)
1300 int result = VirtualFree(v1,v2,v3);
1301 dbgprintf("VirtualFree(0x%x, %d, %d) => %d\n",v1,v2,v3, result);
1302 return result;
1305 /* we're building a table of critical sections. cs_win pointer uses the DLL
1306 cs_unix is the real structure, we're using cs_win only to identifying cs_unix */
1307 struct critsecs_list_t
1309 CRITICAL_SECTION *cs_win;
1310 struct CRITSECT *cs_unix;
1313 /* 'NEWTYPE' is working with VIVO, 3ivX and QTX dll (no more segfaults) -- alex */
1314 #undef CRITSECS_NEWTYPE
1315 //#define CRITSECS_NEWTYPE 1
1317 #ifdef CRITSECS_NEWTYPE
1318 /* increased due to ucod needs more than 32 entries */
1319 /* and 64 should be enough for everything */
1320 #define CRITSECS_LIST_MAX 64
1321 static struct critsecs_list_t critsecs_list[CRITSECS_LIST_MAX];
1323 static int critsecs_get_pos(CRITICAL_SECTION *cs_win)
1325 int i;
1327 for (i=0; i < CRITSECS_LIST_MAX; i++)
1328 if (critsecs_list[i].cs_win == cs_win)
1329 return i;
1330 return -1;
1333 static int critsecs_get_unused(void)
1335 int i;
1337 for (i=0; i < CRITSECS_LIST_MAX; i++)
1338 if (critsecs_list[i].cs_win == NULL)
1339 return i;
1340 return -1;
1343 struct CRITSECT *critsecs_get_unix(CRITICAL_SECTION *cs_win)
1345 int i;
1347 for (i=0; i < CRITSECS_LIST_MAX; i++)
1348 if (critsecs_list[i].cs_win == cs_win && critsecs_list[i].cs_unix)
1349 return critsecs_list[i].cs_unix;
1350 return NULL;
1352 #endif
1354 static void WINAPI expInitializeCriticalSection(CRITICAL_SECTION* c)
1356 dbgprintf("InitializeCriticalSection(0x%x)\n", c);
1357 /* if(sizeof(pthread_mutex_t)>sizeof(CRITICAL_SECTION))
1359 printf(" ERROR:::: sizeof(pthread_mutex_t) is %d, expected <=%d!\n",
1360 sizeof(pthread_mutex_t), sizeof(CRITICAL_SECTION));
1361 return;
1363 /* pthread_mutex_init((pthread_mutex_t*)c, NULL); */
1364 #ifdef CRITSECS_NEWTYPE
1366 struct CRITSECT *cs;
1367 int i = critsecs_get_unused();
1369 if (i < 0)
1371 printf("InitializeCriticalSection(%p) - no more space in list\n", c);
1372 return;
1374 dbgprintf("got unused space at %d\n", i);
1375 cs = malloc(sizeof(struct CRITSECT));
1376 if (!cs)
1378 printf("InitializeCriticalSection(%p) - out of memory\n", c);
1379 return;
1381 pthread_mutex_init(&cs->mutex, NULL);
1382 pthread_cond_init(&cs->unlocked, NULL);
1383 cs->lock_count = 0;
1384 critsecs_list[i].cs_win = c;
1385 critsecs_list[i].cs_unix = cs;
1386 dbgprintf("InitializeCriticalSection -> itemno=%d, cs_win=%p, cs_unix=%p\n",
1387 i, c, cs);
1389 #else
1391 struct CRITSECT* cs = mreq_private(sizeof(struct CRITSECT) + sizeof(CRITICAL_SECTION),
1392 0, AREATYPE_CRITSECT);
1393 pthread_mutex_init(&cs->mutex, NULL);
1394 pthread_cond_init(&cs->unlocked, NULL);
1395 cs->lock_count = 0;
1396 cs->deadbeef = 0xdeadbeef;
1397 *(void**)c = cs;
1399 #endif
1400 return;
1403 static void WINAPI expInitializeCriticalSectionAndSpinCount(CRITICAL_SECTION* c, DWORD spin)
1405 expInitializeCriticalSection(c);
1408 static void WINAPI expEnterCriticalSection(CRITICAL_SECTION* c)
1410 #ifdef CRITSECS_NEWTYPE
1411 struct CRITSECT* cs = critsecs_get_unix(c);
1412 #else
1413 struct CRITSECT* cs = (*(struct CRITSECT**)c);
1414 #endif
1415 dbgprintf("EnterCriticalSection(0x%x) %p\n",c, cs);
1416 if (!cs)
1418 dbgprintf("entered uninitialized critisec!\n");
1419 expInitializeCriticalSection(c);
1420 #ifdef CRITSECS_NEWTYPE
1421 cs=critsecs_get_unix(c);
1422 #else
1423 cs = (*(struct CRITSECT**)c);
1424 #endif
1425 dbgprintf("Win32 Warning: Accessed uninitialized Critical Section (%p)!\n", c);
1427 pthread_mutex_lock(&(cs->mutex));
1428 if (cs->lock_count > 0 && cs->id == pthread_self()) {
1429 cs->lock_count++;
1430 } else {
1431 while (cs->lock_count != 0) {
1432 pthread_cond_wait(&(cs->unlocked), &(cs->mutex));
1434 cs->lock_count = 1;
1435 cs->id = pthread_self();
1437 pthread_mutex_unlock(&(cs->mutex));
1438 return;
1440 static void WINAPI expLeaveCriticalSection(CRITICAL_SECTION* c)
1442 #ifdef CRITSECS_NEWTYPE
1443 struct CRITSECT* cs = critsecs_get_unix(c);
1444 #else
1445 struct CRITSECT* cs = (*(struct CRITSECT**)c);
1446 #endif
1447 // struct CRITSECT* cs=(struct CRITSECT*)c;
1448 dbgprintf("LeaveCriticalSection(0x%x) 0x%x\n",c, cs);
1449 if (!cs)
1451 dbgprintf("Win32 Warning: Leaving uninitialized Critical Section %p!!\n", c);
1452 return;
1454 pthread_mutex_lock(&(cs->mutex));
1455 if (cs->lock_count == 0) {
1456 dbgprintf("Win32 Warning: Unlocking unlocked Critical Section %p!!\n", c);
1457 } else {
1458 cs->lock_count--;
1460 if (cs->lock_count == 0) {
1461 pthread_cond_signal(&(cs->unlocked));
1463 pthread_mutex_unlock(&(cs->mutex));
1464 return;
1467 static void expfree(void* mem); /* forward declaration */
1469 static void WINAPI expDeleteCriticalSection(CRITICAL_SECTION *c)
1471 #ifdef CRITSECS_NEWTYPE
1472 struct CRITSECT* cs = critsecs_get_unix(c);
1473 #else
1474 struct CRITSECT* cs= (*(struct CRITSECT**)c);
1475 #endif
1476 // struct CRITSECT* cs=(struct CRITSECT*)c;
1477 dbgprintf("DeleteCriticalSection(0x%x)\n",c);
1479 if (!cs)
1481 dbgprintf("Win32 Warning: Deleting uninitialized Critical Section %p!!\n", c);
1482 return;
1485 pthread_mutex_lock(&(cs->mutex));
1486 if (cs->lock_count > 0)
1488 dbgprintf("Win32 Warning: Deleting locked Critical Section %p!!\n", c);
1490 pthread_mutex_unlock(&(cs->mutex));
1492 #ifndef GARBAGE
1493 pthread_mutex_destroy(&(cs->mutex));
1494 pthread_cond_destroy(&(cs->unlocked));
1495 // released by GarbageCollector in my_relase otherwise
1496 #endif
1497 my_release(cs);
1498 #ifdef CRITSECS_NEWTYPE
1500 int i = critsecs_get_pos(c);
1502 if (i < 0)
1504 printf("DeleteCriticalSection(%p) error (critsec not found)\n", c);
1505 return;
1508 critsecs_list[i].cs_win = NULL;
1509 expfree(critsecs_list[i].cs_unix);
1510 critsecs_list[i].cs_unix = NULL;
1511 dbgprintf("DeleteCriticalSection -> itemno=%d\n", i);
1513 #endif
1514 return;
1516 static int WINAPI expGetCurrentThreadId(void)
1518 dbgprintf("GetCurrentThreadId() => %d\n", pthread_self());
1519 return pthread_self();
1521 static int WINAPI expGetCurrentProcess(void)
1523 dbgprintf("GetCurrentProcess() => %d\n", getpid());
1524 return getpid();
1527 #ifdef CONFIG_QTX_CODECS
1528 // this version is required for Quicktime codecs (.qtx/.qts) to work.
1529 // (they assume some pointers at FS: segment)
1531 extern void* fs_seg;
1533 //static int tls_count;
1534 static int tls_use_map[64];
1535 static int WINAPI expTlsAlloc(void)
1537 int i;
1538 for(i=0; i<64; i++)
1539 if(tls_use_map[i]==0)
1541 tls_use_map[i]=1;
1542 dbgprintf("TlsAlloc() => %d\n",i);
1543 return i;
1545 dbgprintf("TlsAlloc() => -1 (ERROR)\n");
1546 return -1;
1549 //static int WINAPI expTlsSetValue(DWORD index, void* value)
1550 static int WINAPI expTlsSetValue(int index, void* value)
1552 dbgprintf("TlsSetValue(%d,0x%x) => 1\n",index,value);
1553 // if((index<0) || (index>64))
1554 if((index>=64))
1555 return 0;
1556 *(void**)((char*)fs_seg+0x88+4*index) = value;
1557 return 1;
1560 static void* WINAPI expTlsGetValue(DWORD index)
1562 dbgprintf("TlsGetValue(%d)\n",index);
1563 // if((index<0) || (index>64))
1564 if((index>=64)) return NULL;
1565 return *(void**)((char*)fs_seg+0x88+4*index);
1568 static int WINAPI expTlsFree(int idx)
1570 int index = (int) idx;
1571 dbgprintf("TlsFree(%d)\n",index);
1572 if((index<0) || (index>64))
1573 return 0;
1574 tls_use_map[index]=0;
1575 return 1;
1578 #else
1579 struct tls_s {
1580 void* value;
1581 int used;
1582 struct tls_s* prev;
1583 struct tls_s* next;
1586 static void* WINAPI expTlsAlloc(void)
1588 if (g_tls == NULL)
1590 g_tls=my_mreq(sizeof(tls_t), 0);
1591 g_tls->next=g_tls->prev=NULL;
1593 else
1595 g_tls->next=my_mreq(sizeof(tls_t), 0);
1596 g_tls->next->prev=g_tls;
1597 g_tls->next->next=NULL;
1598 g_tls=g_tls->next;
1600 dbgprintf("TlsAlloc() => 0x%x\n", g_tls);
1601 if (g_tls)
1602 g_tls->value=0; /* XXX For Divx.dll */
1603 return g_tls;
1606 static int WINAPI expTlsSetValue(void* idx, void* value)
1608 tls_t* index = (tls_t*) idx;
1609 int result;
1610 if(index==0)
1611 result=0;
1612 else
1614 index->value=value;
1615 result=1;
1617 dbgprintf("TlsSetValue(index 0x%x, value 0x%x) => %d \n", index, value, result );
1618 return result;
1620 static void* WINAPI expTlsGetValue(void* idx)
1622 tls_t* index = (tls_t*) idx;
1623 void* result;
1624 if(index==0)
1625 result=0;
1626 else
1627 result=index->value;
1628 dbgprintf("TlsGetValue(index 0x%x) => 0x%x\n", index, result);
1629 return result;
1631 static int WINAPI expTlsFree(void* idx)
1633 tls_t* index = (tls_t*) idx;
1634 int result;
1635 if(index==0)
1636 result=0;
1637 else
1639 if(index->next)
1640 index->next->prev=index->prev;
1641 if(index->prev)
1642 index->prev->next=index->next;
1643 if (g_tls == index)
1644 g_tls = index->prev;
1645 my_release((void*)index);
1646 result=1;
1648 dbgprintf("TlsFree(index 0x%x) => %d\n", index, result);
1649 return result;
1651 #endif
1653 static void* WINAPI expLocalAlloc(int flags, int size)
1655 void* z = my_mreq(size, (flags & GMEM_ZEROINIT));
1656 if (z == 0)
1657 printf("LocalAlloc() failed\n");
1658 dbgprintf("LocalAlloc(%d, flags 0x%x) => 0x%x\n", size, flags, z);
1659 return z;
1662 static void* WINAPI expLocalReAlloc(int handle,int size, int flags)
1664 void *newpointer;
1665 int oldsize;
1667 newpointer=NULL;
1668 if (flags & LMEM_MODIFY) {
1669 dbgprintf("LocalReAlloc MODIFY\n");
1670 return (void *)handle;
1672 oldsize = my_size((void *)handle);
1673 newpointer = my_realloc((void *)handle,size);
1674 dbgprintf("LocalReAlloc(%x %d(old %d), flags 0x%x) => 0x%x\n", handle,size,oldsize, flags,newpointer);
1676 return newpointer;
1679 static void* WINAPI expLocalLock(void* z)
1681 dbgprintf("LocalLock(0x%x) => 0x%x\n", z, z);
1682 return z;
1685 static void* WINAPI expGlobalAlloc(int flags, int size)
1687 void* z;
1688 dbgprintf("GlobalAlloc(%d, flags 0x%X)\n", size, flags);
1690 z=my_mreq(size, (flags & GMEM_ZEROINIT));
1691 //z=calloc(size, 1);
1692 //z=malloc(size);
1693 if(z==0)
1694 printf("GlobalAlloc() failed\n");
1695 dbgprintf("GlobalAlloc(%d, flags 0x%x) => 0x%x\n", size, flags, z);
1696 return z;
1698 static void* WINAPI expGlobalLock(void* z)
1700 dbgprintf("GlobalLock(0x%x) => 0x%x\n", z, z);
1701 return z;
1703 // pvmjpg20 - but doesn't work anyway
1704 static int WINAPI expGlobalSize(void* amem)
1706 int size = 100000;
1707 #ifdef GARBAGE
1708 alloc_header* header = last_alloc;
1709 alloc_header* mem = (alloc_header*) amem - 1;
1710 if (amem == 0)
1711 return 0;
1712 pthread_mutex_lock(&memmut);
1713 while (header)
1715 if (header->deadbeef != 0xdeadbeef)
1717 dbgprintf("FATAL found corrupted memory! %p 0x%lx (%d)\n", header, header->deadbeef, alccnt);
1718 break;
1721 if (header == mem)
1723 size = header->size;
1724 break;
1727 header = header->prev;
1729 pthread_mutex_unlock(&memmut);
1730 #endif
1732 dbgprintf("GlobalSize(0x%x)\n", amem);
1733 return size;
1736 static int WINAPI expLoadIconA( long hinstance, char *name )
1738 dbgprintf("LoadIconA( %ld, 0x%x ) => 1\n",hinstance,name);
1739 return 1;
1742 static int WINAPI expLoadStringA(long instance, long id, void* buf, long size)
1744 int result=LoadStringA(instance, id, buf, size);
1745 // if(buf)
1746 dbgprintf("LoadStringA(instance 0x%x, id 0x%x, buffer 0x%x, size %d) => %d ( %s )\n",
1747 instance, id, buf, size, result, buf);
1748 // else
1749 // dbgprintf("LoadStringA(instance 0x%x, id 0x%x, buffer 0x%x, size %d) => %d\n",
1750 // instance, id, buf, size, result);
1751 return result;
1754 static long WINAPI expMultiByteToWideChar(long v1, long v2, char* s1, long siz1, short* s2, int siz2)
1756 #warning FIXME
1757 int i;
1758 int result;
1759 if(s2==0)
1760 result=1;
1761 else
1763 if(siz1>siz2/2)siz1=siz2/2;
1764 for(i=1; i<=siz1; i++)
1766 *s2=*s1;
1767 if(!*s1)break;
1768 s2++;
1769 s1++;
1771 result=i;
1773 if(s1)
1774 dbgprintf("MultiByteToWideChar(codepage %d, flags 0x%x, string 0x%x='%s',"
1775 "size %d, dest buffer 0x%x, dest size %d) => %d\n",
1776 v1, v2, s1, s1, siz1, s2, siz2, result);
1777 else
1778 dbgprintf("MultiByteToWideChar(codepage %d, flags 0x%x, string NULL,"
1779 "size %d, dest buffer 0x%x, dest size %d) =>\n",
1780 v1, v2, siz1, s2, siz2, result);
1781 return result;
1783 static void wch_print(const short* str)
1785 dbgprintf(" src: ");
1786 while(*str)dbgprintf("%c", *str++);
1787 dbgprintf("\n");
1789 static long WINAPI expWideCharToMultiByte(long v1, long v2, short* s1, long siz1,
1790 char* s2, int siz2, char* c3, int* siz3)
1792 int result;
1793 dbgprintf("WideCharToMultiByte(codepage %d, flags 0x%x, src 0x%x, src size %d, "
1794 "dest 0x%x, dest size %d, defch 0x%x, used_defch 0x%x)", v1, v2, s1, siz1, s2, siz2, c3, siz3);
1795 result=WideCharToMultiByte(v1, v2, s1, siz1, s2, siz2, c3, siz3);
1796 dbgprintf("=> %d\n", result);
1797 //if(s1)wch_print(s1);
1798 if(s2)dbgprintf(" dest: %s\n", s2);
1799 return result;
1801 static long WINAPI expGetVersionExA(OSVERSIONINFOA* c)
1803 dbgprintf("GetVersionExA(0x%x) => 1\n");
1804 c->dwOSVersionInfoSize=sizeof(*c);
1805 c->dwMajorVersion=4;
1806 c->dwMinorVersion=0;
1807 c->dwBuildNumber=0x4000457;
1808 #if 1
1809 // leave it here for testing win9x-only codecs
1810 c->dwPlatformId=VER_PLATFORM_WIN32_WINDOWS;
1811 strcpy(c->szCSDVersion, " B");
1812 #else
1813 c->dwPlatformId=VER_PLATFORM_WIN32_NT; // let's not make DLL assume that it can read CR* registers
1814 strcpy(c->szCSDVersion, "Service Pack 3");
1815 #endif
1816 dbgprintf(" Major version: 4\n Minor version: 0\n Build number: 0x4000457\n"
1817 " Platform Id: VER_PLATFORM_WIN32_NT\n Version string: 'Service Pack 3'\n");
1818 return 1;
1820 static HANDLE WINAPI expCreateSemaphoreA(char* v1, long init_count,
1821 long max_count, char* name)
1823 pthread_mutex_t *pm;
1824 pthread_cond_t *pc;
1825 HANDLE ret;
1827 mutex_list* pp;
1828 printf("CreateSemaphoreA(%p = %s)\n", name, (name ? name : "<null>"));
1829 pp=mlist;
1830 while(pp)
1832 printf("%p => ", pp);
1833 pp=pp->prev;
1835 printf("0\n");
1837 pthread_mutex_lock(&mlist_lock);
1838 if(mlist!=NULL)
1840 mutex_list* pp=mlist;
1841 if(name!=NULL)
1844 if((strcmp(pp->name, name)==0) && (pp->type==1))
1846 dbgprintf("CreateSemaphoreA(0x%x, init_count %d, max_count %d, name 0x%x='%s') => 0x%x\n",
1847 v1, init_count, max_count, name, name, mlist);
1848 ret = (HANDLE)mlist;
1849 pthread_mutex_unlock(&mlist_lock);
1850 return ret;
1852 }while((pp=pp->prev) != NULL);
1854 pm=mreq_private(sizeof(pthread_mutex_t), 0, AREATYPE_MUTEX);
1855 pthread_mutex_init(pm, NULL);
1856 pc=mreq_private(sizeof(pthread_cond_t), 0, AREATYPE_COND);
1857 pthread_cond_init(pc, NULL);
1858 if(mlist==NULL)
1860 mlist=mreq_private(sizeof(mutex_list), 00, AREATYPE_EVENT);
1861 mlist->next=mlist->prev=NULL;
1863 else
1865 mlist->next=mreq_private(sizeof(mutex_list), 00, AREATYPE_EVENT);
1866 mlist->next->prev=mlist;
1867 mlist->next->next=NULL;
1868 mlist=mlist->next;
1869 // printf("new semaphore %p\n", mlist);
1871 mlist->type=1; /* Type Semaphore */
1872 mlist->pm=pm;
1873 mlist->pc=pc;
1874 mlist->state=0;
1875 mlist->reset=0;
1876 mlist->semaphore=init_count;
1877 if(name!=NULL)
1878 strncpy(mlist->name, name, 64);
1879 else
1880 mlist->name[0]=0;
1881 if(pm==NULL)
1882 dbgprintf("ERROR::: CreateSemaphoreA failure\n");
1883 if(name)
1884 dbgprintf("CreateSemaphoreA(0x%x, init_count %d, max_count %d, name 0x%x='%s') => 0x%x\n",
1885 v1, init_count, max_count, name, name, mlist);
1886 else
1887 dbgprintf("CreateSemaphoreA(0x%x, init_count %d, max_count %d, name 0) => 0x%x\n",
1888 v1, init_count, max_count, mlist);
1889 ret = (HANDLE)mlist;
1890 pthread_mutex_unlock(&mlist_lock);
1891 return ret;
1894 static long WINAPI expReleaseSemaphore(long hsem, long increment, long* prev_count)
1896 // The state of a semaphore object is signaled when its count
1897 // is greater than zero and nonsignaled when its count is equal to zero
1898 // Each time a waiting thread is released because of the semaphore's signaled
1899 // state, the count of the semaphore is decreased by one.
1900 mutex_list *ml = (mutex_list *)hsem;
1902 pthread_mutex_lock(ml->pm);
1903 if (prev_count != 0) *prev_count = ml->semaphore;
1904 if (ml->semaphore == 0) pthread_cond_signal(ml->pc);
1905 ml->semaphore += increment;
1906 pthread_mutex_unlock(ml->pm);
1907 dbgprintf("ReleaseSemaphore(semaphore 0x%x, increment %d, prev_count 0x%x) => 1\n",
1908 hsem, increment, prev_count);
1909 return 1;
1912 static HANDLE WINAPI expCreateMutexA(void *pSecAttr,
1913 char bInitialOwner, const char *name)
1915 pthread_mutex_t *pm;
1916 pthread_cond_t *pc;
1917 HANDLE ret;
1918 pthread_mutex_lock(&mlist_lock);
1919 if(mlist!=NULL)
1921 mutex_list* pp=mlist;
1922 if(name!=NULL)
1925 if((strcmp(pp->name, name)==0) && (pp->type==2))
1927 dbgprintf("CreateMutexA(0x%x, %d, '%s') => 0x%x\n", pSecAttr, bInitialOwner, name, mlist);
1928 ret = (HANDLE)mlist;
1929 pthread_mutex_unlock(&mlist_lock);
1930 return ret;
1932 }while((pp=pp->prev) != NULL);
1934 pm=mreq_private(sizeof(pthread_mutex_t), 0, AREATYPE_MUTEX);
1935 pthread_mutex_init(pm, NULL);
1936 pc=mreq_private(sizeof(pthread_cond_t), 0, AREATYPE_COND);
1937 pthread_cond_init(pc, NULL);
1938 if(mlist==NULL)
1940 mlist=mreq_private(sizeof(mutex_list), 00, AREATYPE_EVENT);
1941 mlist->next=mlist->prev=NULL;
1943 else
1945 mlist->next=mreq_private(sizeof(mutex_list), 00, AREATYPE_EVENT);
1946 mlist->next->prev=mlist;
1947 mlist->next->next=NULL;
1948 mlist=mlist->next;
1950 mlist->type=2; /* Type Mutex */
1951 mlist->pm=pm;
1952 mlist->pc=pc;
1953 mlist->state=0;
1954 mlist->reset=0;
1955 mlist->semaphore=0;
1956 if (bInitialOwner) {
1957 mlist->owner = pthread_self();
1958 mlist->lock_count = 1;
1959 } else {
1960 mlist->owner = (pthread_t)0;
1961 mlist->lock_count = 0;
1963 if(name!=NULL)
1964 strncpy(mlist->name, name, 64);
1965 else
1966 mlist->name[0]=0;
1967 if(pm==NULL)
1968 dbgprintf("ERROR::: CreateMutexA failure\n");
1969 if(name)
1970 dbgprintf("CreateMutexA(0x%x, %d, '%s') => 0x%x\n",
1971 pSecAttr, bInitialOwner, name, mlist);
1972 else
1973 dbgprintf("CreateMutexA(0x%x, %d, NULL) => 0x%x\n",
1974 pSecAttr, bInitialOwner, mlist);
1975 ret = (HANDLE)mlist;
1976 pthread_mutex_unlock(&mlist_lock);
1977 return ret;
1980 static int WINAPI expReleaseMutex(HANDLE hMutex)
1982 mutex_list *ml = (mutex_list *)hMutex;
1984 pthread_mutex_lock(ml->pm);
1985 if (--ml->lock_count == 0) pthread_cond_signal(ml->pc);
1986 pthread_mutex_unlock(ml->pm);
1987 return 1;
1990 static DWORD WINAPI expSignalObjectAndWait(HANDLE hObjectToSignal,
1991 HANDLE hObjectToWaitOn,
1992 DWORD dwMilliseconds,
1993 WIN_BOOL bAlertable) {
1994 mutex_list* mlist = (mutex_list*)hObjectToSignal;
1996 switch (mlist->type) {
1997 case 0: // Event
1998 expSetEvent(mlist);
1999 break;
2000 case 1: // Semaphore
2001 expReleaseSemaphore(mlist, 1, NULL);
2002 break;
2003 case 2: // Mutex
2004 expReleaseMutex(mlist);
2005 break;
2006 default:
2007 dbgprintf("Signalling unknown object type %d!\n", hObjectToSignal);
2009 return expWaitForSingleObject(hObjectToWaitOn, dwMilliseconds);
2012 static long WINAPI expRegOpenKeyExA(long key, const char* subkey, long reserved, long access, int* newkey)
2014 long result=RegOpenKeyExA(key, subkey, reserved, access, newkey);
2015 dbgprintf("RegOpenKeyExA(key 0x%x, subkey %s, reserved %d, access 0x%x, pnewkey 0x%x) => %d\n",
2016 key, subkey, reserved, access, newkey, result);
2017 if(newkey)dbgprintf(" New key: 0x%x\n", *newkey);
2018 return result;
2020 static long WINAPI expRegCloseKey(long key)
2022 long result=RegCloseKey(key);
2023 dbgprintf("RegCloseKey(0x%x) => %d\n", key, result);
2024 return result;
2026 static long WINAPI expRegQueryValueExA(long key, const char* value, int* reserved, int* type, int* data, int* count)
2028 long result=RegQueryValueExA(key, value, reserved, type, data, count);
2029 dbgprintf("RegQueryValueExA(key 0x%x, value %s, reserved 0x%x, data 0x%x, count 0x%x)"
2030 " => 0x%x\n", key, value, reserved, data, count, result);
2031 if(data && count)dbgprintf(" read %d bytes: '%s'\n", *count, data);
2032 return result;
2035 //from wine source dlls/advapi32/registry.c
2036 static long WINAPI expRegCreateKeyA(long hkey, const char* name, int *retkey)
2038 dbgprintf("RegCreateKeyA(key 0x%x, name 0x%x='%s',newkey=0x%x)\n",hkey,name,retkey);
2039 return RegCreateKeyExA( hkey, name, 0, NULL,REG_OPTION_NON_VOLATILE,
2040 KEY_ALL_ACCESS , NULL, retkey, NULL );
2043 static long WINAPI expRegCreateKeyExA(long key, const char* name, long reserved,
2044 void* classs, long options, long security,
2045 void* sec_attr, int* newkey, int* status)
2047 long result=RegCreateKeyExA(key, name, reserved, classs, options, security, sec_attr, newkey, status);
2048 dbgprintf("RegCreateKeyExA(key 0x%x, name 0x%x='%s', reserved=0x%x,"
2049 " 0x%x, 0x%x, 0x%x, newkey=0x%x, status=0x%x) => %d\n",
2050 key, name, name, reserved, classs, options, security, sec_attr, newkey, status, result);
2051 if(!result && newkey) dbgprintf(" New key: 0x%x\n", *newkey);
2052 if(!result && status) dbgprintf(" New key status: 0x%x\n", *status);
2053 return result;
2055 static long WINAPI expRegSetValueExA(long key, const char* name, long v1, long v2, void* data, long size)
2057 long result=RegSetValueExA(key, name, v1, v2, data, size);
2058 dbgprintf("RegSetValueExA(key 0x%x, name '%s', 0x%x, 0x%x, data 0x%x -> 0x%x '%s', size=%d) => %d",
2059 key, name, v1, v2, data, *(int*)data, data, size, result);
2060 return result;
2063 static long WINAPI expRegOpenKeyA (long hKey, LPCSTR lpSubKey, int* phkResult)
2065 long result=RegOpenKeyExA(hKey, lpSubKey, 0, 0, phkResult);
2066 dbgprintf("RegOpenKeyExA(key 0x%x, subkey '%s', 0x%x) => %d\n",
2067 hKey, lpSubKey, phkResult, result);
2068 if(!result && phkResult) dbgprintf(" New key: 0x%x\n", *phkResult);
2069 return result;
2072 static DWORD WINAPI expRegEnumValueA(HKEY hkey, DWORD index, LPSTR value, LPDWORD val_count,
2073 LPDWORD reserved, LPDWORD type, LPBYTE data, LPDWORD count)
2075 return RegEnumValueA(hkey, index, value, val_count,
2076 reserved, type, data, count);
2079 static DWORD WINAPI expRegEnumKeyExA(HKEY hKey, DWORD dwIndex, LPSTR lpName, LPDWORD lpcbName,
2080 LPDWORD lpReserved, LPSTR lpClass, LPDWORD lpcbClass,
2081 LPFILETIME lpftLastWriteTime)
2083 return RegEnumKeyExA(hKey, dwIndex, lpName, lpcbName, lpReserved, lpClass,
2084 lpcbClass, lpftLastWriteTime);
2087 static long WINAPI expQueryPerformanceCounter(long long* z)
2089 longcount(z);
2090 dbgprintf("QueryPerformanceCounter(0x%x) => 1 ( %Ld )\n", z, *z);
2091 return 1;
2095 * dummy function RegQueryInfoKeyA(), required by vss codecs
2097 static DWORD WINAPI expRegQueryInfoKeyA( HKEY hkey, LPSTR class, LPDWORD class_len, LPDWORD reserved,
2098 LPDWORD subkeys, LPDWORD max_subkey, LPDWORD max_class,
2099 LPDWORD values, LPDWORD max_value, LPDWORD max_data,
2100 LPDWORD security, FILETIME *modif )
2102 return ERROR_SUCCESS;
2106 * return CPU clock (in kHz), using linux's /proc filesystem (/proc/cpuinfo)
2108 static double linux_cpuinfo_freq(void)
2110 double freq=-1;
2111 FILE *f;
2112 char line[200];
2113 char *s,*value;
2115 f = fopen ("/proc/cpuinfo", "r");
2116 if (f != NULL) {
2117 while (fgets(line,sizeof(line),f)!=NULL) {
2118 /* NOTE: the ':' is the only character we can rely on */
2119 if (!(value = strchr(line,':')))
2120 continue;
2121 /* terminate the valuename */
2122 *value++ = '\0';
2123 /* skip any leading spaces */
2124 while (*value==' ') value++;
2125 if ((s=strchr(value,'\n')))
2126 *s='\0';
2128 if (!strncasecmp(line, "cpu MHz",strlen("cpu MHz"))
2129 && sscanf(value, "%lf", &freq) == 1) {
2130 freq*=1000;
2131 break;
2134 fclose(f);
2136 return freq;
2140 static double solaris_kstat_freq(void)
2142 #if defined(HAVE_LIBKSTAT) && defined(KSTAT_DATA_INT32)
2144 * try to extract the CPU speed from the solaris kernel's kstat data
2146 kstat_ctl_t *kc;
2147 kstat_t *ksp;
2148 kstat_named_t *kdata;
2149 int mhz = 0;
2151 kc = kstat_open();
2152 if (kc != NULL)
2154 ksp = kstat_lookup(kc, "cpu_info", 0, "cpu_info0");
2156 /* kstat found and name/value pairs? */
2157 if (ksp != NULL && ksp->ks_type == KSTAT_TYPE_NAMED)
2159 /* read the kstat data from the kernel */
2160 if (kstat_read(kc, ksp, NULL) != -1)
2163 * lookup desired "clock_MHz" entry, check the expected
2164 * data type
2166 kdata = (kstat_named_t *)kstat_data_lookup(ksp, "clock_MHz");
2167 if (kdata != NULL && kdata->data_type == KSTAT_DATA_INT32)
2168 mhz = kdata->value.i32;
2171 kstat_close(kc);
2174 if (mhz > 0)
2175 return mhz * 1000.;
2176 #endif /* HAVE_LIBKSTAT */
2177 return -1; // kstat stuff is not available, CPU freq is unknown
2181 * Measure CPU freq using the pentium's time stamp counter register (TSC)
2183 static double tsc_freq(void)
2185 static double ofreq=0.0;
2186 int i;
2187 int x,y;
2188 i=time(NULL);
2189 if (ofreq != 0.0) return ofreq;
2190 while(i==time(NULL));
2191 x=localcount();
2192 i++;
2193 while(i==time(NULL));
2194 y=localcount();
2195 ofreq = (double)(y-x)/1000.;
2196 return ofreq;
2199 static double CPU_Freq(void)
2201 double freq;
2203 if ((freq = linux_cpuinfo_freq()) > 0)
2204 return freq;
2206 if ((freq = solaris_kstat_freq()) > 0)
2207 return freq;
2209 return tsc_freq();
2212 static long WINAPI expQueryPerformanceFrequency(long long* z)
2214 *z=(long long)CPU_Freq();
2215 dbgprintf("QueryPerformanceFrequency(0x%x) => 1 ( %Ld )\n", z, *z);
2216 return 1;
2218 static long WINAPI exptimeGetTime(void)
2220 struct timeval t;
2221 long result;
2222 gettimeofday(&t, 0);
2223 result=1000*t.tv_sec+t.tv_usec/1000;
2224 dbgprintf("timeGetTime() => %d\n", result);
2225 return result;
2227 static void* WINAPI expLocalHandle(void* v)
2229 dbgprintf("LocalHandle(0x%x) => 0x%x\n", v, v);
2230 return v;
2233 static void* WINAPI expGlobalHandle(void* v)
2235 dbgprintf("GlobalHandle(0x%x) => 0x%x\n", v, v);
2236 return v;
2238 static int WINAPI expGlobalUnlock(void* v)
2240 dbgprintf("GlobalUnlock(0x%x) => 1\n", v);
2241 return 1;
2243 static void* WINAPI expGlobalFree(void* v)
2245 dbgprintf("GlobalFree(0x%x) => 0\n", v);
2246 my_release(v);
2247 //free(v);
2248 return 0;
2251 static void* WINAPI expGlobalReAlloc(void* v, int size, int flags)
2253 void* result=my_realloc(v, size);
2254 //void* result=realloc(v, size);
2255 dbgprintf("GlobalReAlloc(0x%x, size %d, flags 0x%x) => 0x%x\n", v,size,flags,result);
2256 return result;
2259 static int WINAPI expLocalUnlock(void* v)
2261 dbgprintf("LocalUnlock(0x%x) => 1\n", v);
2262 return 1;
2265 static void* WINAPI expLocalFree(void* v)
2267 dbgprintf("LocalFree(0x%x) => 0\n", v);
2268 my_release(v);
2269 return 0;
2271 static HRSRC WINAPI expFindResourceA(HMODULE module, char* name, char* type)
2273 HRSRC result;
2275 result=FindResourceA(module, name, type);
2276 dbgprintf("FindResourceA(module 0x%x, name 0x%x(%s), type 0x%x(%s)) => 0x%x\n",
2277 module, name, HIWORD(name) ? name : "UNICODE", type, HIWORD(type) ? type : "UNICODE", result);
2278 return result;
2281 static HGLOBAL WINAPI expLoadResource(HMODULE module, HRSRC res)
2283 HGLOBAL result=LoadResource(module, res);
2284 dbgprintf("LoadResource(module 0x%x, resource 0x%x) => 0x%x\n", module, res, result);
2285 return result;
2287 static void* WINAPI expLockResource(long res)
2289 void* result=LockResource(res);
2290 dbgprintf("LockResource(0x%x) => 0x%x\n", res, result);
2291 return result;
2293 static int WINAPI expFreeResource(long res)
2295 int result=FreeResource(res);
2296 dbgprintf("FreeResource(0x%x) => %d\n", res, result);
2297 return result;
2299 //bool fun(HANDLE)
2300 //!0 on success
2301 static int WINAPI expCloseHandle(long v1)
2303 dbgprintf("CloseHandle(0x%x) => 1\n", v1);
2304 /* do not close stdin,stdout and stderr */
2305 if (v1 > 2)
2306 if (!close(v1))
2307 return 0;
2308 return 1;
2311 static const char* WINAPI expGetCommandLineA(void)
2313 dbgprintf("GetCommandLineA() => \"c:\\aviplay.exe\"\n");
2314 return "c:\\aviplay.exe";
2316 static short envs[]={'p', 'a', 't', 'h', ' ', 'c', ':', '\\', 0, 0};
2317 static LPWSTR WINAPI expGetEnvironmentStringsW(void)
2319 dbgprintf("GetEnvironmentStringsW() => 0\n", envs);
2320 return 0;
2322 static void * WINAPI expRtlZeroMemory(void *p, size_t len)
2324 void* result=memset(p,0,len);
2325 dbgprintf("RtlZeroMemory(0x%x, len %d) => 0x%x\n",p,len,result);
2326 return result;
2328 static void * WINAPI expRtlMoveMemory(void *dst, void *src, size_t len)
2330 void* result=memmove(dst,src,len);
2331 dbgprintf("RtlMoveMemory (dest 0x%x, src 0x%x, len %d) => 0x%x\n",dst,src,len,result);
2332 return result;
2335 static void * WINAPI expRtlFillMemory(void *p, int ch, size_t len)
2337 void* result=memset(p,ch,len);
2338 dbgprintf("RtlFillMemory(0x%x, char 0x%x, len %d) => 0x%x\n",p,ch,len,result);
2339 return result;
2341 static int WINAPI expFreeEnvironmentStringsW(short* strings)
2343 dbgprintf("FreeEnvironmentStringsW(0x%x) => 1\n", strings);
2344 return 1;
2346 static int WINAPI expFreeEnvironmentStringsA(char* strings)
2348 dbgprintf("FreeEnvironmentStringsA(0x%x) => 1\n", strings);
2349 return 1;
2352 static const char ch_envs[]=
2353 "__MSVCRT_HEAP_SELECT=__GLOBAL_HEAP_SELECTED,1\r\n"
2354 "PATH=C:\\;C:\\windows\\;C:\\windows\\system\r\n";
2355 static LPCSTR WINAPI expGetEnvironmentStrings(void)
2357 dbgprintf("GetEnvironmentStrings() => 0x%x\n", ch_envs);
2358 return (LPCSTR)ch_envs;
2359 // dbgprintf("GetEnvironmentStrings() => 0\n");
2360 // return 0;
2363 static int WINAPI expGetStartupInfoA(STARTUPINFOA *s)
2365 dbgprintf("GetStartupInfoA(0x%x) => 1\n");
2366 memset(s, 0, sizeof(*s));
2367 s->cb=sizeof(*s);
2368 // s->lpReserved="Reserved";
2369 // s->lpDesktop="Desktop";
2370 // s->lpTitle="Title";
2371 // s->dwX=s->dwY=0;
2372 // s->dwXSize=s->dwYSize=200;
2373 s->dwFlags=s->wShowWindow=1;
2374 // s->hStdInput=s->hStdOutput=s->hStdError=0x1234;
2375 dbgprintf(" cb=%d\n", s->cb);
2376 dbgprintf(" lpReserved='%s'\n", s->lpReserved);
2377 dbgprintf(" lpDesktop='%s'\n", s->lpDesktop);
2378 dbgprintf(" lpTitle='%s'\n", s->lpTitle);
2379 dbgprintf(" dwX=%d dwY=%d dwXSize=%d dwYSize=%d\n",
2380 s->dwX, s->dwY, s->dwXSize, s->dwYSize);
2381 dbgprintf(" dwXCountChars=%d dwYCountChars=%d dwFillAttribute=%d\n",
2382 s->dwXCountChars, s->dwYCountChars, s->dwFillAttribute);
2383 dbgprintf(" dwFlags=0x%x wShowWindow=0x%x cbReserved2=0x%x\n",
2384 s->dwFlags, s->wShowWindow, s->cbReserved2);
2385 dbgprintf(" lpReserved2=0x%x hStdInput=0x%x hStdOutput=0x%x hStdError=0x%x\n",
2386 s->lpReserved2, s->hStdInput, s->hStdOutput, s->hStdError);
2387 return 1;
2390 static int WINAPI expGetStdHandle(int z)
2392 dbgprintf("GetStdHandle(0x%x) => 0x%x\n", z+0x1234);
2393 return z+0x1234;
2396 #ifdef CONFIG_QTX_CODECS
2397 #define FILE_HANDLE_quicktimeqts ((HANDLE)0x444)
2398 #define FILE_HANDLE_quicktimeqtx ((HANDLE)0x445)
2399 #endif
2401 static int WINAPI expGetFileType(int handle)
2403 dbgprintf("GetFileType(0x%x) => 0x3 = pipe\n", handle);
2404 return 0x3;
2406 #ifdef CONFIG_QTX_CODECS
2407 static int WINAPI expGetFileAttributesA(char *filename)
2409 dbgprintf("GetFileAttributesA(%s) => FILE_ATTR_NORMAL\n", filename);
2410 if (strstr(filename, "QuickTime.qts"))
2411 return FILE_ATTRIBUTE_SYSTEM;
2412 return FILE_ATTRIBUTE_NORMAL;
2414 #endif
2415 static int WINAPI expSetHandleCount(int count)
2417 dbgprintf("SetHandleCount(0x%x) => 1\n", count);
2418 return 1;
2420 static int WINAPI expGetACP(void)
2422 dbgprintf("GetACP() => 0\n");
2423 return 0;
2425 static int WINAPI expGetModuleFileNameA(int module, char* s, int len)
2427 WINE_MODREF *mr;
2428 int result;
2429 //printf("File name of module %X (%s) requested\n", module, s);
2431 if (module == 0 && len >= 12)
2433 /* return caller program name */
2434 strcpy(s, "aviplay.dll");
2435 result=1;
2437 else if(s==0)
2438 result=0;
2439 else
2440 if(len<35)
2441 result=0;
2442 else
2444 result=1;
2445 strcpy(s, "c:\\windows\\system\\");
2446 mr=MODULE32_LookupHMODULE(module);
2447 if(mr==0)//oops
2448 strcat(s, "aviplay.dll");
2449 else
2450 if(strrchr(mr->filename, '/')==NULL)
2451 strcat(s, mr->filename);
2452 else
2453 strcat(s, strrchr(mr->filename, '/')+1);
2455 if(!s)
2456 dbgprintf("GetModuleFileNameA(0x%x, 0x%x, %d) => %d\n",
2457 module, s, len, result);
2458 else
2459 dbgprintf("GetModuleFileNameA(0x%x, 0x%x, %d) => %d ( '%s' )\n",
2460 module, s, len, result, s);
2461 return result;
2464 static int WINAPI expGetModuleBaseNameA(int process, int module, char* s, int len)
2466 int result = 0;
2468 if (s && len) {
2469 av_strlcpy(s, "aviplay.dll", len);
2470 result = strlen(s);
2473 dbgprintf("GetModuleBaseNameA(0x%x, 0x%x, 0x%x, %d) => %d\n",
2474 process, module, s, len, result);
2476 return result;
2479 static int WINAPI expSetUnhandledExceptionFilter(void* filter)
2481 dbgprintf("SetUnhandledExceptionFilter(0x%x) => 1\n", filter);
2482 return 1;//unsupported and probably won't ever be supported
2485 static int WINAPI expLoadLibraryA(char* name)
2487 int result = 0;
2488 char* lastbc;
2489 if (!name)
2490 return -1;
2491 // we skip to the last backslash
2492 // this is effectively eliminating weird characters in
2493 // the text output windows
2495 lastbc = strrchr(name, '\\');
2496 if (lastbc)
2498 int i;
2499 lastbc++;
2500 for (i = 0; 1 ;i++)
2502 name[i] = *lastbc++;
2503 if (!name[i])
2504 break;
2507 if(strncmp(name, "c:\\windows\\", 11)==0) name += 11;
2508 if(strncmp(name, ".\\", 2)==0) name += 2;
2510 dbgprintf("Entering LoadLibraryA(%s)\n", name);
2512 // PIMJ and VIVO audio are loading kernel32.dll
2513 if (strcasecmp(name, "kernel32.dll") == 0 || strcasecmp(name, "kernel32") == 0)
2514 return MODULE_HANDLE_kernel32;
2515 // return ERROR_SUCCESS; /* yeah, we have also the kernel32 calls */
2516 /* exported -> do not return failed! */
2518 if (strcasecmp(name, "user32.dll") == 0 || strcasecmp(name, "user32") == 0)
2519 // return MODULE_HANDLE_kernel32;
2520 return MODULE_HANDLE_user32;
2522 #ifdef CONFIG_QTX_CODECS
2523 if (strcasecmp(name, "wininet.dll") == 0 || strcasecmp(name, "wininet") == 0)
2524 return MODULE_HANDLE_wininet;
2525 if (strcasecmp(name, "ddraw.dll") == 0 || strcasecmp(name, "ddraw") == 0)
2526 return MODULE_HANDLE_ddraw;
2527 if (strcasecmp(name, "advapi32.dll") == 0 || strcasecmp(name, "advapi32") == 0)
2528 return MODULE_HANDLE_advapi32;
2529 #endif
2531 if (strcasecmp(name, "comdlg32.dll") == 0 || strcasecmp(name, "comdlg32") == 0)
2532 return MODULE_HANDLE_comdlg32;
2533 if (strcasecmp(name, "msvcrt.dll") == 0 || strcasecmp(name, "msvcrt") == 0)
2534 return MODULE_HANDLE_msvcrt;
2535 if (strcasecmp(name, "ole32.dll") == 0 || strcasecmp(name, "ole32") == 0)
2536 return MODULE_HANDLE_ole32;
2537 if (strcasecmp(name, "winmm.dll") == 0 || strcasecmp(name, "winmm") == 0)
2538 return MODULE_HANDLE_winmm;
2539 if (strcasecmp(name, "psapi.dll") == 0 || strcasecmp(name, "psapi") == 0)
2540 return MODULE_HANDLE_psapi;
2542 result=LoadLibraryA(name);
2543 dbgprintf("Returned LoadLibraryA(0x%x='%s'), def_path=%s => 0x%x\n", name, name, def_path, result);
2545 return result;
2548 static int WINAPI expFreeLibrary(int module)
2550 #ifdef CONFIG_QTX_CODECS
2551 int result=0; /* FIXME:XXX: qtx svq3 frees up qt.qts */
2552 #else
2553 int result=FreeLibrary(module);
2554 #endif
2555 dbgprintf("FreeLibrary(0x%x) => %d\n", module, result);
2556 return result;
2559 static void* WINAPI expGetProcAddress(HMODULE mod, char* name)
2561 void* result;
2562 switch(mod){
2563 case MODULE_HANDLE_kernel32:
2564 result=LookupExternalByName("kernel32.dll", name); break;
2565 case MODULE_HANDLE_user32:
2566 result=LookupExternalByName("user32.dll", name); break;
2567 #ifdef CONFIG_QTX_CODECS
2568 case MODULE_HANDLE_wininet:
2569 result=LookupExternalByName("wininet.dll", name); break;
2570 case MODULE_HANDLE_ddraw:
2571 result=LookupExternalByName("ddraw.dll", name); break;
2572 case MODULE_HANDLE_advapi32:
2573 result=LookupExternalByName("advapi32.dll", name); break;
2574 #endif
2575 case MODULE_HANDLE_comdlg32:
2576 result=LookupExternalByName("comdlg32.dll", name); break;
2577 case MODULE_HANDLE_msvcrt:
2578 result=LookupExternalByName("msvcrt.dll", name); break;
2579 case MODULE_HANDLE_ole32:
2580 result=LookupExternalByName("ole32.dll", name); break;
2581 case MODULE_HANDLE_winmm:
2582 result=LookupExternalByName("winmm.dll", name); break;
2583 case MODULE_HANDLE_psapi:
2584 result=LookupExternalByName("psapi.dll", name); break;
2585 default:
2586 result=GetProcAddress(mod, name);
2588 if((unsigned int)name > 0xffff)
2589 dbgprintf("GetProcAddress(0x%x, '%s') => 0x%x\n", mod, name, result);
2590 else
2591 dbgprintf("GetProcAddress(0x%x, '%d') => 0x%x\n", mod, (int)name, result);
2592 return result;
2595 static long WINAPI expCreateFileMappingA(int hFile, void* lpAttr,
2596 long flProtect, long dwMaxHigh,
2597 long dwMaxLow, const char* name)
2599 long result=CreateFileMappingA(hFile, lpAttr, flProtect, dwMaxHigh, dwMaxLow, name);
2600 if(!name)
2601 dbgprintf("CreateFileMappingA(file 0x%x, lpAttr 0x%x,"
2602 "flProtect 0x%x, dwMaxHigh 0x%x, dwMaxLow 0x%x, name 0) => %d\n",
2603 hFile, lpAttr, flProtect, dwMaxHigh, dwMaxLow, result);
2604 else
2605 dbgprintf("CreateFileMappingA(file 0x%x, lpAttr 0x%x,"
2606 "flProtect 0x%x, dwMaxHigh 0x%x, dwMaxLow 0x%x, name 0x%x='%s') => %d\n",
2607 hFile, lpAttr, flProtect, dwMaxHigh, dwMaxLow, name, name, result);
2608 return result;
2611 static long WINAPI expOpenFileMappingA(long hFile, long hz, const char* name)
2613 long result=OpenFileMappingA(hFile, hz, name);
2614 if(!name)
2615 dbgprintf("OpenFileMappingA(0x%x, 0x%x, 0) => %d\n",
2616 hFile, hz, result);
2617 else
2618 dbgprintf("OpenFileMappingA(0x%x, 0x%x, 0x%x='%s') => %d\n",
2619 hFile, hz, name, name, result);
2620 return result;
2623 static void* WINAPI expMapViewOfFile(HANDLE file, DWORD mode, DWORD offHigh,
2624 DWORD offLow, DWORD size)
2626 dbgprintf("MapViewOfFile(0x%x, 0x%x, 0x%x, 0x%x, size %d) => 0x%x\n",
2627 file,mode,offHigh,offLow,size,(char*)file+offLow);
2628 return (char*)file+offLow;
2631 static void* WINAPI expUnmapViewOfFile(void* view)
2633 dbgprintf("UnmapViewOfFile(0x%x) => 0\n", view);
2634 return 0;
2637 static void* WINAPI expSleep(int time)
2639 #if HAVE_NANOSLEEP
2640 /* solaris doesn't have thread safe usleep */
2641 struct timespec tsp;
2642 tsp.tv_sec = time / 1000000;
2643 tsp.tv_nsec = (time % 1000000) * 1000;
2644 nanosleep(&tsp, NULL);
2645 #else
2646 usleep(time);
2647 #endif
2648 dbgprintf("Sleep(%d) => 0\n", time);
2649 return 0;
2652 // why does IV32 codec want to call this? I don't know ...
2653 static int WINAPI expCreateCompatibleDC(int hdc)
2655 int dc = 0;//0x81;
2656 //dbgprintf("CreateCompatibleDC(%d) => 0x81\n", hdc);
2657 dbgprintf("CreateCompatibleDC(%d) => %d\n", hdc, dc);
2658 return dc;
2661 static int WINAPI expGetDeviceCaps(int hdc, int unk)
2663 dbgprintf("GetDeviceCaps(0x%x, %d) => 0\n", hdc, unk);
2664 #ifdef CONFIG_QTX_CODECS
2665 #define BITSPIXEL 12
2666 #define PLANES 14
2667 if (unk == BITSPIXEL)
2668 return 24;
2669 if (unk == PLANES)
2670 return 1;
2671 #endif
2672 return 1;
2675 static WIN_BOOL WINAPI expDeleteDC(int hdc)
2677 dbgprintf("DeleteDC(0x%x) => 0\n", hdc);
2678 if (hdc == 0x81)
2679 return 1;
2680 return 0;
2683 static WIN_BOOL WINAPI expDeleteObject(int hdc)
2685 dbgprintf("DeleteObject(0x%x) => 1\n", hdc);
2686 /* FIXME - implement code here */
2687 return 1;
2690 /* btvvc32.drv wants this one */
2691 static void* WINAPI expGetWindowDC(int hdc)
2693 dbgprintf("GetWindowDC(%d) => 0x0\n", hdc);
2694 return 0;
2697 #ifdef CONFIG_QTX_CODECS
2698 static int WINAPI expGetWindowRect(HWND win, RECT *r)
2700 dbgprintf("GetWindowRect(0x%x, 0x%x) => 1\n", win, r);
2701 /* (win == 0) => desktop */
2702 r->right = PSEUDO_SCREEN_WIDTH;
2703 r->left = 0;
2704 r->bottom = PSEUDO_SCREEN_HEIGHT;
2705 r->top = 0;
2706 return 1;
2709 static int WINAPI expMonitorFromWindow(HWND win, int flags)
2711 dbgprintf("MonitorFromWindow(0x%x, 0x%x) => 0\n", win, flags);
2712 return 0;
2715 static int WINAPI expMonitorFromRect(RECT *r, int flags)
2717 dbgprintf("MonitorFromRect(0x%x, 0x%x) => 0\n", r, flags);
2718 return 0;
2721 static int WINAPI expMonitorFromPoint(void *p, int flags)
2723 dbgprintf("MonitorFromPoint(0x%x, 0x%x) => 0\n", p, flags);
2724 return 0;
2727 static int WINAPI expEnumDisplayMonitors(void *dc, RECT *r,
2728 int WINAPI (*callback_proc)(), void *callback_param)
2730 dbgprintf("EnumDisplayMonitors(0x%x, 0x%x, 0x%x, 0x%x) => ?\n",
2731 dc, r, callback_proc, callback_param);
2732 return callback_proc(0, dc, r, callback_param);
2735 #if 0
2736 typedef struct tagMONITORINFO {
2737 DWORD cbSize;
2738 RECT rcMonitor;
2739 RECT rcWork;
2740 DWORD dwFlags;
2741 } MONITORINFO, *LPMONITORINFO;
2742 #endif
2744 #define CCHDEVICENAME 8
2745 typedef struct tagMONITORINFOEX {
2746 DWORD cbSize;
2747 RECT rcMonitor;
2748 RECT rcWork;
2749 DWORD dwFlags;
2750 TCHAR szDevice[CCHDEVICENAME];
2751 } MONITORINFOEX, *LPMONITORINFOEX;
2753 static int WINAPI expGetMonitorInfoA(void *mon, LPMONITORINFO lpmi)
2755 dbgprintf("GetMonitorInfoA(0x%x, 0x%x) => 1\n", mon, lpmi);
2757 lpmi->rcMonitor.right = lpmi->rcWork.right = PSEUDO_SCREEN_WIDTH;
2758 lpmi->rcMonitor.left = lpmi->rcWork.left = 0;
2759 lpmi->rcMonitor.bottom = lpmi->rcWork.bottom = PSEUDO_SCREEN_HEIGHT;
2760 lpmi->rcMonitor.top = lpmi->rcWork.top = 0;
2762 lpmi->dwFlags = 1; /* primary monitor */
2764 if (lpmi->cbSize == sizeof(MONITORINFOEX))
2766 LPMONITORINFOEX lpmiex = (LPMONITORINFOEX)lpmi;
2767 dbgprintf("MONITORINFOEX!\n");
2768 strncpy(lpmiex->szDevice, "Monitor1", CCHDEVICENAME);
2771 return 1;
2774 static int WINAPI expEnumDisplayDevicesA(const char *device, int devnum,
2775 void *dispdev, int flags)
2777 dbgprintf("EnumDisplayDevicesA(0x%x = %s, %d, 0x%x, %x) => 1\n",
2778 device, device, devnum, dispdev, flags);
2779 return 1;
2782 static int WINAPI expIsWindowVisible(HWND win)
2784 dbgprintf("IsWindowVisible(0x%x) => 1\n", win);
2785 return 1;
2788 static HWND WINAPI expGetActiveWindow(void)
2790 dbgprintf("GetActiveWindow() => 0\n");
2791 return (HWND)0;
2794 static int WINAPI expGetClassNameA(HWND win, LPTSTR classname, int maxcount)
2796 strncat(classname, "QuickTime", maxcount);
2797 dbgprintf("GetClassNameA(0x%x, 0x%x, %d) => %d\n",
2798 win, classname, maxcount, strlen(classname));
2799 return strlen(classname);
2802 #define LPWNDCLASS void *
2803 static int WINAPI expGetClassInfoA(HINSTANCE inst, LPCSTR classname, LPWNDCLASS wndclass)
2805 dbgprintf("GetClassInfoA(0x%x, 0x%x = %s, 0x%x) => 1\n", inst,
2806 classname, classname, wndclass);
2807 return 1;
2810 static int WINAPI expGetWindowLongA(HWND win, int index)
2812 dbgprintf("GetWindowLongA(0x%x, %d) => 0\n", win, index);
2813 return 1;
2816 static int WINAPI expGetObjectA(HGDIOBJ hobj, int objsize, LPVOID obj)
2818 dbgprintf("GetObjectA(0x%x, %d, 0x%x) => %d\n", hobj, objsize, obj, objsize);
2819 return objsize;
2822 static int WINAPI expCreateRectRgn(int x, int y, int width, int height)
2824 dbgprintf("CreateRectRgn(%d, %d, %d, %d) => 0\n", x, y, width, height);
2825 return 0;
2828 static int WINAPI expEnumWindows(int (*callback_func)(), void *callback_param)
2830 int i, i2;
2831 dbgprintf("EnumWindows(0x%x, 0x%x) => 1\n", callback_func, callback_param);
2832 i = callback_func(0, callback_param);
2833 i2 = callback_func(1, callback_param);
2834 return i && i2;
2837 static int WINAPI expGetWindowThreadProcessId(HWND win, int *pid_data)
2839 int tid = pthread_self();
2840 dbgprintf("GetWindowThreadProcessId(0x%x, 0x%x) => %d\n",
2841 win, pid_data, tid);
2842 if (pid_data)
2843 *(int*)pid_data = tid;
2844 return tid;
2847 //HWND WINAPI CreateWindowExA(DWORD,LPCSTR,LPCSTR,DWORD,INT,INT,
2848 // INT,INT,HWND,HMENU,HINSTANCE,LPVOID);
2850 static HWND WINAPI expCreateWindowExA(int exstyle, const char *classname,
2851 const char *winname, int style, int x, int y, int w, int h,
2852 HWND parent, HMENU menu, HINSTANCE inst, LPVOID param)
2854 printf("CreateWindowEx() called\n");
2855 dbgprintf("CreateWindowEx(%d, 0x%x = %s, 0x%x = %s, %d, %d, %d, %d, %d, 0x%x, 0x%x, 0x%x, 0x%x) => 1\n",
2856 exstyle, classname, classname, winname, winname, style, x, y, w, h,
2857 parent, menu, inst, param);
2858 printf("CreateWindowEx() called okey\n");
2859 return 1;
2862 static int WINAPI expwaveOutGetNumDevs(void)
2864 dbgprintf("waveOutGetNumDevs() => 0\n");
2865 return 0;
2867 #endif
2870 * Returns the number of milliseconds, modulo 2^32, since the start
2871 * of the wineserver.
2873 static int WINAPI expGetTickCount(void)
2875 static int tcstart = 0;
2876 struct timeval t;
2877 int tc;
2878 gettimeofday( &t, NULL );
2879 tc = ((t.tv_sec * 1000) + (t.tv_usec / 1000)) - tcstart;
2880 if (tcstart == 0)
2882 tcstart = 0;
2883 tc = 0;
2885 dbgprintf("GetTickCount() => %d\n", tc);
2886 return tc;
2889 static int WINAPI expCreateFontA(void)
2891 dbgprintf("CreateFontA() => 0x0\n");
2892 return 1;
2895 /* tried to get pvmjpg work in a different way - no success */
2896 static int WINAPI expDrawTextA(int hDC, char* lpString, int nCount,
2897 LPRECT lpRect, unsigned int uFormat)
2899 dbgprintf("expDrawTextA(%p,...) => 8\n", hDC);
2900 return 8;
2903 static int WINAPI expGetPrivateProfileIntA(const char* appname,
2904 const char* keyname,
2905 int default_value,
2906 const char* filename)
2908 int size=255;
2909 char buffer[256];
2910 char* fullname;
2911 int result;
2913 buffer[255]=0;
2914 if(!(appname && keyname && filename) )
2916 dbgprintf("GetPrivateProfileIntA('%s', '%s', %d, '%s') => %d\n", appname, keyname, default_value, filename, default_value );
2917 return default_value;
2919 fullname=malloc(50+strlen(appname)+strlen(keyname)+strlen(filename));
2920 strcpy(fullname, "Software\\IniFileMapping\\");
2921 strcat(fullname, appname);
2922 strcat(fullname, "\\");
2923 strcat(fullname, keyname);
2924 strcat(fullname, "\\");
2925 strcat(fullname, filename);
2926 result=RegQueryValueExA(HKEY_LOCAL_MACHINE, fullname, NULL, NULL, (int*)buffer, &size);
2927 if((size>=0)&&(size<256))
2928 buffer[size]=0;
2929 // printf("GetPrivateProfileIntA(%s, %s, %s) -> %s\n", appname, keyname, filename, buffer);
2930 free(fullname);
2931 if(result)
2932 result=default_value;
2933 else
2934 result=atoi(buffer);
2935 dbgprintf("GetPrivateProfileIntA('%s', '%s', %d, '%s') => %d\n", appname, keyname, default_value, filename, result);
2936 return result;
2938 static int WINAPI expGetProfileIntA(const char* appname,
2939 const char* keyname,
2940 int default_value)
2942 dbgprintf("GetProfileIntA -> ");
2943 return expGetPrivateProfileIntA(appname, keyname, default_value, "default");
2946 static int WINAPI expGetPrivateProfileStringA(const char* appname,
2947 const char* keyname,
2948 const char* def_val,
2949 char* dest, unsigned int len,
2950 const char* filename)
2952 int result;
2953 int size;
2954 char* fullname;
2955 dbgprintf("GetPrivateProfileStringA('%s', '%s', def_val '%s', 0x%x, 0x%x, '%s')", appname, keyname, def_val, dest, len, filename );
2956 if(!(appname && keyname && filename) ) return 0;
2957 fullname=malloc(50+strlen(appname)+strlen(keyname)+strlen(filename));
2958 strcpy(fullname, "Software\\IniFileMapping\\");
2959 strcat(fullname, appname);
2960 strcat(fullname, "\\");
2961 strcat(fullname, keyname);
2962 strcat(fullname, "\\");
2963 strcat(fullname, filename);
2964 size=len;
2965 result=RegQueryValueExA(HKEY_LOCAL_MACHINE, fullname, NULL, NULL, (int*)dest, &size);
2966 free(fullname);
2967 if(result)
2969 strncpy(dest, def_val, size);
2970 if (strlen(def_val)< size) size = strlen(def_val);
2972 dbgprintf(" => %d ( '%s' )\n", size, dest);
2973 return size;
2975 static int WINAPI expWritePrivateProfileStringA(const char* appname,
2976 const char* keyname,
2977 const char* string,
2978 const char* filename)
2980 char* fullname;
2981 dbgprintf("WritePrivateProfileStringA('%s', '%s', '%s', '%s')", appname, keyname, string, filename );
2982 if(!(appname && keyname && filename) )
2984 dbgprintf(" => -1\n");
2985 return -1;
2987 fullname=malloc(50+strlen(appname)+strlen(keyname)+strlen(filename));
2988 strcpy(fullname, "Software\\IniFileMapping\\");
2989 strcat(fullname, appname);
2990 strcat(fullname, "\\");
2991 strcat(fullname, keyname);
2992 strcat(fullname, "\\");
2993 strcat(fullname, filename);
2994 RegSetValueExA(HKEY_LOCAL_MACHINE, fullname, 0, REG_SZ, (int*)string, strlen(string));
2995 // printf("RegSetValueExA(%s,%d)\n", string, strlen(string));
2996 // printf("WritePrivateProfileStringA(%s, %s, %s, %s)\n", appname, keyname, string, filename );
2997 free(fullname);
2998 dbgprintf(" => 0\n");
2999 return 0;
3002 unsigned int GetPrivateProfileIntA_(const char* appname, const char* keyname, INT default_value, const char* filename)
3004 return expGetPrivateProfileIntA(appname, keyname, default_value, filename);
3006 int GetPrivateProfileStringA_(const char* appname, const char* keyname,
3007 const char* def_val, char* dest, unsigned int len, const char* filename)
3009 return expGetPrivateProfileStringA(appname, keyname, def_val, dest, len, filename);
3011 int WritePrivateProfileStringA_(const char* appname, const char* keyname,
3012 const char* string, const char* filename)
3014 return expWritePrivateProfileStringA(appname, keyname, string, filename);
3019 static int WINAPI expDefDriverProc(int private, int id, int msg, int arg1, int arg2)
3021 dbgprintf("DefDriverProc(0x%x, 0x%x, 0x%x, 0x%x, 0x%x) => 0\n", private, id, msg, arg1, arg2);
3022 return 0;
3025 static int WINAPI expSizeofResource(int v1, int v2)
3027 int result=SizeofResource(v1, v2);
3028 dbgprintf("SizeofResource(0x%x, 0x%x) => %d\n", v1, v2, result);
3029 return result;
3032 static int WINAPI expGetLastError(void)
3034 int result=GetLastError();
3035 dbgprintf("GetLastError() => 0x%x\n", result);
3036 return result;
3039 static void WINAPI expSetLastError(int error)
3041 dbgprintf("SetLastError(0x%x)\n", error);
3042 SetLastError(error);
3045 static int WINAPI expStringFromGUID2(GUID* guid, char* str, int cbMax)
3047 int result=snprintf(str, cbMax, "%.8x-%.4x-%.4x-%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x",
3048 guid->f1, guid->f2, guid->f3,
3049 (unsigned char)guid->f4[0], (unsigned char)guid->f4[1],
3050 (unsigned char)guid->f4[2], (unsigned char)guid->f4[3],
3051 (unsigned char)guid->f4[4], (unsigned char)guid->f4[5],
3052 (unsigned char)guid->f4[6], (unsigned char)guid->f4[7]);
3053 dbgprintf("StringFromGUID2(0x%x, 0x%x='%s', %d) => %d\n", guid, str, str, cbMax, result);
3054 return result;
3058 static int WINAPI expGetFileVersionInfoSizeA(const char* name, int* lpHandle)
3060 dbgprintf("GetFileVersionInfoSizeA(0x%x='%s', 0x%X) => 0\n", name, name, lpHandle);
3061 return 0;
3064 static int WINAPI expIsBadStringPtrW(const short* string, int nchars)
3066 int result;
3067 if(string==0)result=1; else result=0;
3068 dbgprintf("IsBadStringPtrW(0x%x, %d) => %d", string, nchars, result);
3069 if(string)wch_print(string);
3070 return result;
3072 static int WINAPI expIsBadStringPtrA(const char* string, int nchars)
3074 return expIsBadStringPtrW((const short*)string, nchars);
3076 static long WINAPI expInterlockedExchangeAdd( long* dest, long incr )
3078 long ret;
3079 __asm__ volatile
3081 "lock; xaddl %0,(%1)"
3082 : "=r" (ret)
3083 : "r" (dest), "0" (incr)
3084 : "memory"
3086 return ret;
3089 static long WINAPI expInterlockedCompareExchange( unsigned long* dest, unsigned long exchange, unsigned long comperand)
3091 unsigned long retval = *dest;
3092 if(*dest == comperand)
3093 *dest = exchange;
3094 return retval;
3097 static long WINAPI expInterlockedIncrement( long* dest )
3099 long result=expInterlockedExchangeAdd( dest, 1 ) + 1;
3100 dbgprintf("InterlockedIncrement(0x%x => %d) => %d\n", dest, *dest, result);
3101 return result;
3103 static long WINAPI expInterlockedDecrement( long* dest )
3105 long result=expInterlockedExchangeAdd( dest, -1 ) - 1;
3106 dbgprintf("InterlockedDecrement(0x%x => %d) => %d\n", dest, *dest, result);
3107 return result;
3110 static void WINAPI expOutputDebugStringA( const char* string )
3112 dbgprintf("OutputDebugStringA(0x%x='%s')\n", string);
3113 fprintf(stderr, "DEBUG: %s\n", string);
3116 static int WINAPI expGetDC(int hwnd)
3118 dbgprintf("GetDC(0x%x) => 1\n", hwnd);
3119 return 1;
3122 static int WINAPI expReleaseDC(int hwnd, int hdc)
3124 dbgprintf("ReleaseDC(0x%x, 0x%x) => 1\n", hwnd, hdc);
3125 return 1;
3128 static int WINAPI expGetDesktopWindow(void)
3130 dbgprintf("GetDesktopWindow() => 0\n");
3131 return 0;
3134 static int cursor[100];
3136 static int WINAPI expLoadCursorA(int handle,LPCSTR name)
3138 dbgprintf("LoadCursorA(%d, 0x%x='%s') => 0x%x\n", handle, name, (int)&cursor[0]);
3139 return (int)&cursor[0];
3141 static int WINAPI expSetCursor(void *cursor)
3143 dbgprintf("SetCursor(0x%x) => 0x%x\n", cursor, cursor);
3144 return (int)cursor;
3146 static int WINAPI expGetCursorPos(void *cursor)
3148 dbgprintf("GetCursorPos(0x%x) => 0x%x\n", cursor, cursor);
3149 return 1;
3151 #ifdef CONFIG_QTX_CODECS
3152 static int show_cursor = 0;
3153 static int WINAPI expShowCursor(int show)
3155 dbgprintf("ShowCursor(%d) => %d\n", show, show);
3156 if (show)
3157 show_cursor++;
3158 else
3159 show_cursor--;
3160 return show_cursor;
3162 #endif
3163 static int WINAPI expRegisterWindowMessageA(char *message)
3165 dbgprintf("RegisterWindowMessageA(%s)\n", message);
3166 return 1;
3168 static int WINAPI expGetProcessVersion(int pid)
3170 dbgprintf("GetProcessVersion(%d)\n", pid);
3171 return 1;
3173 static int WINAPI expGetCurrentThread(void)
3175 #warning FIXME!
3176 dbgprintf("GetCurrentThread() => %x\n", 0xcfcf9898);
3177 return 0xcfcf9898;
3179 static int WINAPI expGetOEMCP(void)
3181 dbgprintf("GetOEMCP()\n");
3182 return 1;
3184 static int WINAPI expGetCPInfo(int cp,void *info)
3186 dbgprintf("GetCPInfo()\n");
3187 return 0;
3189 #ifdef CONFIG_QTX_CODECS
3190 #define SM_CXSCREEN 0
3191 #define SM_CYSCREEN 1
3192 #define SM_XVIRTUALSCREEN 76
3193 #define SM_YVIRTUALSCREEN 77
3194 #define SM_CXVIRTUALSCREEN 78
3195 #define SM_CYVIRTUALSCREEN 79
3196 #define SM_CMONITORS 80
3197 #endif
3198 static int WINAPI expGetSystemMetrics(int index)
3200 dbgprintf("GetSystemMetrics(%d)\n", index);
3201 #ifdef CONFIG_QTX_CODECS
3202 switch(index)
3204 case SM_XVIRTUALSCREEN:
3205 case SM_YVIRTUALSCREEN:
3206 return 0;
3207 case SM_CXSCREEN:
3208 case SM_CXVIRTUALSCREEN:
3209 return PSEUDO_SCREEN_WIDTH;
3210 case SM_CYSCREEN:
3211 case SM_CYVIRTUALSCREEN:
3212 return PSEUDO_SCREEN_HEIGHT;
3213 case SM_CMONITORS:
3214 return 1;
3216 #endif
3217 return 1;
3219 static int WINAPI expGetSysColor(int index)
3221 dbgprintf("GetSysColor(%d) => 1\n", index);
3222 return 1;
3224 static int WINAPI expGetSysColorBrush(int index)
3226 dbgprintf("GetSysColorBrush(%d)\n", index);
3227 return 1;
3232 static int WINAPI expGetSystemPaletteEntries(int hdc, int iStartIndex, int nEntries, void* lppe)
3234 dbgprintf("GetSystemPaletteEntries(0x%x, 0x%x, 0x%x, 0x%x) => 0\n",
3235 hdc, iStartIndex, nEntries, lppe);
3236 return 0;
3240 typedef struct TIME_ZONE_INFORMATION {
3241 long Bias;
3242 char StandardName[32];
3243 SYSTEMTIME StandardDate;
3244 long StandardBias;
3245 char DaylightName[32];
3246 SYSTEMTIME DaylightDate;
3247 long DaylightBias;
3248 } TIME_ZONE_INFORMATION, *LPTIME_ZONE_INFORMATION;
3251 static int WINAPI expGetTimeZoneInformation(LPTIME_ZONE_INFORMATION lpTimeZoneInformation)
3253 const short name[]={'C', 'e', 'n', 't', 'r', 'a', 'l', ' ', 'S', 't', 'a',
3254 'n', 'd', 'a', 'r', 'd', ' ', 'T', 'i', 'm', 'e', 0};
3255 const short pname[]={'C', 'e', 'n', 't', 'r', 'a', 'l', ' ', 'D', 'a', 'y',
3256 'l', 'i', 'g', 'h', 't', ' ', 'T', 'i', 'm', 'e', 0};
3257 dbgprintf("GetTimeZoneInformation(0x%x) => TIME_ZONE_ID_STANDARD\n");
3258 memset(lpTimeZoneInformation, 0, sizeof(TIME_ZONE_INFORMATION));
3259 lpTimeZoneInformation->Bias=360;//GMT-6
3260 memcpy(lpTimeZoneInformation->StandardName, name, sizeof(name));
3261 lpTimeZoneInformation->StandardDate.wMonth=10;
3262 lpTimeZoneInformation->StandardDate.wDay=5;
3263 lpTimeZoneInformation->StandardDate.wHour=2;
3264 lpTimeZoneInformation->StandardBias=0;
3265 memcpy(lpTimeZoneInformation->DaylightName, pname, sizeof(pname));
3266 lpTimeZoneInformation->DaylightDate.wMonth=4;
3267 lpTimeZoneInformation->DaylightDate.wDay=1;
3268 lpTimeZoneInformation->DaylightDate.wHour=2;
3269 lpTimeZoneInformation->DaylightBias=-60;
3270 return TIME_ZONE_ID_STANDARD;
3273 static void WINAPI expGetLocalTime(SYSTEMTIME* systime)
3275 time_t local_time;
3276 struct tm *local_tm;
3277 struct timeval tv;
3279 dbgprintf("GetLocalTime(0x%x)\n");
3280 gettimeofday(&tv, NULL);
3281 local_time=tv.tv_sec;
3282 local_tm=localtime(&local_time);
3284 systime->wYear = local_tm->tm_year + 1900;
3285 systime->wMonth = local_tm->tm_mon + 1;
3286 systime->wDayOfWeek = local_tm->tm_wday;
3287 systime->wDay = local_tm->tm_mday;
3288 systime->wHour = local_tm->tm_hour;
3289 systime->wMinute = local_tm->tm_min;
3290 systime->wSecond = local_tm->tm_sec;
3291 systime->wMilliseconds = (tv.tv_usec / 1000) % 1000;
3292 dbgprintf(" Year: %d\n Month: %d\n Day of week: %d\n"
3293 " Day: %d\n Hour: %d\n Minute: %d\n Second: %d\n"
3294 " Milliseconds: %d\n",
3295 systime->wYear, systime->wMonth, systime->wDayOfWeek, systime->wDay,
3296 systime->wHour, systime->wMinute, systime->wSecond, systime->wMilliseconds);
3299 static int WINAPI expGetSystemTime(SYSTEMTIME* systime)
3301 time_t local_time;
3302 struct tm *local_tm;
3303 struct timeval tv;
3305 dbgprintf("GetSystemTime(0x%x)\n", systime);
3306 gettimeofday(&tv, NULL);
3307 local_time=tv.tv_sec;
3308 local_tm=gmtime(&local_time);
3310 systime->wYear = local_tm->tm_year + 1900;
3311 systime->wMonth = local_tm->tm_mon + 1;
3312 systime->wDayOfWeek = local_tm->tm_wday;
3313 systime->wDay = local_tm->tm_mday;
3314 systime->wHour = local_tm->tm_hour;
3315 systime->wMinute = local_tm->tm_min;
3316 systime->wSecond = local_tm->tm_sec;
3317 systime->wMilliseconds = (tv.tv_usec / 1000) % 1000;
3318 dbgprintf(" Year: %d\n Month: %d\n Day of week: %d\n"
3319 " Day: %d\n Hour: %d\n Minute: %d\n Second: %d\n"
3320 " Milliseconds: %d\n",
3321 systime->wYear, systime->wMonth, systime->wDayOfWeek, systime->wDay,
3322 systime->wHour, systime->wMinute, systime->wSecond, systime->wMilliseconds);
3323 return 0;
3326 #define SECS_1601_TO_1970 ((369 * 365 + 89) * 86400ULL)
3327 static void WINAPI expGetSystemTimeAsFileTime(FILETIME* systime)
3329 struct timeval tv;
3330 unsigned long long secs;
3332 dbgprintf("GetSystemTime(0x%x)\n", systime);
3333 gettimeofday(&tv, NULL);
3334 secs = (tv.tv_sec + SECS_1601_TO_1970) * 10000000;
3335 secs += tv.tv_usec * 10;
3336 systime->dwLowDateTime = secs & 0xffffffff;
3337 systime->dwHighDateTime = (secs >> 32);
3340 static int WINAPI expGetEnvironmentVariableA(const char* name, char* field, int size)
3342 //char *p;
3343 // printf("%s %x %x\n", name, field, size);
3344 if(field)field[0]=0;
3346 p = getenv(name);
3347 if (p) strncpy(field,p,size);
3349 if (strcmp(name,"__MSVCRT_HEAP_SELECT")==0)
3350 strcpy(field,"__GLOBAL_HEAP_SELECTED,1");
3351 dbgprintf("GetEnvironmentVariableA(0x%x='%s', 0x%x, %d) => %d\n", name, name, field, size, strlen(field));
3352 return strlen(field);
3355 static int WINAPI expSetEnvironmentVariableA(const char *name, const char *value)
3357 dbgprintf("SetEnvironmentVariableA(%s, %s)\n", name, value);
3358 return 0;
3361 static void* WINAPI expCoTaskMemAlloc(ULONG cb)
3363 return my_mreq(cb, 0);
3365 static void WINAPI expCoTaskMemFree(void* cb)
3367 my_release(cb);
3373 void* CoTaskMemAlloc(unsigned long cb)
3375 return expCoTaskMemAlloc(cb);
3377 void CoTaskMemFree(void* cb)
3379 expCoTaskMemFree(cb);
3382 struct COM_OBJECT_INFO
3384 GUID clsid;
3385 long (*GetClassObject) (GUID* clsid, const GUID* iid, void** ppv);
3388 static struct COM_OBJECT_INFO* com_object_table=0;
3389 static int com_object_size=0;
3390 int RegisterComClass(const GUID* clsid, GETCLASSOBJECT gcs)
3392 if(!clsid || !gcs)
3393 return -1;
3394 com_object_table=realloc(com_object_table, sizeof(struct COM_OBJECT_INFO)*(++com_object_size));
3395 com_object_table[com_object_size-1].clsid=*clsid;
3396 com_object_table[com_object_size-1].GetClassObject=gcs;
3397 return 0;
3400 int UnregisterComClass(const GUID* clsid, GETCLASSOBJECT gcs)
3402 int found = 0;
3403 int i = 0;
3404 if(!clsid || !gcs)
3405 return -1;
3407 if (com_object_table == 0)
3408 printf("Warning: UnregisterComClass() called without any registered class\n");
3409 while (i < com_object_size)
3411 if (found && i > 0)
3413 memcpy(&com_object_table[i - 1].clsid,
3414 &com_object_table[i].clsid, sizeof(GUID));
3415 com_object_table[i - 1].GetClassObject =
3416 com_object_table[i].GetClassObject;
3418 else if (memcmp(&com_object_table[i].clsid, clsid, sizeof(GUID)) == 0
3419 && com_object_table[i].GetClassObject == gcs)
3421 found++;
3423 i++;
3425 if (found)
3427 if (--com_object_size == 0)
3429 free(com_object_table);
3430 com_object_table = 0;
3433 return 0;
3437 const GUID IID_IUnknown =
3439 0x00000000, 0x0000, 0x0000,
3440 {0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}
3442 const GUID IID_IClassFactory =
3444 0x00000001, 0x0000, 0x0000,
3445 {0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}
3448 static long WINAPI expCoCreateInstance(GUID* rclsid, struct IUnknown* pUnkOuter,
3449 long dwClsContext, const GUID* riid, void** ppv)
3451 int i;
3452 struct COM_OBJECT_INFO* ci=0;
3453 for(i=0; i<com_object_size; i++)
3454 if(!memcmp(rclsid, &com_object_table[i].clsid, sizeof(GUID)))
3455 ci=&com_object_table[i];
3456 if(!ci)return REGDB_E_CLASSNOTREG;
3457 // in 'real' world we should mess with IClassFactory here
3458 i=ci->GetClassObject(rclsid, riid, ppv);
3459 return i;
3462 long CoCreateInstance(GUID* rclsid, struct IUnknown* pUnkOuter,
3463 long dwClsContext, const GUID* riid, void** ppv)
3465 return expCoCreateInstance(rclsid, pUnkOuter, dwClsContext, riid, ppv);
3468 static int WINAPI expIsRectEmpty(CONST RECT *lprc)
3470 int r = 0;
3471 int w,h;
3472 //trapbug();
3473 if (lprc)
3475 w = lprc->right - lprc->left;
3476 h = lprc->bottom - lprc->top;
3477 if (w <= 0 || h <= 0)
3478 r = 1;
3480 else
3481 r = 1;
3483 dbgprintf("IsRectEmpty(%p) => %s\n", lprc, (r) ? "TRUE" : "FALSE");
3484 //printf("Rect: left: %d, top: %d, right: %d, bottom: %d\n", lprc->left, lprc->top, lprc->right, lprc->bottom);
3485 // return 0; // wmv9?
3486 return r; // TM20
3489 static int _adjust_fdiv=0; //what's this? - used to adjust division
3490 static int _winver = 0x510; // windows version
3495 static unsigned int WINAPI expGetTempPathA(unsigned int len, char* path)
3497 dbgprintf("GetTempPathA(%d, 0x%x)", len, path);
3498 if(len<5)
3500 dbgprintf(" => 0\n");
3501 return 0;
3503 strcpy(path, "/tmp");
3504 dbgprintf(" => 5 ( '/tmp' )\n");
3505 return 5;
3508 FYI:
3509 typedef struct
3511 DWORD dwFileAttributes;
3512 FILETIME ftCreationTime;
3513 FILETIME ftLastAccessTime;
3514 FILETIME ftLastWriteTime;
3515 DWORD nFileSizeHigh;
3516 DWORD nFileSizeLow;
3517 DWORD dwReserved0;
3518 DWORD dwReserved1;
3519 CHAR cFileName[260];
3520 CHAR cAlternateFileName[14];
3521 } WIN32_FIND_DATAA, *LPWIN32_FIND_DATAA;
3524 static DIR* qtx_dir=NULL;
3526 static WIN_BOOL WINAPI expFindNextFileA(HANDLE h,LPWIN32_FIND_DATAA lpfd)
3528 #ifdef CONFIG_QTX_CODECS
3529 dbgprintf("FindNextFileA(0x%x, 0x%x) => 0\n", h, lpfd);
3530 if(h==FILE_HANDLE_quicktimeqtx){
3531 struct dirent* d;
3532 if(!qtx_dir) return 0;
3533 while((d=readdir(qtx_dir))){
3534 char* x=strrchr(d->d_name,'.');
3535 if(!x) continue;
3536 if(strcmp(x,".qtx")) continue;
3537 strcpy(lpfd->cFileName,d->d_name);
3538 // sprintf(lpfd->cAlternateFileName,"%-8s.qtx",d->d_name);
3539 strcpy(lpfd->cAlternateFileName,"foobar.qtx");
3540 dbgprintf("### FindNext: %s\n",lpfd->cFileName);
3541 return 1;
3543 closedir(qtx_dir); qtx_dir=NULL;
3544 return 0;
3546 #endif
3547 return 0;
3550 static HANDLE WINAPI expFindFirstFileA(LPCSTR s, LPWIN32_FIND_DATAA lpfd)
3552 dbgprintf("FindFirstFileA(0x%x='%s', 0x%x) => 0\n", s, s, lpfd);
3553 // printf("\n### FindFirstFileA('%s')...\n",s);
3554 #ifdef CONFIG_QTX_CODECS
3555 if(strstr(s, "quicktime\\*.QTX")){
3556 dbgprintf("FindFirstFileA(0x%x='%s', 0x%x) => QTX\n", s, s, lpfd);
3557 dbgprintf("\n### Searching for QuickTime plugins (*.qtx) at %s...\n",def_path);
3558 qtx_dir=opendir(def_path);
3559 if(!qtx_dir) return (HANDLE)-1;
3560 memset(lpfd,0,sizeof(*lpfd));
3561 if(expFindNextFileA(FILE_HANDLE_quicktimeqtx,lpfd))
3562 return FILE_HANDLE_quicktimeqtx;
3563 printf("loader: Couldn't find the QuickTime plugins (.qtx files) at %s\n",def_path);
3564 return (HANDLE)-1;
3566 #if 0
3567 if(strstr(s, "QuickTime.qts")){
3568 dbgprintf("FindFirstFileA(0x%x='%s', 0x%x) => QTS\n", s, s, lpfd);
3569 // if(!strcmp(s,"C:\\windows\\QuickTime.qts\\QuickTime.qts\\*.QTX"))
3570 // return (HANDLE)-1;
3571 strcpy(lpfd->cFileName, "QuickTime.qts");
3572 strcpy(lpfd->cAlternateFileName, "QuickT~1.qts");
3573 return FILE_HANDLE_quicktimeqts;
3575 #endif
3576 #endif
3577 if(strstr(s, "*.vwp")){
3578 // hack for VoxWare codec plugins:
3579 strcpy(lpfd->cFileName, "msms001.vwp");
3580 strcpy(lpfd->cAlternateFileName, "msms001.vwp");
3581 return (HANDLE)0;
3583 // return 'file not found'
3584 return (HANDLE)-1;
3587 static WIN_BOOL WINAPI expFindClose(HANDLE h)
3589 dbgprintf("FindClose(0x%x) => 0\n", h);
3590 #ifdef CONFIG_QTX_CODECS
3591 // if(h==FILE_HANDLE_quicktimeqtx && qtx_dir){
3592 // closedir(qtx_dir);
3593 // qtx_dir=NULL;
3594 // }
3595 #endif
3596 return 0;
3598 static UINT WINAPI expSetErrorMode(UINT i)
3600 dbgprintf("SetErrorMode(%d) => 0\n", i);
3601 return 0;
3603 static UINT WINAPI expGetWindowsDirectoryA(LPSTR s,UINT c)
3605 char windir[]="c:\\windows";
3606 int result;
3607 strncpy(s, windir, c);
3608 result=1+((c<strlen(windir))?c:strlen(windir));
3609 dbgprintf("GetWindowsDirectoryA(0x%x, %d) => %d\n", s, c, result);
3610 return result;
3612 #ifdef CONFIG_QTX_CODECS
3613 static UINT WINAPI expGetCurrentDirectoryA(UINT c, LPSTR s)
3615 char curdir[]="c:\\";
3616 int result;
3617 strncpy(s, curdir, c);
3618 result=1+((c<strlen(curdir))?c:strlen(curdir));
3619 dbgprintf("GetCurrentDirectoryA(0x%x, %d) => %d\n", s, c, result);
3620 return result;
3623 static int WINAPI expSetCurrentDirectoryA(const char *pathname)
3625 dbgprintf("SetCurrentDirectoryA(0x%x = %s) => 1\n", pathname, pathname);
3626 #if 0
3627 if (strrchr(pathname, '\\'))
3628 chdir(strcat(strrchr(pathname, '\\')+1, '/'));
3629 else
3630 chdir(pathname);
3631 #endif
3632 return 1;
3635 static int WINAPI expCreateDirectoryA(const char *pathname, void *sa)
3637 dbgprintf("CreateDirectory(0x%x = %s, 0x%x) => 1\n",
3638 pathname, pathname, sa);
3639 #if 0
3640 p = strrchr(pathname, '\\')+1;
3641 strcpy(&buf[0], p); /* should be strncpy */
3642 if (!strlen(p))
3644 buf[0] = '.';
3645 buf[1] = 0;
3647 #if 0
3648 if (strrchr(pathname, '\\'))
3649 mkdir(strcat(strrchr(pathname, '\\')+1, '/'), 666);
3650 else
3651 mkdir(pathname, 666);
3652 #endif
3653 mkdir(&buf);
3654 #endif
3655 return 1;
3657 #endif
3658 static WIN_BOOL WINAPI expDeleteFileA(LPCSTR s)
3660 dbgprintf("DeleteFileA(0x%x='%s') => 0\n", s, s);
3661 return 0;
3663 static WIN_BOOL WINAPI expFileTimeToLocalFileTime(const FILETIME* cpf, LPFILETIME pf)
3665 dbgprintf("FileTimeToLocalFileTime(0x%x, 0x%x) => 0\n", cpf, pf);
3666 return 0;
3669 static UINT WINAPI expGetTempFileNameA(LPCSTR cs1,LPCSTR cs2,UINT i,LPSTR ps)
3671 char mask[16]="/tmp/AP_XXXXXX";
3672 int result;
3673 dbgprintf("GetTempFileNameA(0x%x='%s', 0x%x='%s', %d, 0x%x)", cs1, cs1, cs2, cs2, i, ps);
3674 if(i && i<10)
3676 dbgprintf(" => -1\n");
3677 return -1;
3679 result=mkstemp(mask);
3680 sprintf(ps, "AP%d", result);
3681 dbgprintf(" => %d\n", strlen(ps));
3682 return strlen(ps);
3685 // This func might need proper implementation if we want AngelPotion codec.
3686 // They try to open APmpeg4v1.apl with it.
3687 // DLL will close opened file with CloseHandle().
3689 static HANDLE WINAPI expCreateFileA(LPCSTR cs1,DWORD i1,DWORD i2,
3690 LPSECURITY_ATTRIBUTES p1, DWORD i3,DWORD i4,HANDLE i5)
3692 dbgprintf("CreateFileA(0x%x='%s', %d, %d, 0x%x, %d, %d, 0x%x)\n", cs1, cs1, i1,
3693 i2, p1, i3, i4, i5);
3694 if((!cs1) || (strlen(cs1)<2))return -1;
3696 #ifdef CONFIG_QTX_CODECS
3697 if(strstr(cs1, "QuickTime.qts"))
3699 int result;
3700 char* tmp=malloc(strlen(def_path)+50);
3701 strcpy(tmp, def_path);
3702 strcat(tmp, "/");
3703 strcat(tmp, "QuickTime.qts");
3704 result=open(tmp, O_RDONLY);
3705 free(tmp);
3706 return result;
3708 if(strstr(cs1, ".qtx"))
3710 int result;
3711 char* tmp=malloc(strlen(def_path)+250);
3712 char* x=strrchr(cs1,'\\');
3713 sprintf(tmp,"%s/%s",def_path,x?(x+1):cs1);
3714 // printf("### Open: %s -> %s\n",cs1,tmp);
3715 result=open(tmp, O_RDONLY);
3716 free(tmp);
3717 return result;
3719 #endif
3721 if(strncmp(cs1, "AP", 2) == 0)
3723 int result;
3724 char* tmp=malloc(strlen(def_path)+50);
3725 strcpy(tmp, def_path);
3726 strcat(tmp, "/");
3727 strcat(tmp, "APmpg4v1.apl");
3728 result=open(tmp, O_RDONLY);
3729 free(tmp);
3730 return result;
3732 if (strstr(cs1, "vp3") || strstr(cs1, ".fpf"))
3734 int r;
3735 int flg = 0;
3736 char* tmp=malloc(20 + strlen(cs1));
3737 strcpy(tmp, "/tmp/");
3738 strcat(tmp, cs1);
3739 r = 4;
3740 while (tmp[r])
3742 if (tmp[r] == ':' || tmp[r] == '\\')
3743 tmp[r] = '_';
3744 r++;
3746 if (GENERIC_READ & i1)
3747 flg |= O_RDONLY;
3748 else if (GENERIC_WRITE & i1)
3750 flg |= O_WRONLY | O_CREAT;
3751 printf("Warning: openning filename %s %d (flags; 0x%x) for write\n", tmp, r, flg);
3753 r=open(tmp, flg, S_IRWXU);
3754 free(tmp);
3755 return r;
3758 // Needed by wnvplay1.dll
3759 if (strstr(cs1, "WINNOV.bmp"))
3761 int r;
3762 r=open("/dev/null", O_RDONLY);
3763 return r;
3766 #if 0
3767 /* we need this for some virtualdub filters */
3769 int r;
3770 int flg = 0;
3771 if (GENERIC_READ & i1)
3772 flg |= O_RDONLY;
3773 else if (GENERIC_WRITE & i1)
3775 flg |= O_WRONLY;
3776 printf("Warning: openning filename %s %d (flags; 0x%x) for write\n", cs1, r, flg);
3778 r=open(cs1, flg);
3779 return r;
3781 #endif
3783 return atoi(cs1+2);
3785 static UINT WINAPI expGetSystemDirectoryA(
3786 char* lpBuffer, // address of buffer for system directory
3787 UINT uSize // size of directory buffer
3789 dbgprintf("GetSystemDirectoryA(%p,%d)\n", lpBuffer,uSize);
3790 if(!lpBuffer) strcpy(lpBuffer,".");
3791 return 1;
3794 static char sysdir[]=".";
3795 static LPCSTR WINAPI expGetSystemDirectoryA(void)
3797 dbgprintf("GetSystemDirectoryA() => 0x%x='%s'\n", sysdir, sysdir);
3798 return sysdir;
3801 static DWORD WINAPI expGetFullPathNameA
3803 LPCTSTR lpFileName,
3804 DWORD nBufferLength,
3805 LPTSTR lpBuffer,
3806 LPTSTR lpFilePart
3808 if(!lpFileName) return 0;
3809 dbgprintf("GetFullPathNameA('%s',%d,%p,%p)\n",lpFileName,nBufferLength,
3810 lpBuffer, lpFilePart);
3811 #if 0
3812 #ifdef CONFIG_QTX_CODECS
3813 strcpy(lpFilePart, "Quick123.qts");
3814 #else
3815 strcpy(lpFilePart, lpFileName);
3816 #endif
3817 #else
3818 if (strrchr(lpFileName, '\\'))
3819 lpFilePart = strrchr(lpFileName, '\\');
3820 else
3821 lpFilePart = (LPTSTR)lpFileName;
3822 #endif
3823 strcpy(lpBuffer, lpFileName);
3824 // strncpy(lpBuffer, lpFileName, rindex(lpFileName, '\\')-lpFileName);
3825 return strlen(lpBuffer);
3828 static DWORD WINAPI expGetShortPathNameA
3830 LPCSTR longpath,
3831 LPSTR shortpath,
3832 DWORD shortlen
3834 if(!longpath) return 0;
3835 dbgprintf("GetShortPathNameA('%s',%p,%d)\n",longpath,shortpath,shortlen);
3836 strcpy(shortpath,longpath);
3837 return strlen(shortpath);
3840 static WIN_BOOL WINAPI expReadFile(HANDLE h,LPVOID pv,DWORD size,LPDWORD rd,LPOVERLAPPED unused)
3842 int result;
3843 dbgprintf("ReadFile(%d, 0x%x, %d -> 0x%x)\n", h, pv, size, rd);
3844 result=read(h, pv, size);
3845 if(rd)*rd=result;
3846 if(!result)return 0;
3847 return 1;
3850 static WIN_BOOL WINAPI expWriteFile(HANDLE h,LPCVOID pv,DWORD size,LPDWORD wr,LPOVERLAPPED unused)
3852 int result;
3853 dbgprintf("WriteFile(%d, 0x%x, %d -> 0x%x)\n", h, pv, size, wr);
3854 if(h==1234)h=1;
3855 result=write(h, pv, size);
3856 if(wr)*wr=result;
3857 if(!result)return 0;
3858 return 1;
3860 static DWORD WINAPI expSetFilePointer(HANDLE h, LONG val, LPLONG ext, DWORD whence)
3862 int wh;
3863 dbgprintf("SetFilePointer(%d, 0x%x, 0x%x = %d, %d)\n", h, val, ext, ext ? *ext : NULL, whence);
3864 //why would DLL want temporary file with >2Gb size?
3865 switch(whence)
3867 case FILE_BEGIN:
3868 wh=SEEK_SET;break;
3869 case FILE_END:
3870 wh=SEEK_END;break;
3871 case FILE_CURRENT:
3872 wh=SEEK_CUR;break;
3873 default:
3874 return -1;
3876 #ifdef CONFIG_QTX_CODECS
3877 if (val == 0 && ext != 0)
3878 val = val&(*ext);
3879 #endif
3880 return lseek(h, val, wh);
3883 static HDRVR WINAPI expOpenDriverA(LPCSTR szDriverName, LPCSTR szSectionName,
3884 LPARAM lParam2)
3886 dbgprintf("OpenDriverA(0x%x='%s', 0x%x='%s', 0x%x) => -1\n", szDriverName, szDriverName, szSectionName, szSectionName, lParam2);
3887 return -1;
3889 static HDRVR WINAPI expOpenDriver(LPCSTR szDriverName, LPCSTR szSectionName,
3890 LPARAM lParam2)
3892 dbgprintf("OpenDriver(0x%x='%s', 0x%x='%s', 0x%x) => -1\n", szDriverName, szDriverName, szSectionName, szSectionName, lParam2);
3893 return -1;
3897 static WIN_BOOL WINAPI expGetProcessAffinityMask(HANDLE hProcess,
3898 LPDWORD lpProcessAffinityMask,
3899 LPDWORD lpSystemAffinityMask)
3901 dbgprintf("GetProcessAffinityMask(0x%x, 0x%x, 0x%x) => 1\n",
3902 hProcess, lpProcessAffinityMask, lpSystemAffinityMask);
3903 if(lpProcessAffinityMask)*lpProcessAffinityMask=1;
3904 if(lpSystemAffinityMask)*lpSystemAffinityMask=1;
3905 return 1;
3908 // Fake implementation: does nothing, but does it right :)
3909 static WIN_BOOL WINAPI expSetProcessAffinityMask(HANDLE hProcess,
3910 LPDWORD dwProcessAffinityMask)
3912 dbgprintf("SetProcessAffinityMask(0x%x, 0x%x) => 1\n",
3913 hProcess, dwProcessAffinityMask);
3915 return 1;
3918 static int WINAPI expMulDiv(int nNumber, int nNumerator, int nDenominator)
3920 static const long long max_int=0x7FFFFFFFLL;
3921 static const long long min_int=-0x80000000LL;
3922 long long tmp=(long long)nNumber*(long long)nNumerator;
3923 dbgprintf("expMulDiv %d * %d / %d\n", nNumber, nNumerator, nDenominator);
3924 if(!nDenominator)return 1;
3925 tmp/=nDenominator;
3926 if(tmp<min_int) return 1;
3927 if(tmp>max_int) return 1;
3928 return (int)tmp;
3931 static LONG WINAPI explstrcmpiA(const char* str1, const char* str2)
3933 LONG result=strcasecmp(str1, str2);
3934 dbgprintf("strcmpi(0x%x='%s', 0x%x='%s') => %d\n", str1, str1, str2, str2, result);
3935 return result;
3938 static LONG WINAPI explstrlenA(const char* str1)
3940 LONG result=strlen(str1);
3941 dbgprintf("strlen(0x%x='%.50s') => %d\n", str1, str1, result);
3942 return result;
3945 static LONG WINAPI explstrcpyA(char* str1, const char* str2)
3947 int result= (int) strcpy(str1, str2);
3948 dbgprintf("strcpy(0x%.50x, 0x%.50x='%.50s') => %d\n", str1, str2, str2, result);
3949 return result;
3951 static LONG WINAPI explstrcpynA(char* str1, const char* str2,int len)
3953 int result;
3954 if (strlen(str2)>len)
3955 result = (int) strncpy(str1, str2,len);
3956 else
3957 result = (int) strcpy(str1,str2);
3958 dbgprintf("strncpy(0x%x, 0x%x='%s' len %d strlen %d) => %x\n", str1, str2, str2,len, strlen(str2),result);
3959 return result;
3961 static LONG WINAPI explstrcatA(char* str1, const char* str2)
3963 int result= (int) strcat(str1, str2);
3964 dbgprintf("strcat(0x%x, 0x%x='%s') => %d\n", str1, str2, str2, result);
3965 return result;
3969 static LONG WINAPI expInterlockedExchange(long *dest, long l)
3971 long retval = *dest;
3972 *dest = l;
3973 return retval;
3976 static void WINAPI expInitCommonControls(void)
3978 dbgprintf("InitCommonControls called!\n");
3979 return;
3982 #ifdef CONFIG_QTX_CODECS
3983 /* needed by QuickTime.qts */
3984 static HWND WINAPI expCreateUpDownControl (DWORD style, INT x, INT y, INT cx, INT cy,
3985 HWND parent, INT id, HINSTANCE inst,
3986 HWND buddy, INT maxVal, INT minVal, INT curVal)
3988 dbgprintf("CreateUpDownControl(...)\n");
3989 return 0;
3991 #endif
3993 /* alex: implement this call! needed for 3ivx */
3994 static HRESULT WINAPI expCoCreateFreeThreadedMarshaler(void *pUnkOuter, void **ppUnkInner)
3996 dbgprintf("CoCreateFreeThreadedMarshaler(%p, %p) called!\n",
3997 pUnkOuter, ppUnkInner);
3998 // return 0;
3999 return ERROR_CALL_NOT_IMPLEMENTED;
4003 static int WINAPI expDuplicateHandle(HANDLE hSourceProcessHandle, // handle to source process
4004 HANDLE hSourceHandle, // handle to duplicate
4005 HANDLE hTargetProcessHandle, // handle to target process
4006 HANDLE* lpTargetHandle, // duplicate handle
4007 DWORD dwDesiredAccess, // requested access
4008 int bInheritHandle, // handle inheritance option
4009 DWORD dwOptions // optional actions
4012 dbgprintf("DuplicateHandle(%p, %p, %p, %p, 0x%x, %d, %d) called\n",
4013 hSourceProcessHandle, hSourceHandle, hTargetProcessHandle,
4014 lpTargetHandle, dwDesiredAccess, bInheritHandle, dwOptions);
4015 *lpTargetHandle = hSourceHandle;
4016 return 1;
4019 static HRESULT WINAPI expCoInitializeEx(LPVOID lpReserved, DWORD dwCoInit)
4021 dbgprintf("CoInitializeEx(%p, %d) called\n", lpReserved, dwCoInit);
4022 return S_OK;
4025 // required by PIM1 codec (used by win98 PCTV Studio capture sw)
4026 static HRESULT WINAPI expCoInitialize(
4027 LPVOID lpReserved /* [in] pointer to win32 malloc interface
4028 (obsolete, should be NULL) */
4032 * Just delegate to the newer method.
4034 return expCoInitializeEx(lpReserved, COINIT_APARTMENTTHREADED);
4037 static void WINAPI expCoUninitialize(void)
4039 dbgprintf("CoUninitialize() called\n");
4042 /* allow static linking */
4043 HRESULT WINAPI CoInitializeEx(LPVOID lpReserved, DWORD dwCoInit)
4045 return expCoInitializeEx(lpReserved, dwCoInit);
4047 HRESULT WINAPI CoInitialize(LPVOID lpReserved)
4049 return expCoInitialize(lpReserved);
4051 void WINAPI CoUninitialize(void)
4053 expCoUninitialize();
4056 static DWORD WINAPI expSetThreadAffinityMask
4058 HANDLE hThread,
4059 DWORD dwThreadAffinityMask
4061 return 0;
4065 * no WINAPI functions - CDECL
4067 static void* expmalloc(int size)
4069 //printf("malloc");
4070 // return malloc(size);
4071 void* result=my_mreq(size,0);
4072 dbgprintf("malloc(0x%x) => 0x%x\n", size,result);
4073 if(result==0)
4074 printf("WARNING: malloc() failed\n");
4075 return result;
4077 static void expfree(void* mem)
4079 // return free(mem);
4080 dbgprintf("free(%p)\n", mem);
4081 my_release(mem);
4083 /* needed by atrac3.acm */
4084 static void *expcalloc(int num, int size)
4086 void* result=my_mreq(num*size,1);
4087 dbgprintf("calloc(%d,%d) => %p\n", num,size,result);
4088 if(result==0)
4089 printf("WARNING: calloc() failed\n");
4090 return result;
4092 static void* expnew(int size)
4094 // printf("NEW:: Call from address %08x\n STACK DUMP:\n", *(-1+(int*)&size));
4095 // printf("%08x %08x %08x %08x\n",
4096 // size, *(1+(int*)&size),
4097 // *(2+(int*)&size),*(3+(int*)&size));
4098 void* result;
4099 assert(size >= 0);
4101 result=my_mreq(size,0);
4102 dbgprintf("new(%d) => %p\n", size, result);
4103 if (result==0)
4104 printf("WARNING: new() failed\n");
4105 return result;
4108 static int expdelete(void* memory)
4110 dbgprintf("delete(%p)\n", memory);
4111 my_release(memory);
4112 return 0;
4116 * local definition - we need only the last two members at this point
4117 * otherwice we would have to introduce here GUIDs and some more types..
4119 typedef struct __attribute__((__packed__))
4121 char hay[0x40];
4122 unsigned long cbFormat; //0x40
4123 char* pbFormat; //0x44
4124 } MY_MEDIA_TYPE;
4125 static HRESULT WINAPI expMoCopyMediaType(MY_MEDIA_TYPE* dest, const MY_MEDIA_TYPE* src)
4127 if (!dest || !src)
4128 return E_POINTER;
4129 memcpy(dest, src, sizeof(MY_MEDIA_TYPE));
4130 if (dest->cbFormat)
4132 dest->pbFormat = (char*) my_mreq(dest->cbFormat, 0);
4133 if (!dest->pbFormat)
4134 return E_OUTOFMEMORY;
4135 memcpy(dest->pbFormat, src->pbFormat, dest->cbFormat);
4137 return S_OK;
4139 static HRESULT WINAPI expMoInitMediaType(MY_MEDIA_TYPE* dest, DWORD cbFormat)
4141 if (!dest)
4142 return E_POINTER;
4143 memset(dest, 0, sizeof(MY_MEDIA_TYPE));
4144 if (cbFormat)
4146 dest->pbFormat = (char*) my_mreq(cbFormat, 0);
4147 if (!dest->pbFormat)
4148 return E_OUTOFMEMORY;
4150 return S_OK;
4152 static HRESULT WINAPI expMoCreateMediaType(MY_MEDIA_TYPE** dest, DWORD cbFormat)
4154 if (!dest)
4155 return E_POINTER;
4156 *dest = my_mreq(sizeof(MY_MEDIA_TYPE), 0);
4157 return expMoInitMediaType(*dest, cbFormat);
4159 static HRESULT WINAPI expMoDuplicateMediaType(MY_MEDIA_TYPE** dest, const void* src)
4161 if (!dest)
4162 return E_POINTER;
4163 *dest = my_mreq(sizeof(MY_MEDIA_TYPE), 0);
4164 return expMoCopyMediaType(*dest, src);
4166 static HRESULT WINAPI expMoFreeMediaType(MY_MEDIA_TYPE* dest)
4168 if (!dest)
4169 return E_POINTER;
4170 if (dest->pbFormat)
4172 my_release(dest->pbFormat);
4173 dest->pbFormat = 0;
4174 dest->cbFormat = 0;
4176 return S_OK;
4178 static HRESULT WINAPI expMoDeleteMediaType(MY_MEDIA_TYPE* dest)
4180 if (!dest)
4181 return E_POINTER;
4182 expMoFreeMediaType(dest);
4183 my_release(dest);
4184 return S_OK;
4187 static int exp_snprintf( char *str, int size, const char *format, ... )
4189 int x;
4190 va_list va;
4191 va_start(va, format);
4192 x=snprintf(str,size,format,va);
4193 dbgprintf("_snprintf( 0x%x, %d, %s, ... ) => %d\n",str,size,format,x);
4194 va_end(va);
4195 return x;
4198 #if 0
4199 static int exp_initterm(int v1, int v2)
4201 dbgprintf("_initterm(0x%x, 0x%x) => 0\n", v1, v2);
4202 return 0;
4204 #else
4205 /* merged from wine - 2002.04.21 */
4206 typedef void (*INITTERMFUNC)();
4207 static int exp_initterm(INITTERMFUNC *start, INITTERMFUNC *end)
4209 dbgprintf("_initterm(0x%x, 0x%x) %p\n", start, end, *start);
4210 while (start < end)
4212 if (*start)
4214 //printf("call _initfunc: from: %p %d\n", *start);
4215 // ok this trick with push/pop is necessary as otherwice
4216 // edi/esi registers are being trashed
4217 void* p = *start;
4218 __asm__ volatile
4220 "pushl %%ebx \n\t"
4221 "pushl %%ecx \n\t"
4222 "pushl %%edx \n\t"
4223 "pushl %%edi \n\t"
4224 "pushl %%esi \n\t"
4225 "call *%%eax \n\t"
4226 "popl %%esi \n\t"
4227 "popl %%edi \n\t"
4228 "popl %%edx \n\t"
4229 "popl %%ecx \n\t"
4230 "popl %%ebx \n\t"
4232 : "a"(p)
4233 : "memory"
4235 //printf("done %p %d:%d\n", end);
4237 start++;
4239 return 0;
4241 #endif
4243 /* Fake _initterm_e from msvcr80.dll, needed by sirenacm.dll
4244 * NOTE: If I make this an alias for _initterm, then sirenacm.dll tries to call
4245 other uninmplemented functions; keep this in mind if some future codec needs
4246 a real implementation of this function */
4247 static int exp_initterm_e(INITTERMFUNC *start, INITTERMFUNC *end)
4249 dbgprintf("_initterm_e(0x%x, 0x%x)\n", start, end);
4250 return 0;
4253 static void* exp__dllonexit(void)
4255 // FIXME extract from WINE
4256 return NULL;
4259 static int expwsprintfA(char* string, const char* format, ...)
4261 va_list va;
4262 int result;
4263 va_start(va, format);
4264 result = vsprintf(string, format, va);
4265 dbgprintf("wsprintfA(0x%x, '%s', ...) => %d\n", string, format, result);
4266 va_end(va);
4267 return result;
4270 static int expsprintf(char* str, const char* format, ...)
4272 va_list args;
4273 int r;
4274 dbgprintf("sprintf(0x%x, %s)\n", str, format);
4275 va_start(args, format);
4276 r = vsprintf(str, format, args);
4277 va_end(args);
4278 return r;
4280 static int expsscanf(const char* str, const char* format, ...)
4282 va_list args;
4283 int r;
4284 dbgprintf("sscanf(%s, %s)\n", str, format);
4285 va_start(args, format);
4286 r = vsscanf(str, format, args);
4287 va_end(args);
4288 return r;
4290 static void* expfopen(const char* path, const char* mode)
4292 printf("fopen: \"%s\" mode:%s\n", path, mode);
4293 //return fopen(path, mode);
4294 return fdopen(0, mode); // everything on screen
4296 static int expfprintf(void* stream, const char* format, ...)
4298 va_list args;
4299 int r = 0;
4300 dbgprintf("fprintf(%p, %s, ...)\n", stream, format);
4301 va_start(args, format);
4302 r = vfprintf((FILE*) stream, format, args);
4303 va_end(args);
4304 return r;
4307 static int expprintf(const char* format, ...)
4309 va_list args;
4310 int r;
4311 dbgprintf("printf(%s, ...)\n", format);
4312 va_start(args, format);
4313 r = vprintf(format, args);
4314 va_end(args);
4315 return r;
4318 static char* expgetenv(const char* varname)
4320 char* v = getenv(varname);
4321 dbgprintf("getenv(%s) => %s\n", varname, v);
4322 return v;
4325 static void* expwcscpy(WCHAR* dst, const WCHAR* src)
4327 WCHAR* p = dst;
4328 while ((*p++ = *src++))
4330 return dst;
4333 static char* expstrrchr(char* string, int value)
4335 char* result=strrchr(string, value);
4336 if(result)
4337 dbgprintf("strrchr(0x%x='%s', %d) => 0x%x='%s'", string, string, value, result, result);
4338 else
4339 dbgprintf("strrchr(0x%x='%s', %d) => 0", string, string, value);
4340 return result;
4343 static char* expstrchr(char* string, int value)
4345 char* result=strchr(string, value);
4346 if(result)
4347 dbgprintf("strchr(0x%x='%s', %d) => 0x%x='%s'", string, string, value, result, result);
4348 else
4349 dbgprintf("strchr(0x%x='%s', %d) => 0", string, string, value);
4350 return result;
4352 static int expstrlen(char* str)
4354 int result=strlen(str);
4355 dbgprintf("strlen(0x%x='%s') => %d\n", str, str, result);
4356 return result;
4358 static char* expstrcpy(char* str1, const char* str2)
4360 char* result= strcpy(str1, str2);
4361 dbgprintf("strcpy(0x%x, 0x%x='%s') => %p\n", str1, str2, str2, result);
4362 return result;
4364 static char* expstrncpy(char* str1, const char* str2, size_t count)
4366 char* result= strncpy(str1, str2, count);
4367 dbgprintf("strncpy(0x%x, 0x%x='%s', %d) => %p\n", str1, str2, str2, count, result);
4368 return result;
4370 static int expstrcmp(const char* str1, const char* str2)
4372 int result=strcmp(str1, str2);
4373 dbgprintf("strcmp(0x%x='%s', 0x%x='%s') => %d\n", str1, str1, str2, str2, result);
4374 return result;
4376 static int expstrncmp(const char* str1, const char* str2,int x)
4378 int result=strncmp(str1, str2,x);
4379 dbgprintf("strcmp(0x%x='%s', 0x%x='%s') => %d\n", str1, str1, str2, str2, result);
4380 return result;
4382 static char* expstrcat(char* str1, const char* str2)
4384 char* result = strcat(str1, str2);
4385 dbgprintf("strcat(0x%x='%s', 0x%x='%s') => %p\n", str1, str1, str2, str2, result);
4386 return result;
4388 static char* exp_strdup(const char* str1)
4390 int l = strlen(str1);
4391 char* result = (char*) my_mreq(l + 1,0);
4392 if (result)
4393 strcpy(result, str1);
4394 dbgprintf("_strdup(0x%x='%s') => %p\n", str1, str1, result);
4395 return result;
4397 static int expisalnum(int c)
4399 int result= (int) isalnum(c);
4400 dbgprintf("isalnum(0x%x='%c' => %d\n", c, c, result);
4401 return result;
4403 static int expisspace(int c)
4405 int result= (int) isspace(c);
4406 dbgprintf("isspace(0x%x='%c' => %d\n", c, c, result);
4407 return result;
4409 static int expisalpha(int c)
4411 int result= (int) isalpha(c);
4412 dbgprintf("isalpha(0x%x='%c' => %d\n", c, c, result);
4413 return result;
4415 static int expisdigit(int c)
4417 int result= (int) isdigit(c);
4418 dbgprintf("isdigit(0x%x='%c' => %d\n", c, c, result);
4419 return result;
4421 static void* expmemmove(void* dest, void* src, int n)
4423 void* result = memmove(dest, src, n);
4424 dbgprintf("memmove(0x%x, 0x%x, %d) => %p\n", dest, src, n, result);
4425 return result;
4427 static int expmemcmp(void* dest, void* src, int n)
4429 int result = memcmp(dest, src, n);
4430 dbgprintf("memcmp(0x%x, 0x%x, %d) => %d\n", dest, src, n, result);
4431 return result;
4433 static void* expmemcpy(void* dest, void* src, int n)
4435 void *result = memcpy(dest, src, n);
4436 dbgprintf("memcpy(0x%x, 0x%x, %d) => %p\n", dest, src, n, result);
4437 return result;
4439 static void* expmemset(void* dest, int c, size_t n)
4441 void *result = memset(dest, c, n);
4442 dbgprintf("memset(0x%x, %d, %d) => %p\n", dest, c, n, result);
4443 return result;
4445 static time_t exptime(time_t* t)
4447 time_t result = time(t);
4448 dbgprintf("time(0x%x) => %d\n", t, result);
4449 return result;
4452 static int exprand(void)
4454 return rand();
4457 static void expsrand(int seed)
4459 srand(seed);
4462 #if 1
4464 // preferred compilation with -O2 -ffast-math !
4466 static double explog10(double x)
4468 /*printf("Log10 %f => %f 0x%Lx\n", x, log10(x), *((int64_t*)&x));*/
4469 return log10(x);
4472 static double expcos(double x)
4474 /*printf("Cos %f => %f 0x%Lx\n", x, cos(x), *((int64_t*)&x));*/
4475 return cos(x);
4478 #else
4480 static void explog10(void)
4482 __asm__ volatile
4484 "fldl 8(%esp) \n\t"
4485 "fldln2 \n\t"
4486 "fxch %st(1) \n\t"
4487 "fyl2x \n\t"
4491 static void expcos(void)
4493 __asm__ volatile
4495 "fldl 8(%esp) \n\t"
4496 "fcos \n\t"
4500 #endif
4502 // this seem to be the only how to make this function working properly
4503 // ok - I've spent tremendous amount of time (many many many hours
4504 // of debuging fixing & testing - it's almost unimaginable - kabi
4506 // _ftol - operated on the float value which is already on the FPU stack
4508 static void exp_ftol(void)
4510 __asm__ volatile
4512 "sub $12, %esp \n\t"
4513 "fstcw -2(%ebp) \n\t"
4514 "wait \n\t"
4515 "movw -2(%ebp), %ax \n\t"
4516 "orb $0x0C, %ah \n\t"
4517 "movw %ax, -4(%ebp) \n\t"
4518 "fldcw -4(%ebp) \n\t"
4519 "fistpl -12(%ebp) \n\t"
4520 "fldcw -2(%ebp) \n\t"
4521 "movl -12(%ebp), %eax \n\t"
4522 //Note: gcc 3.03 does not do the following op if it
4523 // knows that ebp=esp
4524 "movl %ebp, %esp \n\t"
4528 #define FPU_DOUBLES(var1,var2) double var1,var2; \
4529 __asm__ volatile( "fstpl %0;fwait" : "=m" (var2) : ); \
4530 __asm__ volatile( "fstpl %0;fwait" : "=m" (var1) : )
4532 static double exp_CIpow(void)
4534 FPU_DOUBLES(x,y);
4536 dbgprintf("_CIpow(%lf, %lf)\n", x, y);
4537 return pow(x, y);
4540 static double exppow(double x, double y)
4542 /*printf("Pow %f %f 0x%Lx 0x%Lx => %f\n", x, y, *((int64_t*)&x), *((int64_t*)&y), pow(x, y));*/
4543 return pow(x, y);
4546 static double expldexp(double x, int expo)
4548 /*printf("Cos %f => %f 0x%Lx\n", x, cos(x), *((int64_t*)&x));*/
4549 return ldexp(x, expo);
4552 static double expfrexp(double x, int* expo)
4554 /*printf("Cos %f => %f 0x%Lx\n", x, cos(x), *((int64_t*)&x));*/
4555 return frexp(x, expo);
4560 static int exp_stricmp(const char* s1, const char* s2)
4562 return strcasecmp(s1, s2);
4565 /* from declaration taken from Wine sources - this fountion seems to be
4566 * undocumented in any M$ doc */
4567 static int exp_setjmp3(void* jmpbuf, int x)
4569 //dbgprintf("!!!!UNIMPLEMENTED: setjmp3(%p, %d) => 0\n", jmpbuf, x);
4570 //return 0;
4571 __asm__ volatile
4573 //"mov 4(%%esp), %%edx \n\t"
4574 "mov (%%esp), %%eax \n\t"
4575 "mov %%eax, (%%edx) \n\t" // store ebp
4577 //"mov %%ebp, (%%edx) \n\t"
4578 "mov %%ebx, 4(%%edx) \n\t"
4579 "mov %%edi, 8(%%edx) \n\t"
4580 "mov %%esi, 12(%%edx) \n\t"
4581 "mov %%esp, 16(%%edx) \n\t"
4583 "mov 4(%%esp), %%eax \n\t"
4584 "mov %%eax, 20(%%edx) \n\t"
4586 "movl $0x56433230, 32(%%edx) \n\t" // VC20 ??
4587 "movl $0, 36(%%edx) \n\t"
4588 : // output
4589 : "d"(jmpbuf) // input
4590 : "eax"
4592 __asm__ volatile
4594 "mov %%fs:0, %%eax \n\t" // unsure
4595 "mov %%eax, 24(%%edx) \n\t"
4596 "cmp $0xffffffff, %%eax \n\t"
4597 "jnz l1 \n\t"
4598 "mov %%eax, 28(%%edx) \n\t"
4599 "l1: \n\t"
4602 : "eax"
4605 return 0;
4608 static DWORD WINAPI expGetCurrentProcessId(void)
4610 dbgprintf("GetCurrentProcessId(void) => %d\n", getpid());
4611 return getpid(); //(DWORD)NtCurrentTeb()->pid;
4615 typedef struct {
4616 UINT wPeriodMin;
4617 UINT wPeriodMax;
4618 } TIMECAPS, *LPTIMECAPS;
4620 static MMRESULT WINAPI exptimeGetDevCaps(LPTIMECAPS lpCaps, UINT wSize)
4622 dbgprintf("timeGetDevCaps(%p, %u) !\n", lpCaps, wSize);
4624 lpCaps->wPeriodMin = 1;
4625 lpCaps->wPeriodMax = 65535;
4626 return 0;
4629 static MMRESULT WINAPI exptimeBeginPeriod(UINT wPeriod)
4631 dbgprintf("timeBeginPeriod(%u) !\n", wPeriod);
4633 if (wPeriod < 1 || wPeriod > 65535) return 96+1; //TIMERR_NOCANDO;
4634 return 0;
4637 #ifdef CONFIG_QTX_CODECS
4638 static MMRESULT WINAPI exptimeEndPeriod(UINT wPeriod)
4640 dbgprintf("timeEndPeriod(%u) !\n", wPeriod);
4642 if (wPeriod < 1 || wPeriod > 65535) return 96+1; //TIMERR_NOCANDO;
4643 return 0;
4645 #endif
4647 static void WINAPI expGlobalMemoryStatus(
4648 LPMEMORYSTATUS lpmem
4650 static MEMORYSTATUS cached_memstatus;
4651 static int cache_lastchecked = 0;
4652 SYSTEM_INFO si;
4653 FILE *f;
4655 if (time(NULL)==cache_lastchecked) {
4656 memcpy(lpmem,&cached_memstatus,sizeof(MEMORYSTATUS));
4657 return;
4660 f = fopen( "/proc/meminfo", "r" );
4661 if (f)
4663 char buffer[256];
4664 int total, used, free, shared, buffers, cached;
4666 lpmem->dwLength = sizeof(MEMORYSTATUS);
4667 lpmem->dwTotalPhys = lpmem->dwAvailPhys = 0;
4668 lpmem->dwTotalPageFile = lpmem->dwAvailPageFile = 0;
4669 while (fgets( buffer, sizeof(buffer), f ))
4671 /* old style /proc/meminfo ... */
4672 if (sscanf( buffer, "Mem: %d %d %d %d %d %d", &total, &used, &free, &shared, &buffers, &cached ))
4674 lpmem->dwTotalPhys += total;
4675 lpmem->dwAvailPhys += free + buffers + cached;
4677 if (sscanf( buffer, "Swap: %d %d %d", &total, &used, &free ))
4679 lpmem->dwTotalPageFile += total;
4680 lpmem->dwAvailPageFile += free;
4683 /* new style /proc/meminfo ... */
4684 if (sscanf(buffer, "MemTotal: %d", &total))
4685 lpmem->dwTotalPhys = total*1024;
4686 if (sscanf(buffer, "MemFree: %d", &free))
4687 lpmem->dwAvailPhys = free*1024;
4688 if (sscanf(buffer, "SwapTotal: %d", &total))
4689 lpmem->dwTotalPageFile = total*1024;
4690 if (sscanf(buffer, "SwapFree: %d", &free))
4691 lpmem->dwAvailPageFile = free*1024;
4692 if (sscanf(buffer, "Buffers: %d", &buffers))
4693 lpmem->dwAvailPhys += buffers*1024;
4694 if (sscanf(buffer, "Cached: %d", &cached))
4695 lpmem->dwAvailPhys += cached*1024;
4697 fclose( f );
4699 if (lpmem->dwTotalPhys)
4701 DWORD TotalPhysical = lpmem->dwTotalPhys+lpmem->dwTotalPageFile;
4702 DWORD AvailPhysical = lpmem->dwAvailPhys+lpmem->dwAvailPageFile;
4703 lpmem->dwMemoryLoad = (TotalPhysical-AvailPhysical)
4704 / (TotalPhysical / 100);
4706 } else
4708 /* FIXME: should do something for other systems */
4709 lpmem->dwMemoryLoad = 0;
4710 lpmem->dwTotalPhys = 16*1024*1024;
4711 lpmem->dwAvailPhys = 16*1024*1024;
4712 lpmem->dwTotalPageFile = 16*1024*1024;
4713 lpmem->dwAvailPageFile = 16*1024*1024;
4715 expGetSystemInfo(&si);
4716 lpmem->dwTotalVirtual = si.lpMaximumApplicationAddress-si.lpMinimumApplicationAddress;
4717 /* FIXME: we should track down all the already allocated VM pages and substract them, for now arbitrarily remove 64KB so that it matches NT */
4718 lpmem->dwAvailVirtual = lpmem->dwTotalVirtual-64*1024;
4719 memcpy(&cached_memstatus,lpmem,sizeof(MEMORYSTATUS));
4720 cache_lastchecked = time(NULL);
4722 /* it appears some memory display programs want to divide by these values */
4723 if(lpmem->dwTotalPageFile==0)
4724 lpmem->dwTotalPageFile++;
4726 if(lpmem->dwAvailPageFile==0)
4727 lpmem->dwAvailPageFile++;
4730 static INT WINAPI expGetThreadPriority(HANDLE hthread)
4732 dbgprintf("GetThreadPriority(%p)\n",hthread);
4733 return 0;
4736 /**********************************************************************
4737 * SetThreadPriority [KERNEL32.@] Sets priority for thread.
4739 * RETURNS
4740 * Success: TRUE
4741 * Failure: FALSE
4743 static WIN_BOOL WINAPI expSetThreadPriority(
4744 HANDLE hthread, /* [in] Handle to thread */
4745 INT priority) /* [in] Thread priority level */
4747 dbgprintf("SetThreadPriority(%p,%d)\n",hthread,priority);
4748 return TRUE;
4751 static void WINAPI expTerminateProcess( DWORD process, DWORD status )
4753 printf("EXIT - process %ld code %ld\n", process, status);
4754 exit(status);
4757 static void WINAPI expExitProcess( DWORD status )
4759 printf("EXIT - code %ld\n",status);
4760 exit(status);
4763 static INT WINAPI expMessageBoxA(HWND hWnd, LPCSTR text, LPCSTR title, UINT type){
4764 printf("MSGBOX '%s' '%s' (%d)\n",text,title,type);
4765 #ifdef CONFIG_QTX_CODECS
4766 if (type == MB_ICONHAND && !strlen(text) && !strlen(title))
4767 return IDIGNORE;
4768 #endif
4769 return IDOK;
4772 /* these are needed for mss1 */
4775 * \brief this symbol is defined within exp_EH_prolog_dummy
4776 * \param dest jump target
4778 void exp_EH_prolog(void *dest);
4779 void exp_EH_prolog_dummy(void);
4780 //! just a dummy function that acts a container for the asm section
4781 void exp_EH_prolog_dummy(void) {
4782 __asm__ volatile (
4783 // take care, this "function" may not change flags or
4784 // registers besides eax (which is also why we can't use
4785 // exp_EH_prolog_dummy directly)
4786 MANGLE(exp_EH_prolog)": \n\t"
4787 "pop %eax \n\t"
4788 "push %ebp \n\t"
4789 "mov %esp, %ebp \n\t"
4790 "lea -12(%esp), %esp \n\t"
4791 "jmp *%eax \n\t"
4795 #include <netinet/in.h>
4796 static WINAPI inline unsigned long int exphtonl(unsigned long int hostlong)
4798 // dbgprintf("htonl(%x) => %x\n", hostlong, htonl(hostlong));
4799 return htonl(hostlong);
4802 static WINAPI inline unsigned long int expntohl(unsigned long int netlong)
4804 // dbgprintf("ntohl(%x) => %x\n", netlong, ntohl(netlong));
4805 return ntohl(netlong);
4808 static char* WINAPI expSysAllocStringLen(char *pch, unsigned cch)
4810 char *str;
4811 dbgprintf("SysAllocStringLen('%s', %d)\n", pch, cch);
4812 str = malloc(cch * 2 + sizeof(unsigned) + 2);
4813 *(unsigned *)str = cch;
4814 str += sizeof(unsigned);
4815 if (pch)
4816 memcpy(str, pch, cch * 2);
4817 str[cch * 2] = 0;
4818 str[cch * 2 + 1] = 0;
4819 return str;
4822 static void WINAPI expSysFreeString(char *str)
4824 if (str) {
4825 free(str - sizeof(unsigned));
4829 static void WINAPI expVariantInit(void* p)
4831 printf("InitCommonControls called!\n");
4832 return;
4835 static int WINAPI expRegisterClassA(const void/*WNDCLASSA*/ *wc)
4837 dbgprintf("RegisterClassA(%p) => random id\n", wc);
4838 return time(NULL); /* be precise ! */
4841 static int WINAPI expUnregisterClassA(const char *className, HINSTANCE hInstance)
4843 dbgprintf("UnregisterClassA(%s, %p) => 0\n", className, hInstance);
4844 return 0;
4847 #ifdef CONFIG_QTX_CODECS
4848 /* should be fixed bcs it's not fully strlen equivalent */
4849 static int expSysStringByteLen(void *str)
4851 dbgprintf("SysStringByteLen(%p) => %d\n", str, strlen(str));
4852 return strlen(str);
4855 static int expDirectDrawCreate(void)
4857 dbgprintf("DirectDrawCreate(...) => NULL\n");
4858 return 0;
4861 #if 1
4862 typedef struct tagPALETTEENTRY {
4863 BYTE peRed;
4864 BYTE peGreen;
4865 BYTE peBlue;
4866 BYTE peFlags;
4867 } PALETTEENTRY;
4869 typedef struct tagLOGPALETTE {
4870 WORD palVersion;
4871 WORD palNumEntries;
4872 PALETTEENTRY palPalEntry[1];
4873 } LOGPALETTE;
4875 static HPALETTE WINAPI expCreatePalette(CONST LOGPALETTE *lpgpl)
4877 HPALETTE test;
4878 int i;
4880 dbgprintf("CreatePalette(%x) => NULL\n", lpgpl);
4882 i = sizeof(LOGPALETTE)+((lpgpl->palNumEntries-1)*sizeof(PALETTEENTRY));
4883 test = malloc(i);
4884 memcpy((void *)test, lpgpl, i);
4886 return test;
4888 #else
4889 static int expCreatePalette(void)
4891 dbgprintf("CreatePalette(...) => NULL\n");
4892 return NULL;
4894 #endif
4896 static int WINAPI expGetClientRect(HWND win, RECT *r)
4898 dbgprintf("GetClientRect(0x%x, 0x%x) => 1\n", win, r);
4899 r->right = PSEUDO_SCREEN_WIDTH;
4900 r->left = 0;
4901 r->bottom = PSEUDO_SCREEN_HEIGHT;
4902 r->top = 0;
4903 return 1;
4906 #if 0
4907 typedef struct tagPOINT {
4908 LONG x;
4909 LONG y;
4910 } POINT, *PPOINT;
4911 #endif
4913 static int WINAPI expClientToScreen(HWND win, POINT *p)
4915 dbgprintf("ClientToScreen(0x%x, 0x%x = %d,%d) => 1\n", win, p, p->x, p->y);
4916 p->x = 0;
4917 p->y = 0;
4918 return 1;
4920 #endif
4922 /* for m3jpeg */
4923 static int WINAPI expSetThreadIdealProcessor(HANDLE thread, int proc)
4925 dbgprintf("SetThreadIdealProcessor(0x%x, %x) => 0\n", thread, proc);
4926 return 0;
4929 static int WINAPI expMessageBeep(int type)
4931 dbgprintf("MessageBeep(%d) => 1\n", type);
4932 return 1;
4935 static int WINAPI expDialogBoxParamA(void *inst, const char *name,
4936 HWND parent, void *dialog_func, void *init_param)
4938 dbgprintf("DialogBoxParamA(0x%x, 0x%x = %s, 0x%x, 0x%x, 0x%x) => 0x42424242\n",
4939 inst, name, name, parent, dialog_func, init_param);
4940 return 0x42424242;
4943 static void WINAPI expRegisterClipboardFormatA(const char *name) {
4944 dbgprintf("RegisterClipboardFormatA(0x%x = %s)\n", name, name);
4947 /* needed by imagepower mjpeg2k */
4948 static void *exprealloc(void *ptr, size_t size)
4950 dbgprintf("realloc(0x%x, %x)\n", ptr, size);
4951 if (!ptr)
4952 return my_mreq(size,0);
4953 else
4954 return my_realloc(ptr, size);
4957 /* Fake GetOpenFileNameA from comdlg32.dll for ViVD codec */
4958 static WIN_BOOL WINAPI expGetOpenFileNameA(/*LPOPENFILENAMEA*/ void* lpfn)
4960 return 1;
4963 static char * WINAPI expPathFindExtensionA(const char *path) {
4964 char *ext;
4965 if (!path)
4966 ext = NULL;
4967 else {
4968 ext = strrchr(path, '.');
4969 if (!ext)
4970 ext = &path[strlen(path)];
4972 dbgprintf("PathFindExtensionA(0x%x = %s) => 0x%x, %s\n", path, path, ext, ext);
4973 return ext;
4976 static char * WINAPI expPathFindFileNameA(const char *path) {
4977 char *name;
4978 if (!path || strlen(path) < 2)
4979 name = path;
4980 else {
4981 name = strrchr(path - 1, '\\');
4982 if (!name)
4983 name = path;
4985 dbgprintf("PathFindFileNameA(0x%x = %s) => 0x%x, %s\n", path, path, name, name);
4986 return name;
4989 static double expfloor(double x)
4991 dbgprintf("floor(%lf)\n", x);
4992 return floor(x);
4995 #define FPU_DOUBLE(var) double var; \
4996 __asm__ volatile( "fstpl %0;fwait" : "=m" (var) : )
4998 static double exp_CIcos(void)
5000 FPU_DOUBLE(x);
5002 dbgprintf("_CIcos(%lf)\n", x);
5003 return cos(x);
5006 static double exp_CIsin(void)
5008 FPU_DOUBLE(x);
5010 dbgprintf("_CIsin(%lf)\n", x);
5011 return sin(x);
5014 static double exp_CIsqrt(void)
5016 FPU_DOUBLE(x);
5018 dbgprintf("_CIsqrt(%lf)\n", x);
5019 return sqrt(x);
5022 /* Needed by rp8 sipr decoder */
5023 static LPSTR WINAPI expCharNextA(LPCSTR ptr)
5025 if (!*ptr) return (LPSTR)ptr;
5026 // dbgprintf("CharNextA(0x%08x), %s\n", ptr, ptr);
5027 return (LPSTR)(ptr + 1);
5030 // Fake implementation, needed by wvc1dmod.dll
5031 static int WINAPI expPropVariantClear(void *pvar)
5033 // dbgprintf("PropVariantclear (0x%08x), %s\n", ptr, ptr);
5034 return 1;
5037 // This define is fake, the real thing is a struct
5038 #define LPDEVMODEA void*
5039 // Dummy implementation, always return 1
5040 // Required for frapsvid.dll 2.8.1, return value does not matter
5041 static WIN_BOOL WINAPI expEnumDisplaySettingsA(LPCSTR name ,DWORD n,
5042 LPDEVMODEA devmode)
5044 dbgprintf("EnumDisplaySettingsA (dummy) => 1\n");
5045 return 1;
5048 // Fake implementation of _decode_pointer from msvcr80.dll, needed by sirenacm.dll
5049 // NOTE: undocumented function, probably the declaration is not right
5050 static int exp_decode_pointer(void *ptr)
5052 dbgprintf("_decode_pointer (0x%08x)\n", ptr);
5053 return 0;
5056 /* Fake implementation of sdt::_Lockit::_Lockit(void) from msvcp60.dll
5057 Needed by SCLS.DLL */
5058 static int exp_0Lockit_dummy(void)
5060 dbgprintf("0Lockit_dummy (??0_Lockit@std@@QAE@XZ)\n");
5061 return 0;
5064 /* Fake implementation of sdt::_Lockit::~_Lockit(void) from msvcp60.dll
5065 Needed by SCLS.DLL */
5066 static int exp_1Lockit_dummy(void)
5068 dbgprintf("1Lockit_dummy (??1_Lockit@std@@QAE@XZ)\n");
5069 return 0;
5072 static void * WINAPI expEncodePointer(void *p)
5074 return p;
5077 static void * WINAPI expDecodePointer(void *p)
5079 return p;
5082 static DWORD WINAPI expGetThreadLocale(void)
5084 return 0;
5088 * Very incomplete implementation, return an error for almost all cases.
5090 static DWORD WINAPI expGetLocaleInfoA(DWORD locale, DWORD lctype, char* lpLCData, int cchData)
5092 if (lctype == 0x1004) { // LOCALE_IDEFAULTANSICODEPAGE
5093 if (cchData < 4)
5094 return cchData == 0 ? 4 : 0;
5095 strcpy(lpLCData, "437");
5096 return 4;
5098 return 0;
5101 struct exports
5103 char name[64];
5104 int id;
5105 void* func;
5107 struct libs
5109 char name[64];
5110 int length;
5111 struct exports* exps;
5114 #define FF(X,Y) \
5115 {#X, Y, (void*)exp##X},
5117 #define UNDEFF(X, Y) \
5118 {#X, Y, (void*)-1},
5120 struct exports exp_kernel32[]=
5122 FF(GetVolumeInformationA,-1)
5123 FF(GetDriveTypeA,-1)
5124 FF(GetLogicalDriveStringsA,-1)
5125 FF(IsBadWritePtr, 357)
5126 FF(IsBadReadPtr, 354)
5127 FF(IsBadStringPtrW, -1)
5128 FF(IsBadStringPtrA, -1)
5129 FF(DisableThreadLibraryCalls, -1)
5130 FF(CreateThread, -1)
5131 FF(ResumeThread, -1)
5132 FF(CreateEventA, -1)
5133 FF(SetEvent, -1)
5134 FF(ResetEvent, -1)
5135 FF(WaitForSingleObject, -1)
5136 #ifdef CONFIG_QTX_CODECS
5137 FF(WaitForMultipleObjects, -1)
5138 FF(ExitThread, -1)
5139 #endif
5140 FF(GetSystemInfo, -1)
5141 FF(GetVersion, 332)
5142 FF(HeapCreate, 461)
5143 FF(HeapAlloc, -1)
5144 FF(HeapDestroy, -1)
5145 FF(HeapFree, -1)
5146 FF(HeapSize, -1)
5147 FF(HeapReAlloc,-1)
5148 FF(GetProcessHeap, -1)
5149 FF(VirtualAlloc, -1)
5150 FF(VirtualFree, -1)
5151 FF(InitializeCriticalSection, -1)
5152 FF(InitializeCriticalSectionAndSpinCount, -1)
5153 FF(EnterCriticalSection, -1)
5154 FF(LeaveCriticalSection, -1)
5155 FF(DeleteCriticalSection, -1)
5156 FF(TlsAlloc, -1)
5157 FF(TlsFree, -1)
5158 FF(TlsGetValue, -1)
5159 FF(TlsSetValue, -1)
5160 FF(GetCurrentThreadId, -1)
5161 FF(GetCurrentProcess, -1)
5162 FF(LocalAlloc, -1)
5163 FF(LocalReAlloc,-1)
5164 FF(LocalLock, -1)
5165 FF(GlobalAlloc, -1)
5166 FF(GlobalReAlloc, -1)
5167 FF(GlobalLock, -1)
5168 FF(GlobalSize, -1)
5169 FF(MultiByteToWideChar, 427)
5170 FF(WideCharToMultiByte, -1)
5171 FF(GetVersionExA, -1)
5172 FF(CreateSemaphoreA, -1)
5173 FF(QueryPerformanceCounter, -1)
5174 FF(QueryPerformanceFrequency, -1)
5175 FF(LocalHandle, -1)
5176 FF(LocalUnlock, -1)
5177 FF(LocalFree, -1)
5178 FF(GlobalHandle, -1)
5179 FF(GlobalUnlock, -1)
5180 FF(GlobalFree, -1)
5181 FF(LoadResource, -1)
5182 FF(ReleaseSemaphore, -1)
5183 FF(CreateMutexA, -1)
5184 FF(ReleaseMutex, -1)
5185 FF(SignalObjectAndWait, -1)
5186 FF(FindResourceA, -1)
5187 FF(LockResource, -1)
5188 FF(FreeResource, -1)
5189 FF(SizeofResource, -1)
5190 FF(CloseHandle, -1)
5191 FF(GetCommandLineA, -1)
5192 FF(GetEnvironmentStringsW, -1)
5193 FF(FreeEnvironmentStringsW, -1)
5194 FF(FreeEnvironmentStringsA, -1)
5195 FF(GetEnvironmentStrings, -1)
5196 FF(GetStartupInfoA, -1)
5197 FF(GetStdHandle, -1)
5198 FF(GetFileType, -1)
5199 #ifdef CONFIG_QTX_CODECS
5200 FF(GetFileAttributesA, -1)
5201 #endif
5202 FF(SetHandleCount, -1)
5203 FF(GetACP, -1)
5204 FF(GetModuleFileNameA, -1)
5205 FF(SetUnhandledExceptionFilter, -1)
5206 FF(LoadLibraryA, -1)
5207 FF(GetProcAddress, -1)
5208 FF(FreeLibrary, -1)
5209 FF(CreateFileMappingA, -1)
5210 FF(OpenFileMappingA, -1)
5211 FF(MapViewOfFile, -1)
5212 FF(UnmapViewOfFile, -1)
5213 FF(Sleep, -1)
5214 FF(GetModuleHandleA, -1)
5215 FF(GetModuleHandleW, -1)
5216 FF(GetProfileIntA, -1)
5217 FF(GetPrivateProfileIntA, -1)
5218 FF(GetPrivateProfileStringA, -1)
5219 FF(WritePrivateProfileStringA, -1)
5220 FF(GetLastError, -1)
5221 FF(SetLastError, -1)
5222 FF(InterlockedIncrement, -1)
5223 FF(InterlockedDecrement, -1)
5224 FF(GetTimeZoneInformation, -1)
5225 FF(OutputDebugStringA, -1)
5226 FF(GetLocalTime, -1)
5227 FF(GetSystemTime, -1)
5228 FF(GetSystemTimeAsFileTime, -1)
5229 FF(GetEnvironmentVariableA, -1)
5230 FF(SetEnvironmentVariableA, -1)
5231 FF(RtlZeroMemory,-1)
5232 FF(RtlMoveMemory,-1)
5233 FF(RtlFillMemory,-1)
5234 FF(GetTempPathA,-1)
5235 FF(FindFirstFileA,-1)
5236 FF(FindNextFileA,-1)
5237 FF(FindClose,-1)
5238 FF(FileTimeToLocalFileTime,-1)
5239 FF(DeleteFileA,-1)
5240 FF(ReadFile,-1)
5241 FF(WriteFile,-1)
5242 FF(SetFilePointer,-1)
5243 FF(GetTempFileNameA,-1)
5244 FF(CreateFileA,-1)
5245 FF(GetSystemDirectoryA,-1)
5246 FF(GetWindowsDirectoryA,-1)
5247 #ifdef CONFIG_QTX_CODECS
5248 FF(GetCurrentDirectoryA,-1)
5249 FF(SetCurrentDirectoryA,-1)
5250 FF(CreateDirectoryA,-1)
5251 #endif
5252 FF(GetShortPathNameA,-1)
5253 FF(GetFullPathNameA,-1)
5254 FF(SetErrorMode, -1)
5255 FF(IsProcessorFeaturePresent, -1)
5256 FF(IsDebuggerPresent, -1)
5257 FF(GetProcessAffinityMask, -1)
5258 FF(InterlockedExchange, -1)
5259 FF(InterlockedCompareExchange, -1)
5260 FF(MulDiv, -1)
5261 FF(lstrcmpiA, -1)
5262 FF(lstrlenA, -1)
5263 FF(lstrcpyA, -1)
5264 FF(lstrcatA, -1)
5265 FF(lstrcpynA,-1)
5266 FF(GetProcessVersion,-1)
5267 FF(GetCurrentThread,-1)
5268 FF(GetOEMCP,-1)
5269 FF(GetCPInfo,-1)
5270 FF(DuplicateHandle,-1)
5271 FF(GetTickCount, -1)
5272 FF(SetThreadAffinityMask,-1)
5273 FF(GetCurrentProcessId,-1)
5274 FF(GlobalMemoryStatus,-1)
5275 FF(GetThreadPriority,-1)
5276 FF(SetThreadPriority,-1)
5277 FF(TerminateProcess,-1)
5278 FF(ExitProcess,-1)
5279 {"LoadLibraryExA", -1, (void*)&LoadLibraryExA},
5280 FF(SetThreadIdealProcessor,-1)
5281 FF(SetProcessAffinityMask, -1)
5282 FF(EncodePointer, -1)
5283 FF(DecodePointer, -1)
5284 FF(GetThreadLocale, -1)
5285 FF(GetLocaleInfoA, -1)
5286 UNDEFF(FlsAlloc, -1)
5287 UNDEFF(FlsGetValue, -1)
5288 UNDEFF(FlsSetValue, -1)
5289 UNDEFF(FlsFree, -1)
5292 struct exports exp_msvcrt[]={
5293 FF(malloc, -1)
5294 FF(_initterm, -1)
5295 FF(__dllonexit, -1)
5296 FF(_snprintf,-1)
5297 FF(free, -1)
5298 {"??3@YAXPAX@Z", -1, expdelete},
5299 {"??2@YAPAXI@Z", -1, expnew},
5300 {"_adjust_fdiv", -1, (void*)&_adjust_fdiv},
5301 {"_winver",-1,(void*)&_winver},
5302 FF(strrchr, -1)
5303 FF(strchr, -1)
5304 FF(strlen, -1)
5305 FF(strcpy, -1)
5306 FF(strncpy, -1)
5307 FF(wcscpy, -1)
5308 FF(strcmp, -1)
5309 FF(strncmp, -1)
5310 FF(strcat, -1)
5311 FF(_stricmp,-1)
5312 FF(_strdup,-1)
5313 FF(_setjmp3,-1)
5314 FF(isalnum, -1)
5315 FF(isspace, -1)
5316 FF(isalpha, -1)
5317 FF(isdigit, -1)
5318 FF(memmove, -1)
5319 FF(memcmp, -1)
5320 FF(memset, -1)
5321 FF(memcpy, -1)
5322 FF(time, -1)
5323 FF(rand, -1)
5324 FF(srand, -1)
5325 FF(log10, -1)
5326 FF(pow, -1)
5327 FF(cos, -1)
5328 FF(_ftol,-1)
5329 FF(_CIpow,-1)
5330 FF(_CIcos,-1)
5331 FF(_CIsin,-1)
5332 FF(_CIsqrt,-1)
5333 FF(ldexp,-1)
5334 FF(frexp,-1)
5335 FF(sprintf,-1)
5336 FF(sscanf,-1)
5337 FF(fopen,-1)
5338 FF(fprintf,-1)
5339 FF(printf,-1)
5340 FF(getenv,-1)
5341 FF(floor,-1)
5342 /* needed by frapsvid.dll */
5343 {"strstr",-1,(char *)&strstr},
5344 {"qsort",-1,(void *)&qsort},
5345 FF(_EH_prolog,-1)
5346 FF(calloc,-1)
5347 {"ceil",-1,(void*)&ceil},
5348 /* needed by imagepower mjpeg2k */
5349 {"clock",-1,(void*)&clock},
5350 {"memchr",-1,(void*)&memchr},
5351 {"vfprintf",-1,(void*)&vfprintf},
5352 // {"realloc",-1,(void*)&realloc},
5353 FF(realloc,-1)
5354 {"puts",-1,(void*)&puts}
5356 struct exports exp_winmm[]={
5357 FF(GetDriverModuleHandle, -1)
5358 FF(timeGetTime, -1)
5359 FF(DefDriverProc, -1)
5360 FF(OpenDriverA, -1)
5361 FF(OpenDriver, -1)
5362 FF(timeGetDevCaps, -1)
5363 FF(timeBeginPeriod, -1)
5364 #ifdef CONFIG_QTX_CODECS
5365 FF(timeEndPeriod, -1)
5366 FF(waveOutGetNumDevs, -1)
5367 #endif
5369 struct exports exp_psapi[]={
5370 FF(GetModuleBaseNameA, -1)
5372 struct exports exp_user32[]={
5373 FF(LoadIconA,-1)
5374 FF(LoadStringA, -1)
5375 FF(wsprintfA, -1)
5376 FF(GetDC, -1)
5377 FF(GetDesktopWindow, -1)
5378 FF(ReleaseDC, -1)
5379 FF(IsRectEmpty, -1)
5380 FF(LoadCursorA,-1)
5381 FF(SetCursor,-1)
5382 FF(GetCursorPos,-1)
5383 #ifdef CONFIG_QTX_CODECS
5384 FF(ShowCursor,-1)
5385 #endif
5386 FF(RegisterWindowMessageA,-1)
5387 FF(GetSystemMetrics,-1)
5388 FF(GetSysColor,-1)
5389 FF(GetSysColorBrush,-1)
5390 FF(GetWindowDC, -1)
5391 FF(DrawTextA, -1)
5392 FF(MessageBoxA, -1)
5393 FF(RegisterClassA, -1)
5394 FF(UnregisterClassA, -1)
5395 #ifdef CONFIG_QTX_CODECS
5396 FF(GetWindowRect, -1)
5397 FF(MonitorFromWindow, -1)
5398 FF(MonitorFromRect, -1)
5399 FF(MonitorFromPoint, -1)
5400 FF(EnumDisplayMonitors, -1)
5401 FF(GetMonitorInfoA, -1)
5402 FF(EnumDisplayDevicesA, -1)
5403 FF(GetClientRect, -1)
5404 FF(ClientToScreen, -1)
5405 FF(IsWindowVisible, -1)
5406 FF(GetActiveWindow, -1)
5407 FF(GetClassNameA, -1)
5408 FF(GetClassInfoA, -1)
5409 FF(GetWindowLongA, -1)
5410 FF(EnumWindows, -1)
5411 FF(GetWindowThreadProcessId, -1)
5412 FF(CreateWindowExA, -1)
5413 #endif
5414 FF(MessageBeep, -1)
5415 FF(DialogBoxParamA, -1)
5416 FF(RegisterClipboardFormatA, -1)
5417 FF(CharNextA, -1)
5418 FF(EnumDisplaySettingsA, -1)
5420 struct exports exp_advapi32[]={
5421 FF(RegCloseKey, -1)
5422 FF(RegCreateKeyA, -1)
5423 FF(RegCreateKeyExA, -1)
5424 FF(RegEnumKeyExA, -1)
5425 FF(RegEnumValueA, -1)
5426 FF(RegOpenKeyA, -1)
5427 FF(RegOpenKeyExA, -1)
5428 FF(RegQueryValueExA, -1)
5429 FF(RegSetValueExA, -1)
5430 FF(RegQueryInfoKeyA, -1)
5432 struct exports exp_gdi32[]={
5433 FF(CreateCompatibleDC, -1)
5434 FF(CreateFontA, -1)
5435 FF(DeleteDC, -1)
5436 FF(DeleteObject, -1)
5437 FF(GetDeviceCaps, -1)
5438 FF(GetSystemPaletteEntries, -1)
5439 #ifdef CONFIG_QTX_CODECS
5440 FF(CreatePalette, -1)
5441 FF(GetObjectA, -1)
5442 FF(CreateRectRgn, -1)
5443 #endif
5445 struct exports exp_version[]={
5446 FF(GetFileVersionInfoSizeA, -1)
5448 struct exports exp_ole32[]={
5449 FF(CoCreateFreeThreadedMarshaler,-1)
5450 FF(CoCreateInstance, -1)
5451 FF(CoInitialize, -1)
5452 FF(CoInitializeEx, -1)
5453 FF(CoUninitialize, -1)
5454 FF(CoTaskMemAlloc, -1)
5455 FF(CoTaskMemFree, -1)
5456 FF(StringFromGUID2, -1)
5457 FF(PropVariantClear, -1)
5459 // do we really need crtdll ???
5460 // msvcrt is the correct place probably...
5461 struct exports exp_crtdll[]={
5462 FF(memcpy, -1)
5463 FF(wcscpy, -1)
5465 struct exports exp_comctl32[]={
5466 FF(StringFromGUID2, -1)
5467 FF(InitCommonControls, 17)
5468 #ifdef CONFIG_QTX_CODECS
5469 FF(CreateUpDownControl, 16)
5470 #endif
5472 struct exports exp_wsock32[]={
5473 FF(htonl,8)
5474 FF(ntohl,14)
5476 struct exports exp_msdmo[]={
5477 FF(memcpy, -1) // just test
5478 FF(MoCopyMediaType, -1)
5479 FF(MoCreateMediaType, -1)
5480 FF(MoDeleteMediaType, -1)
5481 FF(MoDuplicateMediaType, -1)
5482 FF(MoFreeMediaType, -1)
5483 FF(MoInitMediaType, -1)
5485 struct exports exp_oleaut32[]={
5486 FF(SysAllocStringLen, 4)
5487 FF(SysFreeString, 6)
5488 FF(VariantInit, 8)
5489 #ifdef CONFIG_QTX_CODECS
5490 FF(SysStringByteLen, 149)
5491 #endif
5494 /* realplayer8:
5495 DLL Name: PNCRT.dll
5496 vma: Hint/Ord Member-Name
5497 22ff4 615 free
5498 2302e 250 _ftol
5499 22fea 666 malloc
5500 2303e 609 fprintf
5501 2305e 167 _adjust_fdiv
5502 23052 280 _initterm
5504 22ffc 176 _beginthreadex
5505 23036 284 _iob
5506 2300e 85 __CxxFrameHandler
5507 23022 411 _purecall
5509 #ifdef REALPLAYER
5510 struct exports exp_pncrt[]={
5511 FF(malloc, -1) // just test
5512 FF(free, -1) // just test
5513 FF(fprintf, -1) // just test
5514 {"_adjust_fdiv", -1, (void*)&_adjust_fdiv},
5515 FF(_ftol,-1)
5516 FF(_initterm, -1)
5517 {"??3@YAXPAX@Z", -1, expdelete},
5518 {"??2@YAPAXI@Z", -1, expnew},
5519 FF(__dllonexit, -1)
5520 FF(strncpy, -1)
5521 FF(_CIpow,-1)
5522 FF(calloc,-1)
5523 FF(memmove, -1)
5524 FF(ldexp, -1)
5525 FF(frexp, -1)
5527 #endif
5529 #ifdef CONFIG_QTX_CODECS
5530 struct exports exp_ddraw[]={
5531 FF(DirectDrawCreate, -1)
5533 #endif
5535 struct exports exp_comdlg32[]={
5536 FF(GetOpenFileNameA, -1)
5539 struct exports exp_shlwapi[]={
5540 FF(PathFindExtensionA, -1)
5541 FF(PathFindFileNameA, -1)
5544 struct exports exp_msvcr80[]={
5545 FF(_CIpow,-1)
5546 FF(_CIsin,-1)
5547 FF(_CIcos,-1)
5548 FF(_CIsqrt,-1)
5549 FF(memset,-1)
5550 FF(_initterm_e, -1)
5551 FF(_initterm, -1)
5552 FF(_decode_pointer, -1)
5553 /* needed by KGV1-VFW.dll */
5554 {"??2@YAPAXI@Z", -1, expnew},
5555 {"??3@YAXPAX@Z", -1, expdelete}
5558 struct exports exp_msvcp60[]={
5559 {"??0_Lockit@std@@QAE@XZ", -1, exp_0Lockit_dummy},
5560 {"??1_Lockit@std@@QAE@XZ", -1, exp_1Lockit_dummy}
5563 #define LL(X) \
5564 {#X".dll", sizeof(exp_##X)/sizeof(struct exports), exp_##X},
5566 struct libs libraries[]={
5567 LL(kernel32)
5568 LL(msvcrt)
5569 LL(winmm)
5570 LL(psapi)
5571 LL(user32)
5572 LL(advapi32)
5573 LL(gdi32)
5574 LL(version)
5575 LL(ole32)
5576 LL(oleaut32)
5577 LL(crtdll)
5578 LL(comctl32)
5579 LL(wsock32)
5580 LL(msdmo)
5581 #ifdef REALPLAYER
5582 LL(pncrt)
5583 #endif
5584 #ifdef CONFIG_QTX_CODECS
5585 LL(ddraw)
5586 #endif
5587 LL(comdlg32)
5588 LL(shlwapi)
5589 LL(msvcr80)
5590 LL(msvcp60)
5593 static WIN_BOOL WINAPI ext_stubs(void)
5595 // NOTE! these magic values will be replaced at runtime, make sure
5596 // add_stub can still find them if you change them.
5597 volatile int idx = 0x0deadabc;
5598 // make sure gcc does not do eip-relative call or something like that
5599 void (* volatile my_printf)(char *, char *) = (void *)0xdeadfbcd;
5600 my_printf("Called unk_%s\n", export_names[idx]);
5601 return 0;
5604 #define MAX_STUB_SIZE 0x60
5605 #define MAX_NUM_STUBS 200
5606 static int pos=0;
5607 static char *extcode = NULL;
5609 static void* add_stub(void)
5611 int i;
5612 int found = 0;
5613 // generated code in runtime!
5614 char* answ;
5615 if (!extcode)
5616 extcode = mmap_anon(NULL, MAX_NUM_STUBS * MAX_STUB_SIZE,
5617 PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE, 0);
5618 answ = extcode + pos * MAX_STUB_SIZE;
5619 if (pos >= MAX_NUM_STUBS) {
5620 printf("too many stubs, expect crash\n");
5621 return NULL;
5623 memcpy(answ, ext_stubs, MAX_STUB_SIZE);
5624 for (i = 0; i < MAX_STUB_SIZE - 3; i++) {
5625 int *magic = (int *)(answ + i);
5626 if (*magic == 0x0deadabc) {
5627 *magic = pos;
5628 found |= 1;
5630 if (*magic == 0xdeadfbcd) {
5631 *magic = (intptr_t)printf;
5632 found |= 2;
5635 if (found != 3) {
5636 printf("magic code not found in ext_subs, expect crash\n");
5637 return NULL;
5639 pos++;
5640 return (void*)answ;
5643 void* LookupExternal(const char* library, int ordinal)
5645 int i,j;
5646 if(library==0)
5648 printf("ERROR: library=0\n");
5649 return (void*)ext_unknown;
5651 // printf("%x %x\n", &unk_exp1, &unk_exp2);
5653 dbgprintf("External func %s:%d\n", library, ordinal);
5655 for(i=0; i<sizeof(libraries)/sizeof(struct libs); i++)
5657 if(strcasecmp(library, libraries[i].name))
5658 continue;
5659 for(j=0; j<libraries[i].length; j++)
5661 if(ordinal!=libraries[i].exps[j].id)
5662 continue;
5663 //printf("Hit: 0x%p\n", libraries[i].exps[j].func);
5664 return libraries[i].exps[j].func;
5668 #ifndef LOADLIB_TRY_NATIVE
5669 /* hack for truespeech and vssh264*/
5670 if (!strcmp(library, "tsd32.dll") || !strcmp(library,"vssh264dec.dll") || !strcmp(library,"LCMW2.dll") || !strcmp(library,"VDODEC32.dll"))
5671 #endif
5672 /* ok, this is a hack, and a big memory leak. should be fixed. - alex */
5674 int hand;
5675 WINE_MODREF *wm;
5676 void *func;
5678 hand = LoadLibraryA(library);
5679 if (!hand)
5680 goto no_dll;
5681 wm = MODULE32_LookupHMODULE(hand);
5682 if (!wm)
5684 FreeLibrary(hand);
5685 goto no_dll;
5687 func = PE_FindExportedFunction(wm, (LPCSTR) ordinal, 0);
5688 if (!func)
5690 printf("No such ordinal in external dll\n");
5691 FreeLibrary((int)hand);
5692 goto no_dll;
5695 printf("External dll loaded (offset: 0x%x, func: %p)\n",
5696 hand, func);
5697 return func;
5700 no_dll:
5701 if(pos>150)return 0;
5702 snprintf(export_names[pos], sizeof(export_names[pos]), "%s:%d", library, ordinal);
5703 return add_stub();
5706 void* LookupExternalByName(const char* library, const char* name)
5708 int i,j;
5709 // return (void*)ext_unknown;
5710 if(library==0)
5712 printf("ERROR: library=0\n");
5713 return (void*)ext_unknown;
5715 if((unsigned long)name<=0xffff)
5717 return LookupExternal(library, (int)name);
5719 dbgprintf("External func %s:%s\n", library, name);
5720 for(i=0; i<sizeof(libraries)/sizeof(struct libs); i++)
5722 if(strcasecmp(library, libraries[i].name))
5723 continue;
5724 for(j=0; j<libraries[i].length; j++)
5726 if(strcmp(name, libraries[i].exps[j].name))
5727 continue;
5728 if((unsigned int)(libraries[i].exps[j].func) == -1)
5729 return NULL; //undefined func
5730 // printf("Hit: 0x%08X\n", libraries[i].exps[j].func);
5731 return libraries[i].exps[j].func;
5735 #ifndef LOADLIB_TRY_NATIVE
5736 /* hack for vss h264 */
5737 if (!strcmp(library,"vssh264core.dll") || !strcmp(library,"3ivx.dll"))
5738 #endif
5739 /* ok, this is a hack, and a big memory leak. should be fixed. - alex */
5741 int hand;
5742 WINE_MODREF *wm;
5743 void *func;
5745 hand = LoadLibraryA(library);
5746 if (!hand)
5747 goto no_dll_byname;
5748 wm = MODULE32_LookupHMODULE(hand);
5749 if (!wm)
5751 FreeLibrary(hand);
5752 goto no_dll_byname;
5754 func = PE_FindExportedFunction(wm, name, 0);
5755 if (!func)
5757 printf("No such name in external dll\n");
5758 FreeLibrary((int)hand);
5759 goto no_dll_byname;
5762 printf("External dll loaded (offset: 0x%x, func: %p)\n",
5763 hand, func);
5764 return func;
5767 no_dll_byname:
5768 if(pos>150)return 0;// to many symbols
5769 snprintf(export_names[pos], sizeof(export_names[pos]), "%s", name);
5770 return add_stub();
5773 void my_garbagecollection(void)
5775 #ifdef GARBAGE
5776 int unfree = 0, unfreecnt = 0;
5778 int max_fatal = 8;
5779 free_registry();
5780 while (last_alloc)
5782 alloc_header* mem = last_alloc + 1;
5783 unfree += my_size(mem);
5784 unfreecnt++;
5785 if (my_release(mem) != 0)
5786 // avoid endless loop when memory is trashed
5787 if (--max_fatal < 0)
5788 break;
5790 dbgprintf("Total Unfree %d bytes cnt %d [%p,%d]\n",unfree, unfreecnt, last_alloc, alccnt);
5791 #endif
5792 g_tls = NULL;
5793 pthread_mutex_lock(&list_lock);
5794 list = NULL;
5795 pthread_mutex_unlock(&list_lock);