Merge svn changes up to r30917
[mplayer/glamo.git] / loader / win32.c
blobd0cbddca66f916544952b6a918cb39d31143d8f0
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 = BINARY_CODECS_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 expCreateEventW(void* pSecAttr, char bManualReset,
796 char bInitialState, const WCHAR* name)
798 char ascii_name[256];
799 char *aname = NULL;
800 if (name) {
801 WideCharToMultiByte(65001, 0x0, name, -1, ascii_name, 256, NULL, NULL);
802 aname = ascii_name;
804 return expCreateEventA(pSecAttr, bManualReset, bInitialState, aname);
807 static void* WINAPI expSetEvent(void* event)
809 mutex_list *ml = (mutex_list *)event;
810 dbgprintf("SetEvent(%x) => 0x1\n", event);
811 pthread_mutex_lock(ml->pm);
812 if (ml->state == 0) {
813 ml->state = 1;
814 pthread_cond_signal(ml->pc);
816 pthread_mutex_unlock(ml->pm);
818 return (void *)1;
820 static void* WINAPI expResetEvent(void* event)
822 mutex_list *ml = (mutex_list *)event;
823 dbgprintf("ResetEvent(0x%x) => 0x1\n", event);
824 pthread_mutex_lock(ml->pm);
825 ml->state = 0;
826 pthread_mutex_unlock(ml->pm);
828 return (void *)1;
831 static void* WINAPI expWaitForSingleObject(void* object, int duration)
833 mutex_list *ml = (mutex_list *)object;
834 // FIXME FIXME FIXME - this value is sometime unititialize !!!
835 int ret = WAIT_FAILED;
836 mutex_list* pp;
837 th_list* tp;
838 if(object == (void*)0xcfcf9898)
841 From GetCurrentThread() documentation:
842 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.
844 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.
846 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.
848 dbgprintf("WaitForSingleObject(thread_handle) called\n");
849 return (void*)WAIT_FAILED;
851 dbgprintf("WaitForSingleObject(0x%x, duration %d) =>\n",object, duration);
853 // See if this is a thread.
854 pthread_mutex_lock(&list_lock);
855 tp=list;
856 while (tp && (tp->thread != object))
857 tp = tp->prev;
858 pthread_mutex_unlock(&list_lock);
859 if (tp) {
860 if (pthread_join(*(pthread_t*)object, NULL) == 0) {
861 return (void*)WAIT_OBJECT_0;
862 } else {
863 return (void*)WAIT_FAILED;
867 // loop below was slightly fixed - its used just for checking if
868 // this object really exists in our list
869 if (!ml)
870 return (void*) ret;
871 pthread_mutex_lock(&mlist_lock);
872 pp=mlist;
873 while (pp && (pp->pm != ml->pm))
874 pp = pp->prev;
875 pthread_mutex_unlock(&mlist_lock);
876 if (!pp) {
877 dbgprintf("WaitForSingleObject: NotFound\n");
878 return (void*)ret;
881 pthread_mutex_lock(ml->pm);
883 switch(ml->type) {
884 case 0: /* Event */
885 if (duration == 0) { /* Check Only */
886 if (ml->state == 1) ret = WAIT_OBJECT_0;
887 else ret = WAIT_FAILED;
889 if (duration == -1) { /* INFINITE */
890 if (ml->state == 0)
891 pthread_cond_wait(ml->pc,ml->pm);
892 if (ml->reset)
893 ml->state = 0;
894 ret = WAIT_OBJECT_0;
896 if (duration > 0) { /* Timed Wait */
897 struct timespec abstime;
898 struct timeval now;
899 gettimeofday(&now, 0);
900 abstime.tv_sec = now.tv_sec + (now.tv_usec+duration)/1000000;
901 abstime.tv_nsec = ((now.tv_usec+duration)%1000000)*1000;
902 if (ml->state == 0)
903 ret=pthread_cond_timedwait(ml->pc,ml->pm,&abstime);
904 if (ret == ETIMEDOUT) ret = WAIT_TIMEOUT;
905 else ret = WAIT_OBJECT_0;
906 if (ml->reset)
907 ml->state = 0;
909 break;
910 case 1: /* Semaphore */
911 if (duration == 0) {
912 if(ml->semaphore==0) ret = WAIT_FAILED;
913 else {
914 ml->semaphore--;
915 ret = WAIT_OBJECT_0;
918 if (duration == -1) {
919 if (ml->semaphore==0)
920 pthread_cond_wait(ml->pc,ml->pm);
921 ml->semaphore--;
922 ret = WAIT_OBJECT_0;
924 break;
925 case 2: /* Mutex */
926 if (duration == 0) {
927 if(ml->lock_count > 0 && ml->owner != pthread_self()) ret = WAIT_FAILED;
928 else {
929 ml->lock_count++;
930 ml->owner = pthread_self();
931 ret = WAIT_OBJECT_0;
934 if (duration == -1) {
935 if (ml->lock_count > 0 && ml->owner != pthread_self()) {
936 pthread_cond_wait(ml->pc,ml->pm);
938 ml->lock_count++;
939 ml->owner = pthread_self();
940 ret = WAIT_OBJECT_0;
942 break;
944 pthread_mutex_unlock(ml->pm);
946 dbgprintf("WaitForSingleObject(0x%x, %d): 0x%x => 0x%x \n",object,duration,ml,ret);
947 return (void *)ret;
950 #ifdef CONFIG_QTX_CODECS
951 static void* WINAPI expWaitForMultipleObjects(int count, const void** objects,
952 int WaitAll, int duration)
954 int i;
955 void *object;
956 void *ret;
958 dbgprintf("WaitForMultipleObjects(%d, 0x%x, %d, duration %d) =>\n",
959 count, objects, WaitAll, duration);
961 for (i = 0; i < count; i++)
963 object = (void *)objects[i];
964 ret = expWaitForSingleObject(object, duration);
965 if (WaitAll)
966 dbgprintf("WaitAll flag not yet supported...\n");
967 else
968 return ret;
970 return NULL;
973 static void WINAPI expExitThread(int retcode)
975 dbgprintf("ExitThread(%d)\n", retcode);
976 pthread_exit(&retcode);
978 #endif
980 static int pf_set = 0;
981 static BYTE PF[64] = {0,};
983 static void DumpSystemInfo(const SYSTEM_INFO* si)
985 dbgprintf(" Processor architecture %d\n", si->u.s.wProcessorArchitecture);
986 dbgprintf(" Page size: %d\n", si->dwPageSize);
987 dbgprintf(" Minimum app address: %d\n", si->lpMinimumApplicationAddress);
988 dbgprintf(" Maximum app address: %d\n", si->lpMaximumApplicationAddress);
989 dbgprintf(" Active processor mask: 0x%x\n", si->dwActiveProcessorMask);
990 dbgprintf(" Number of processors: %d\n", si->dwNumberOfProcessors);
991 dbgprintf(" Processor type: 0x%x\n", si->dwProcessorType);
992 dbgprintf(" Allocation granularity: 0x%x\n", si->dwAllocationGranularity);
993 dbgprintf(" Processor level: 0x%x\n", si->wProcessorLevel);
994 dbgprintf(" Processor revision: 0x%x\n", si->wProcessorRevision);
997 static void WINAPI expGetSystemInfo(SYSTEM_INFO* si)
999 /* FIXME: better values for the two entries below... */
1000 static int cache = 0;
1001 static SYSTEM_INFO cachedsi;
1002 dbgprintf("GetSystemInfo(%p) =>\n", si);
1004 if (cache) {
1005 goto exit;
1007 memset(PF,0,sizeof(PF));
1008 pf_set = 1;
1010 cachedsi.u.s.wProcessorArchitecture = PROCESSOR_ARCHITECTURE_INTEL;
1011 cachedsi.dwPageSize = getpagesize();
1013 /* FIXME: better values for the two entries below... */
1014 cachedsi.lpMinimumApplicationAddress = (void *)0x00000000;
1015 cachedsi.lpMaximumApplicationAddress = (void *)0x7FFFFFFF;
1016 cachedsi.dwActiveProcessorMask = 1;
1017 cachedsi.dwNumberOfProcessors = 1;
1018 cachedsi.dwProcessorType = PROCESSOR_INTEL_386;
1019 cachedsi.dwAllocationGranularity = 0x10000;
1020 cachedsi.wProcessorLevel = 5; /* pentium */
1021 cachedsi.wProcessorRevision = 0x0101;
1023 /* mplayer's way to detect PF's */
1025 #include "cpudetect.h"
1027 if (gCpuCaps.hasMMX)
1028 PF[PF_MMX_INSTRUCTIONS_AVAILABLE] = TRUE;
1029 if (gCpuCaps.hasSSE)
1030 PF[PF_XMMI_INSTRUCTIONS_AVAILABLE] = TRUE;
1031 if (gCpuCaps.hasSSE2)
1032 PF[PF_XMMI64_INSTRUCTIONS_AVAILABLE] = TRUE;
1033 if (gCpuCaps.has3DNow)
1034 PF[PF_AMD3D_INSTRUCTIONS_AVAILABLE] = TRUE;
1036 if (gCpuCaps.cpuType == 4)
1038 cachedsi.dwProcessorType = PROCESSOR_INTEL_486;
1039 cachedsi.wProcessorLevel = 4;
1041 else if (gCpuCaps.cpuType >= 5)
1043 cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
1044 cachedsi.wProcessorLevel = 5;
1046 else
1048 cachedsi.dwProcessorType = PROCESSOR_INTEL_386;
1049 cachedsi.wProcessorLevel = 3;
1051 cachedsi.wProcessorRevision = gCpuCaps.cpuStepping;
1052 cachedsi.dwNumberOfProcessors = 1; /* hardcoded */
1055 /* MPlayer: linux detection enabled (based on proc/cpuinfo) for checking
1056 fdiv_bug and fpu emulation flags -- alex/MPlayer */
1057 #ifdef __linux__
1059 char buf[20];
1060 char line[200];
1061 FILE *f = fopen ("/proc/cpuinfo", "r");
1063 if (!f)
1065 mp_msg(MSGT_WIN32, MSGL_WARN, "expGetSystemInfo: "
1066 "/proc/cpuinfo not readable! "
1067 "Expect bad performance and/or weird behaviour\n");
1068 goto exit;
1070 while (fgets(line,200,f)!=NULL) {
1071 char *s,*value;
1073 /* NOTE: the ':' is the only character we can rely on */
1074 if (!(value = strchr(line,':')))
1075 continue;
1076 /* terminate the valuename */
1077 *value++ = '\0';
1078 /* skip any leading spaces */
1079 while (*value==' ') value++;
1080 if ((s=strchr(value,'\n')))
1081 *s='\0';
1083 /* 2.1 method */
1084 if (!lstrncmpiA(line, "cpu family",strlen("cpu family"))) {
1085 if (isdigit (value[0])) {
1086 switch (value[0] - '0') {
1087 case 3: cachedsi.dwProcessorType = PROCESSOR_INTEL_386;
1088 cachedsi.wProcessorLevel= 3;
1089 break;
1090 case 4: cachedsi.dwProcessorType = PROCESSOR_INTEL_486;
1091 cachedsi.wProcessorLevel= 4;
1092 break;
1093 case 5: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
1094 cachedsi.wProcessorLevel= 5;
1095 break;
1096 case 6: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
1097 cachedsi.wProcessorLevel= 5;
1098 break;
1099 default:cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
1100 cachedsi.wProcessorLevel= 5;
1101 break;
1104 /* set the CPU type of the current processor */
1105 sprintf(buf,"CPU %ld",cachedsi.dwProcessorType);
1106 continue;
1108 /* old 2.0 method */
1109 if (!lstrncmpiA(line, "cpu",strlen("cpu"))) {
1110 if ( isdigit (value[0]) && value[1] == '8' &&
1111 value[2] == '6' && value[3] == 0
1113 switch (value[0] - '0') {
1114 case 3: cachedsi.dwProcessorType = PROCESSOR_INTEL_386;
1115 cachedsi.wProcessorLevel= 3;
1116 break;
1117 case 4: cachedsi.dwProcessorType = PROCESSOR_INTEL_486;
1118 cachedsi.wProcessorLevel= 4;
1119 break;
1120 case 5: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
1121 cachedsi.wProcessorLevel= 5;
1122 break;
1123 case 6: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
1124 cachedsi.wProcessorLevel= 5;
1125 break;
1126 default:cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
1127 cachedsi.wProcessorLevel= 5;
1128 break;
1131 /* set the CPU type of the current processor */
1132 sprintf(buf,"CPU %ld",cachedsi.dwProcessorType);
1133 continue;
1135 if (!lstrncmpiA(line,"fdiv_bug",strlen("fdiv_bug"))) {
1136 if (!lstrncmpiA(value,"yes",3))
1137 PF[PF_FLOATING_POINT_PRECISION_ERRATA] = TRUE;
1139 continue;
1141 if (!lstrncmpiA(line,"fpu",strlen("fpu"))) {
1142 if (!lstrncmpiA(value,"no",2))
1143 PF[PF_FLOATING_POINT_EMULATED] = TRUE;
1145 continue;
1147 if (!lstrncmpiA(line,"processor",strlen("processor"))) {
1148 /* processor number counts up...*/
1149 unsigned int x;
1151 if (sscanf(value,"%d",&x))
1152 if (x+1>cachedsi.dwNumberOfProcessors)
1153 cachedsi.dwNumberOfProcessors=x+1;
1155 /* Create a new processor subkey on a multiprocessor
1156 * system
1158 sprintf(buf,"%d",x);
1160 if (!lstrncmpiA(line,"stepping",strlen("stepping"))) {
1161 int x;
1163 if (sscanf(value,"%d",&x))
1164 cachedsi.wProcessorRevision = x;
1167 ( (!lstrncmpiA(line,"flags",strlen("flags")))
1168 || (!lstrncmpiA(line,"features",strlen("features"))) )
1170 if (strstr(value,"cx8"))
1171 PF[PF_COMPARE_EXCHANGE_DOUBLE] = TRUE;
1172 if (strstr(value,"mmx"))
1173 PF[PF_MMX_INSTRUCTIONS_AVAILABLE] = TRUE;
1174 if (strstr(value,"tsc"))
1175 PF[PF_RDTSC_INSTRUCTION_AVAILABLE] = TRUE;
1176 if (strstr(value,"xmm") || strstr(value,"sse"))
1177 PF[PF_XMMI_INSTRUCTIONS_AVAILABLE] = TRUE;
1178 if (strstr(value,"sse2"))
1179 PF[PF_XMMI64_INSTRUCTIONS_AVAILABLE] = TRUE;
1180 if (strstr(value,"3dnow"))
1181 PF[PF_AMD3D_INSTRUCTIONS_AVAILABLE] = TRUE;
1184 fclose (f);
1186 * ad hoc fix for smp machines.
1187 * some problems on WaitForSingleObject,CreateEvent,SetEvent
1188 * CreateThread ...etc..
1191 cachedsi.dwNumberOfProcessors=1;
1193 #endif /* __linux__ */
1194 cache = 1;
1195 exit:
1196 memcpy(si,&cachedsi,sizeof(*si));
1197 DumpSystemInfo(si);
1200 // avoid undefined expGetSystemInfo
1201 static WIN_BOOL WINAPI expIsProcessorFeaturePresent(DWORD v)
1203 WIN_BOOL result = 0;
1204 if (!pf_set)
1206 SYSTEM_INFO si;
1207 expGetSystemInfo(&si);
1209 if(v<64) result=PF[v];
1210 dbgprintf("IsProcessorFeaturePresent(0x%x) => 0x%x\n", v, result);
1211 return result;
1214 static WIN_BOOL WINAPI expIsDebuggerPresent(void)
1216 return 0;
1219 static long WINAPI expGetVersion(void)
1221 dbgprintf("GetVersion() => 0xC0000004\n");
1222 return 0xC0000004;//Windows 95
1225 static HANDLE WINAPI expHeapCreate(long flags, long init_size, long max_size)
1227 // printf("HeapCreate:");
1228 HANDLE result;
1229 if(init_size==0)
1230 result=(HANDLE)my_mreq(0x110000, 0);
1231 else
1232 result=(HANDLE)my_mreq((init_size + 0xfff) & 0x7ffff000 , 0);
1233 dbgprintf("HeapCreate(flags 0x%x, initial size %d, maximum size %d) => 0x%x\n", flags, init_size, max_size, result);
1234 return result;
1237 // this is another dirty hack
1238 // VP31 is releasing one allocated Heap chunk twice
1239 // we will silently ignore this second call...
1240 static void* heapfreehack = 0;
1241 static int heapfreehackshown = 0;
1242 //void trapbug(void);
1243 static void* WINAPI expHeapAlloc(HANDLE heap, int flags, int size)
1245 void* z;
1247 Morgan's m3jpeg32.dll v. 2.0 encoder expects that request for
1248 HeapAlloc returns area larger than size argument :-/
1250 actually according to M$ Doc HeapCreate size should be rounded
1251 to page boundaries thus we should simulate this
1253 //if (size == 22276) trapbug();
1254 z=my_mreq((size + 0xfff) & 0x7ffff000, (flags & HEAP_ZERO_MEMORY));
1255 if(z==0)
1256 printf("HeapAlloc failure\n");
1257 dbgprintf("HeapAlloc(heap 0x%x, flags 0x%x, size %d) => 0x%x\n", heap, flags, size, z);
1258 heapfreehack = 0; // reset
1259 return z;
1261 static long WINAPI expHeapDestroy(void* heap)
1263 dbgprintf("HeapDestroy(heap 0x%x) => 1\n", heap);
1264 my_release(heap);
1265 return 1;
1268 static long WINAPI expHeapFree(HANDLE heap, DWORD dwFlags, LPVOID lpMem)
1270 dbgprintf("HeapFree(0x%x, 0x%x, pointer 0x%x) => 1\n", heap, dwFlags, lpMem);
1271 if (heapfreehack != lpMem && lpMem != (void*)0xffffffff
1272 && lpMem != (void*)0xbdbdbdbd)
1273 // 0xbdbdbdbd is for i263_drv.drv && libefence
1274 // it seems to be reading from relased memory
1275 // EF_PROTECT_FREE doens't show any probleme
1276 my_release(lpMem);
1277 else
1279 if (!heapfreehackshown++)
1280 printf("Info: HeapFree deallocating same memory twice! (%p)\n", lpMem);
1282 heapfreehack = lpMem;
1283 return 1;
1285 static long WINAPI expHeapSize(int heap, int flags, void* pointer)
1287 long result=my_size(pointer);
1288 dbgprintf("HeapSize(heap 0x%x, flags 0x%x, pointer 0x%x) => %d\n", heap, flags, pointer, result);
1289 return result;
1291 static void* WINAPI expHeapReAlloc(HANDLE heap,int flags,void *lpMem,int size)
1293 long orgsize = my_size(lpMem);
1294 dbgprintf("HeapReAlloc() Size %ld org %d\n",orgsize,size);
1295 return my_realloc(lpMem, size);
1297 static long WINAPI expGetProcessHeap(void)
1299 dbgprintf("GetProcessHeap() => 1\n");
1300 return 1;
1302 static void* WINAPI expVirtualAlloc(void* v1, long v2, long v3, long v4)
1304 void* z = VirtualAlloc(v1, v2, v3, v4);
1305 if(z==0)
1306 printf("VirtualAlloc failure\n");
1307 dbgprintf("VirtualAlloc(0x%x, %d, %d, %d) => 0x%x \n",v1,v2,v3,v4, z);
1308 return z;
1310 static int WINAPI expVirtualFree(void* v1, int v2, int v3)
1312 int result = VirtualFree(v1,v2,v3);
1313 dbgprintf("VirtualFree(0x%x, %d, %d) => %d\n",v1,v2,v3, result);
1314 return result;
1317 /* we're building a table of critical sections. cs_win pointer uses the DLL
1318 cs_unix is the real structure, we're using cs_win only to identifying cs_unix */
1319 struct critsecs_list_t
1321 CRITICAL_SECTION *cs_win;
1322 struct CRITSECT *cs_unix;
1325 /* 'NEWTYPE' is working with VIVO, 3ivX and QTX dll (no more segfaults) -- alex */
1326 #undef CRITSECS_NEWTYPE
1327 //#define CRITSECS_NEWTYPE 1
1329 #ifdef CRITSECS_NEWTYPE
1330 /* increased due to ucod needs more than 32 entries */
1331 /* and 64 should be enough for everything */
1332 #define CRITSECS_LIST_MAX 64
1333 static struct critsecs_list_t critsecs_list[CRITSECS_LIST_MAX];
1335 static int critsecs_get_pos(CRITICAL_SECTION *cs_win)
1337 int i;
1339 for (i=0; i < CRITSECS_LIST_MAX; i++)
1340 if (critsecs_list[i].cs_win == cs_win)
1341 return i;
1342 return -1;
1345 static int critsecs_get_unused(void)
1347 int i;
1349 for (i=0; i < CRITSECS_LIST_MAX; i++)
1350 if (critsecs_list[i].cs_win == NULL)
1351 return i;
1352 return -1;
1355 struct CRITSECT *critsecs_get_unix(CRITICAL_SECTION *cs_win)
1357 int i;
1359 for (i=0; i < CRITSECS_LIST_MAX; i++)
1360 if (critsecs_list[i].cs_win == cs_win && critsecs_list[i].cs_unix)
1361 return critsecs_list[i].cs_unix;
1362 return NULL;
1364 #endif
1366 static void WINAPI expInitializeCriticalSection(CRITICAL_SECTION* c)
1368 dbgprintf("InitializeCriticalSection(0x%x)\n", c);
1369 /* if(sizeof(pthread_mutex_t)>sizeof(CRITICAL_SECTION))
1371 printf(" ERROR:::: sizeof(pthread_mutex_t) is %d, expected <=%d!\n",
1372 sizeof(pthread_mutex_t), sizeof(CRITICAL_SECTION));
1373 return;
1375 /* pthread_mutex_init((pthread_mutex_t*)c, NULL); */
1376 #ifdef CRITSECS_NEWTYPE
1378 struct CRITSECT *cs;
1379 int i = critsecs_get_unused();
1381 if (i < 0)
1383 printf("InitializeCriticalSection(%p) - no more space in list\n", c);
1384 return;
1386 dbgprintf("got unused space at %d\n", i);
1387 cs = malloc(sizeof(struct CRITSECT));
1388 if (!cs)
1390 printf("InitializeCriticalSection(%p) - out of memory\n", c);
1391 return;
1393 pthread_mutex_init(&cs->mutex, NULL);
1394 pthread_cond_init(&cs->unlocked, NULL);
1395 cs->lock_count = 0;
1396 critsecs_list[i].cs_win = c;
1397 critsecs_list[i].cs_unix = cs;
1398 dbgprintf("InitializeCriticalSection -> itemno=%d, cs_win=%p, cs_unix=%p\n",
1399 i, c, cs);
1401 #else
1403 struct CRITSECT* cs = mreq_private(sizeof(struct CRITSECT) + sizeof(CRITICAL_SECTION),
1404 0, AREATYPE_CRITSECT);
1405 pthread_mutex_init(&cs->mutex, NULL);
1406 pthread_cond_init(&cs->unlocked, NULL);
1407 cs->lock_count = 0;
1408 cs->deadbeef = 0xdeadbeef;
1409 *(void**)c = cs;
1411 #endif
1412 return;
1415 static WIN_BOOL WINAPI expInitializeCriticalSectionAndSpinCount(CRITICAL_SECTION* c, DWORD spin)
1417 expInitializeCriticalSection(c);
1418 return 1;
1421 static void WINAPI expEnterCriticalSection(CRITICAL_SECTION* c)
1423 #ifdef CRITSECS_NEWTYPE
1424 struct CRITSECT* cs = critsecs_get_unix(c);
1425 #else
1426 struct CRITSECT* cs = (*(struct CRITSECT**)c);
1427 #endif
1428 dbgprintf("EnterCriticalSection(0x%x) %p\n",c, cs);
1429 if (!cs)
1431 dbgprintf("entered uninitialized critisec!\n");
1432 expInitializeCriticalSection(c);
1433 #ifdef CRITSECS_NEWTYPE
1434 cs=critsecs_get_unix(c);
1435 #else
1436 cs = (*(struct CRITSECT**)c);
1437 #endif
1438 dbgprintf("Win32 Warning: Accessed uninitialized Critical Section (%p)!\n", c);
1440 pthread_mutex_lock(&(cs->mutex));
1441 if (cs->lock_count > 0 && cs->id == pthread_self()) {
1442 cs->lock_count++;
1443 } else {
1444 while (cs->lock_count != 0) {
1445 pthread_cond_wait(&(cs->unlocked), &(cs->mutex));
1447 cs->lock_count = 1;
1448 cs->id = pthread_self();
1450 pthread_mutex_unlock(&(cs->mutex));
1451 return;
1453 static void WINAPI expLeaveCriticalSection(CRITICAL_SECTION* c)
1455 #ifdef CRITSECS_NEWTYPE
1456 struct CRITSECT* cs = critsecs_get_unix(c);
1457 #else
1458 struct CRITSECT* cs = (*(struct CRITSECT**)c);
1459 #endif
1460 // struct CRITSECT* cs=(struct CRITSECT*)c;
1461 dbgprintf("LeaveCriticalSection(0x%x) 0x%x\n",c, cs);
1462 if (!cs)
1464 dbgprintf("Win32 Warning: Leaving uninitialized Critical Section %p!!\n", c);
1465 return;
1467 pthread_mutex_lock(&(cs->mutex));
1468 if (cs->lock_count == 0) {
1469 dbgprintf("Win32 Warning: Unlocking unlocked Critical Section %p!!\n", c);
1470 } else {
1471 cs->lock_count--;
1473 if (cs->lock_count == 0) {
1474 pthread_cond_signal(&(cs->unlocked));
1476 pthread_mutex_unlock(&(cs->mutex));
1477 return;
1480 static void expfree(void* mem); /* forward declaration */
1482 static void WINAPI expDeleteCriticalSection(CRITICAL_SECTION *c)
1484 #ifdef CRITSECS_NEWTYPE
1485 struct CRITSECT* cs = critsecs_get_unix(c);
1486 #else
1487 struct CRITSECT* cs= (*(struct CRITSECT**)c);
1488 #endif
1489 // struct CRITSECT* cs=(struct CRITSECT*)c;
1490 dbgprintf("DeleteCriticalSection(0x%x)\n",c);
1492 if (!cs)
1494 dbgprintf("Win32 Warning: Deleting uninitialized Critical Section %p!!\n", c);
1495 return;
1498 pthread_mutex_lock(&(cs->mutex));
1499 if (cs->lock_count > 0)
1501 dbgprintf("Win32 Warning: Deleting locked Critical Section %p!!\n", c);
1503 pthread_mutex_unlock(&(cs->mutex));
1505 #ifndef GARBAGE
1506 pthread_mutex_destroy(&(cs->mutex));
1507 pthread_cond_destroy(&(cs->unlocked));
1508 // released by GarbageCollector in my_relase otherwise
1509 #endif
1510 my_release(cs);
1511 #ifdef CRITSECS_NEWTYPE
1513 int i = critsecs_get_pos(c);
1515 if (i < 0)
1517 printf("DeleteCriticalSection(%p) error (critsec not found)\n", c);
1518 return;
1521 critsecs_list[i].cs_win = NULL;
1522 expfree(critsecs_list[i].cs_unix);
1523 critsecs_list[i].cs_unix = NULL;
1524 dbgprintf("DeleteCriticalSection -> itemno=%d\n", i);
1526 #endif
1527 return;
1529 static int WINAPI expGetCurrentThreadId(void)
1531 dbgprintf("GetCurrentThreadId() => %d\n", pthread_self());
1532 return pthread_self();
1534 static int WINAPI expGetCurrentProcess(void)
1536 dbgprintf("GetCurrentProcess() => %d\n", getpid());
1537 return getpid();
1540 #ifdef CONFIG_QTX_CODECS
1541 // this version is required for Quicktime codecs (.qtx/.qts) to work.
1542 // (they assume some pointers at FS: segment)
1544 extern void* fs_seg;
1546 //static int tls_count;
1547 static int tls_use_map[64];
1548 static int WINAPI expTlsAlloc(void)
1550 int i;
1551 for(i=0; i<64; i++)
1552 if(tls_use_map[i]==0)
1554 tls_use_map[i]=1;
1555 dbgprintf("TlsAlloc() => %d\n",i);
1556 return i;
1558 dbgprintf("TlsAlloc() => -1 (ERROR)\n");
1559 return -1;
1562 //static int WINAPI expTlsSetValue(DWORD index, void* value)
1563 static int WINAPI expTlsSetValue(int index, void* value)
1565 dbgprintf("TlsSetValue(%d,0x%x) => 1\n",index,value);
1566 // if((index<0) || (index>64))
1567 if((index>=64))
1568 return 0;
1569 *(void**)((char*)fs_seg+0x88+4*index) = value;
1570 return 1;
1573 static void* WINAPI expTlsGetValue(DWORD index)
1575 dbgprintf("TlsGetValue(%d)\n",index);
1576 // if((index<0) || (index>64))
1577 if((index>=64)) return NULL;
1578 return *(void**)((char*)fs_seg+0x88+4*index);
1581 static int WINAPI expTlsFree(int idx)
1583 int index = (int) idx;
1584 dbgprintf("TlsFree(%d)\n",index);
1585 if((index<0) || (index>64))
1586 return 0;
1587 tls_use_map[index]=0;
1588 return 1;
1591 #else
1592 struct tls_s {
1593 void* value;
1594 int used;
1595 struct tls_s* prev;
1596 struct tls_s* next;
1599 static void* WINAPI expTlsAlloc(void)
1601 if (g_tls == NULL)
1603 g_tls=my_mreq(sizeof(tls_t), 0);
1604 g_tls->next=g_tls->prev=NULL;
1606 else
1608 g_tls->next=my_mreq(sizeof(tls_t), 0);
1609 g_tls->next->prev=g_tls;
1610 g_tls->next->next=NULL;
1611 g_tls=g_tls->next;
1613 dbgprintf("TlsAlloc() => 0x%x\n", g_tls);
1614 if (g_tls)
1615 g_tls->value=0; /* XXX For Divx.dll */
1616 return g_tls;
1619 static int WINAPI expTlsSetValue(void* idx, void* value)
1621 tls_t* index = (tls_t*) idx;
1622 int result;
1623 if(index==0)
1624 result=0;
1625 else
1627 index->value=value;
1628 result=1;
1630 dbgprintf("TlsSetValue(index 0x%x, value 0x%x) => %d \n", index, value, result );
1631 return result;
1633 static void* WINAPI expTlsGetValue(void* idx)
1635 tls_t* index = (tls_t*) idx;
1636 void* result;
1637 if(index==0)
1638 result=0;
1639 else
1640 result=index->value;
1641 dbgprintf("TlsGetValue(index 0x%x) => 0x%x\n", index, result);
1642 return result;
1644 static int WINAPI expTlsFree(void* idx)
1646 tls_t* index = (tls_t*) idx;
1647 int result;
1648 if(index==0)
1649 result=0;
1650 else
1652 if(index->next)
1653 index->next->prev=index->prev;
1654 if(index->prev)
1655 index->prev->next=index->next;
1656 if (g_tls == index)
1657 g_tls = index->prev;
1658 my_release((void*)index);
1659 result=1;
1661 dbgprintf("TlsFree(index 0x%x) => %d\n", index, result);
1662 return result;
1664 #endif
1666 static void* WINAPI expLocalAlloc(int flags, int size)
1668 void* z = my_mreq(size, (flags & GMEM_ZEROINIT));
1669 if (z == 0)
1670 printf("LocalAlloc() failed\n");
1671 dbgprintf("LocalAlloc(%d, flags 0x%x) => 0x%x\n", size, flags, z);
1672 return z;
1675 static void* WINAPI expLocalReAlloc(int handle,int size, int flags)
1677 void *newpointer;
1678 int oldsize;
1680 newpointer=NULL;
1681 if (flags & LMEM_MODIFY) {
1682 dbgprintf("LocalReAlloc MODIFY\n");
1683 return (void *)handle;
1685 oldsize = my_size((void *)handle);
1686 newpointer = my_realloc((void *)handle,size);
1687 dbgprintf("LocalReAlloc(%x %d(old %d), flags 0x%x) => 0x%x\n", handle,size,oldsize, flags,newpointer);
1689 return newpointer;
1692 static void* WINAPI expLocalLock(void* z)
1694 dbgprintf("LocalLock(0x%x) => 0x%x\n", z, z);
1695 return z;
1698 static void* WINAPI expGlobalAlloc(int flags, int size)
1700 void* z;
1701 dbgprintf("GlobalAlloc(%d, flags 0x%X)\n", size, flags);
1703 z=my_mreq(size, (flags & GMEM_ZEROINIT));
1704 //z=calloc(size, 1);
1705 //z=malloc(size);
1706 if(z==0)
1707 printf("GlobalAlloc() failed\n");
1708 dbgprintf("GlobalAlloc(%d, flags 0x%x) => 0x%x\n", size, flags, z);
1709 return z;
1711 static void* WINAPI expGlobalLock(void* z)
1713 dbgprintf("GlobalLock(0x%x) => 0x%x\n", z, z);
1714 return z;
1716 // pvmjpg20 - but doesn't work anyway
1717 static int WINAPI expGlobalSize(void* amem)
1719 int size = 100000;
1720 #ifdef GARBAGE
1721 alloc_header* header = last_alloc;
1722 alloc_header* mem = (alloc_header*) amem - 1;
1723 if (amem == 0)
1724 return 0;
1725 pthread_mutex_lock(&memmut);
1726 while (header)
1728 if (header->deadbeef != 0xdeadbeef)
1730 dbgprintf("FATAL found corrupted memory! %p 0x%lx (%d)\n", header, header->deadbeef, alccnt);
1731 break;
1734 if (header == mem)
1736 size = header->size;
1737 break;
1740 header = header->prev;
1742 pthread_mutex_unlock(&memmut);
1743 #endif
1745 dbgprintf("GlobalSize(0x%x)\n", amem);
1746 return size;
1749 static int WINAPI expLoadIconA( long hinstance, char *name )
1751 dbgprintf("LoadIconA( %ld, 0x%x ) => 1\n",hinstance,name);
1752 return 1;
1755 static int WINAPI expLoadStringA(long instance, long id, void* buf, long size)
1757 int result=LoadStringA(instance, id, buf, size);
1758 // if(buf)
1759 dbgprintf("LoadStringA(instance 0x%x, id 0x%x, buffer 0x%x, size %d) => %d ( %s )\n",
1760 instance, id, buf, size, result, buf);
1761 // else
1762 // dbgprintf("LoadStringA(instance 0x%x, id 0x%x, buffer 0x%x, size %d) => %d\n",
1763 // instance, id, buf, size, result);
1764 return result;
1767 static long WINAPI expMultiByteToWideChar(long v1, long v2, char* s1, long siz1, short* s2, int siz2)
1769 #warning FIXME
1770 int i;
1771 int result;
1772 if(s2==0)
1773 result=1;
1774 else
1776 if(siz1>siz2/2)siz1=siz2/2;
1777 for(i=1; i<=siz1; i++)
1779 *s2=*s1;
1780 if(!*s1)break;
1781 s2++;
1782 s1++;
1784 result=i;
1786 if(s1)
1787 dbgprintf("MultiByteToWideChar(codepage %d, flags 0x%x, string 0x%x='%s',"
1788 "size %d, dest buffer 0x%x, dest size %d) => %d\n",
1789 v1, v2, s1, s1, siz1, s2, siz2, result);
1790 else
1791 dbgprintf("MultiByteToWideChar(codepage %d, flags 0x%x, string NULL,"
1792 "size %d, dest buffer 0x%x, dest size %d) =>\n",
1793 v1, v2, siz1, s2, siz2, result);
1794 return result;
1796 static void wch_print(const short* str)
1798 dbgprintf(" src: ");
1799 while(*str)dbgprintf("%c", *str++);
1800 dbgprintf("\n");
1802 static long WINAPI expWideCharToMultiByte(long v1, long v2, short* s1, long siz1,
1803 char* s2, int siz2, char* c3, int* siz3)
1805 int result;
1806 dbgprintf("WideCharToMultiByte(codepage %d, flags 0x%x, src 0x%x, src size %d, "
1807 "dest 0x%x, dest size %d, defch 0x%x, used_defch 0x%x)", v1, v2, s1, siz1, s2, siz2, c3, siz3);
1808 result=WideCharToMultiByte(v1, v2, s1, siz1, s2, siz2, c3, siz3);
1809 dbgprintf("=> %d\n", result);
1810 //if(s1)wch_print(s1);
1811 if(s2)dbgprintf(" dest: %s\n", s2);
1812 return result;
1815 static long WINAPI expGetVersionExA(OSVERSIONINFOA* c)
1817 dbgprintf("GetVersionExA(0x%x) => 1\n");
1818 c->dwOSVersionInfoSize=sizeof(*c);
1819 c->dwMajorVersion=4;
1820 c->dwMinorVersion=0;
1821 c->dwBuildNumber=0x4000457;
1822 #if 1
1823 // leave it here for testing win9x-only codecs
1824 c->dwPlatformId=VER_PLATFORM_WIN32_WINDOWS;
1825 strcpy(c->szCSDVersion, " B");
1826 #else
1827 c->dwPlatformId=VER_PLATFORM_WIN32_NT; // let's not make DLL assume that it can read CR* registers
1828 strcpy(c->szCSDVersion, "Service Pack 3");
1829 #endif
1830 dbgprintf(" Major version: 4\n Minor version: 0\n Build number: 0x4000457\n"
1831 " Platform Id: VER_PLATFORM_WIN32_NT\n Version string: 'Service Pack 3'\n");
1832 return 1;
1835 static long WINAPI expGetVersionExW(OSVERSIONINFOW* c)
1837 char CSDVersion[128];
1838 dbgprintf("GetVersionExW(0x%x) => 1\n");
1839 c->dwOSVersionInfoSize=sizeof(*c);
1840 c->dwMajorVersion=5;
1841 c->dwMinorVersion=0;
1842 c->dwBuildNumber=0x5000457;
1843 #if 1
1844 // leave it here for testing win9x-only codecs
1845 c->dwPlatformId=VER_PLATFORM_WIN32_WINDOWS;
1846 strcpy(CSDVersion, " B");
1847 #else
1848 c->dwPlatformId=VER_PLATFORM_WIN32_NT; // let's not make DLL assume that it can read CR* registers
1849 strcpy(CSDVersion, "Service Pack 3");
1850 #endif
1851 MultiByteToWideChar(65001, 0x0, CSDVersion, -1, c->szCSDVersion, 128);
1852 dbgprintf(" Major version: %d\n Minor version: %d\n Build number: 0x%08x\n"
1853 " Platform Id: %s\n Version string: '%s'\n",
1854 c->dwMajorVersion, c->dwMinorVersion, c->dwBuildNumber,
1855 (c->dwPlatformId==VER_PLATFORM_WIN32_WINDOWS ? "VER_PLATFORM_WIN32_WINDOWS" :
1856 (c->dwPlatformId==VER_PLATFORM_WIN32_NT ? "VER_PLATFORM_WIN32_NT" : "Unknown")),
1857 CSDVersion);
1858 return 1;
1861 static HANDLE WINAPI expCreateSemaphoreA(char* v1, long init_count,
1862 long max_count, char* name)
1864 pthread_mutex_t *pm;
1865 pthread_cond_t *pc;
1866 HANDLE ret;
1868 mutex_list* pp;
1869 printf("CreateSemaphoreA(%p = %s)\n", name, (name ? name : "<null>"));
1870 pp=mlist;
1871 while(pp)
1873 printf("%p => ", pp);
1874 pp=pp->prev;
1876 printf("0\n");
1878 pthread_mutex_lock(&mlist_lock);
1879 if(mlist!=NULL)
1881 mutex_list* pp=mlist;
1882 if(name!=NULL)
1885 if((strcmp(pp->name, name)==0) && (pp->type==1))
1887 dbgprintf("CreateSemaphoreA(0x%x, init_count %d, max_count %d, name 0x%x='%s') => 0x%x\n",
1888 v1, init_count, max_count, name, name, mlist);
1889 ret = (HANDLE)mlist;
1890 pthread_mutex_unlock(&mlist_lock);
1891 return ret;
1893 }while((pp=pp->prev) != NULL);
1895 pm=mreq_private(sizeof(pthread_mutex_t), 0, AREATYPE_MUTEX);
1896 pthread_mutex_init(pm, NULL);
1897 pc=mreq_private(sizeof(pthread_cond_t), 0, AREATYPE_COND);
1898 pthread_cond_init(pc, NULL);
1899 if(mlist==NULL)
1901 mlist=mreq_private(sizeof(mutex_list), 00, AREATYPE_EVENT);
1902 mlist->next=mlist->prev=NULL;
1904 else
1906 mlist->next=mreq_private(sizeof(mutex_list), 00, AREATYPE_EVENT);
1907 mlist->next->prev=mlist;
1908 mlist->next->next=NULL;
1909 mlist=mlist->next;
1910 // printf("new semaphore %p\n", mlist);
1912 mlist->type=1; /* Type Semaphore */
1913 mlist->pm=pm;
1914 mlist->pc=pc;
1915 mlist->state=0;
1916 mlist->reset=0;
1917 mlist->semaphore=init_count;
1918 if(name!=NULL)
1919 strncpy(mlist->name, name, 64);
1920 else
1921 mlist->name[0]=0;
1922 if(pm==NULL)
1923 dbgprintf("ERROR::: CreateSemaphoreA failure\n");
1924 if(name)
1925 dbgprintf("CreateSemaphoreA(0x%x, init_count %d, max_count %d, name 0x%x='%s') => 0x%x\n",
1926 v1, init_count, max_count, name, name, mlist);
1927 else
1928 dbgprintf("CreateSemaphoreA(0x%x, init_count %d, max_count %d, name 0) => 0x%x\n",
1929 v1, init_count, max_count, mlist);
1930 ret = (HANDLE)mlist;
1931 pthread_mutex_unlock(&mlist_lock);
1932 return ret;
1935 static HANDLE WINAPI expCreateSemaphoreW(char* v1, long init_count,
1936 long max_count, const WCHAR* name)
1938 char ascii_name[256];
1939 char *aname = NULL;
1940 if (name) {
1941 WideCharToMultiByte(65001, 0x0, name, -1, ascii_name, 256, NULL, NULL);
1942 aname = ascii_name;
1944 return expCreateSemaphoreA(v1, init_count, max_count, aname);
1947 static long WINAPI expReleaseSemaphore(long hsem, long increment, long* prev_count)
1949 // The state of a semaphore object is signaled when its count
1950 // is greater than zero and nonsignaled when its count is equal to zero
1951 // Each time a waiting thread is released because of the semaphore's signaled
1952 // state, the count of the semaphore is decreased by one.
1953 mutex_list *ml = (mutex_list *)hsem;
1955 pthread_mutex_lock(ml->pm);
1956 if (prev_count != 0) *prev_count = ml->semaphore;
1957 if (ml->semaphore == 0) pthread_cond_signal(ml->pc);
1958 ml->semaphore += increment;
1959 pthread_mutex_unlock(ml->pm);
1960 dbgprintf("ReleaseSemaphore(semaphore 0x%x, increment %d, prev_count 0x%x) => 1\n",
1961 hsem, increment, prev_count);
1962 return 1;
1965 static HANDLE WINAPI expCreateMutexA(void *pSecAttr,
1966 char bInitialOwner, const char *name)
1968 pthread_mutex_t *pm;
1969 pthread_cond_t *pc;
1970 HANDLE ret;
1971 pthread_mutex_lock(&mlist_lock);
1972 if(mlist!=NULL)
1974 mutex_list* pp=mlist;
1975 if(name!=NULL)
1978 if((strcmp(pp->name, name)==0) && (pp->type==2))
1980 dbgprintf("CreateMutexA(0x%x, %d, '%s') => 0x%x\n", pSecAttr, bInitialOwner, name, mlist);
1981 ret = (HANDLE)mlist;
1982 pthread_mutex_unlock(&mlist_lock);
1983 return ret;
1985 }while((pp=pp->prev) != NULL);
1987 pm=mreq_private(sizeof(pthread_mutex_t), 0, AREATYPE_MUTEX);
1988 pthread_mutex_init(pm, NULL);
1989 pc=mreq_private(sizeof(pthread_cond_t), 0, AREATYPE_COND);
1990 pthread_cond_init(pc, NULL);
1991 if(mlist==NULL)
1993 mlist=mreq_private(sizeof(mutex_list), 00, AREATYPE_EVENT);
1994 mlist->next=mlist->prev=NULL;
1996 else
1998 mlist->next=mreq_private(sizeof(mutex_list), 00, AREATYPE_EVENT);
1999 mlist->next->prev=mlist;
2000 mlist->next->next=NULL;
2001 mlist=mlist->next;
2003 mlist->type=2; /* Type Mutex */
2004 mlist->pm=pm;
2005 mlist->pc=pc;
2006 mlist->state=0;
2007 mlist->reset=0;
2008 mlist->semaphore=0;
2009 if (bInitialOwner) {
2010 mlist->owner = pthread_self();
2011 mlist->lock_count = 1;
2012 } else {
2013 mlist->owner = (pthread_t)0;
2014 mlist->lock_count = 0;
2016 if(name!=NULL)
2017 strncpy(mlist->name, name, 64);
2018 else
2019 mlist->name[0]=0;
2020 if(pm==NULL)
2021 dbgprintf("ERROR::: CreateMutexA failure\n");
2022 if(name)
2023 dbgprintf("CreateMutexA(0x%x, %d, '%s') => 0x%x\n",
2024 pSecAttr, bInitialOwner, name, mlist);
2025 else
2026 dbgprintf("CreateMutexA(0x%x, %d, NULL) => 0x%x\n",
2027 pSecAttr, bInitialOwner, mlist);
2028 ret = (HANDLE)mlist;
2029 pthread_mutex_unlock(&mlist_lock);
2030 return ret;
2033 static HANDLE WINAPI expCreateMutexW(void *pSecAttr, char bInitialOwner, const WCHAR *name)
2035 char ascii_name[256];
2036 char *aname = NULL;
2037 if (name) {
2038 WideCharToMultiByte(65001, 0x0, name, -1, ascii_name, 256, NULL, NULL);
2039 aname = ascii_name;
2041 return expCreateMutexA(pSecAttr, bInitialOwner, aname);
2044 static int WINAPI expReleaseMutex(HANDLE hMutex)
2046 mutex_list *ml = (mutex_list *)hMutex;
2048 pthread_mutex_lock(ml->pm);
2049 if (--ml->lock_count == 0) pthread_cond_signal(ml->pc);
2050 pthread_mutex_unlock(ml->pm);
2051 return 1;
2054 static DWORD WINAPI expSignalObjectAndWait(HANDLE hObjectToSignal,
2055 HANDLE hObjectToWaitOn,
2056 DWORD dwMilliseconds,
2057 WIN_BOOL bAlertable) {
2058 mutex_list* mlist = (mutex_list*)hObjectToSignal;
2060 switch (mlist->type) {
2061 case 0: // Event
2062 expSetEvent(mlist);
2063 break;
2064 case 1: // Semaphore
2065 expReleaseSemaphore(mlist, 1, NULL);
2066 break;
2067 case 2: // Mutex
2068 expReleaseMutex(mlist);
2069 break;
2070 default:
2071 dbgprintf("Signalling unknown object type %d!\n", hObjectToSignal);
2073 return expWaitForSingleObject(hObjectToWaitOn, dwMilliseconds);
2076 static long WINAPI expRegOpenKeyExA(long key, const char* subkey, long reserved, long access, int* newkey)
2078 long result=RegOpenKeyExA(key, subkey, reserved, access, newkey);
2079 dbgprintf("RegOpenKeyExA(key 0x%x, subkey %s, reserved %d, access 0x%x, pnewkey 0x%x) => %d\n",
2080 key, subkey, reserved, access, newkey, result);
2081 if(newkey)dbgprintf(" New key: 0x%x\n", *newkey);
2082 return result;
2084 static long WINAPI expRegCloseKey(long key)
2086 long result=RegCloseKey(key);
2087 dbgprintf("RegCloseKey(0x%x) => %d\n", key, result);
2088 return result;
2090 static long WINAPI expRegQueryValueExA(long key, const char* value, int* reserved, int* type, int* data, int* count)
2092 long result=RegQueryValueExA(key, value, reserved, type, data, count);
2093 dbgprintf("RegQueryValueExA(key 0x%x, value %s, reserved 0x%x, data 0x%x, count 0x%x)"
2094 " => 0x%x\n", key, value, reserved, data, count, result);
2095 if(data && count)dbgprintf(" read %d bytes: '%s'\n", *count, data);
2096 return result;
2099 //from wine source dlls/advapi32/registry.c
2100 static long WINAPI expRegCreateKeyA(long hkey, const char* name, int *retkey)
2102 dbgprintf("RegCreateKeyA(key 0x%x, name 0x%x='%s',newkey=0x%x)\n",hkey,name,retkey);
2103 return RegCreateKeyExA( hkey, name, 0, NULL,REG_OPTION_NON_VOLATILE,
2104 KEY_ALL_ACCESS , NULL, retkey, NULL );
2107 static long WINAPI expRegCreateKeyExA(long key, const char* name, long reserved,
2108 void* classs, long options, long security,
2109 void* sec_attr, int* newkey, int* status)
2111 long result=RegCreateKeyExA(key, name, reserved, classs, options, security, sec_attr, newkey, status);
2112 dbgprintf("RegCreateKeyExA(key 0x%x, name 0x%x='%s', reserved=0x%x,"
2113 " 0x%x, 0x%x, 0x%x, newkey=0x%x, status=0x%x) => %d\n",
2114 key, name, name, reserved, classs, options, security, sec_attr, newkey, status, result);
2115 if(!result && newkey) dbgprintf(" New key: 0x%x\n", *newkey);
2116 if(!result && status) dbgprintf(" New key status: 0x%x\n", *status);
2117 return result;
2119 static long WINAPI expRegSetValueExA(long key, const char* name, long v1, long v2, void* data, long size)
2121 long result=RegSetValueExA(key, name, v1, v2, data, size);
2122 dbgprintf("RegSetValueExA(key 0x%x, name '%s', 0x%x, 0x%x, data 0x%x -> 0x%x '%s', size=%d) => %d",
2123 key, name, v1, v2, data, *(int*)data, data, size, result);
2124 return result;
2127 static long WINAPI expRegOpenKeyA (long hKey, LPCSTR lpSubKey, int* phkResult)
2129 long result=RegOpenKeyExA(hKey, lpSubKey, 0, 0, phkResult);
2130 dbgprintf("RegOpenKeyExA(key 0x%x, subkey '%s', 0x%x) => %d\n",
2131 hKey, lpSubKey, phkResult, result);
2132 if(!result && phkResult) dbgprintf(" New key: 0x%x\n", *phkResult);
2133 return result;
2136 static DWORD WINAPI expRegEnumValueA(HKEY hkey, DWORD index, LPSTR value, LPDWORD val_count,
2137 LPDWORD reserved, LPDWORD type, LPBYTE data, LPDWORD count)
2139 return RegEnumValueA(hkey, index, value, val_count,
2140 reserved, type, data, count);
2143 static DWORD WINAPI expRegEnumKeyExA(HKEY hKey, DWORD dwIndex, LPSTR lpName, LPDWORD lpcbName,
2144 LPDWORD lpReserved, LPSTR lpClass, LPDWORD lpcbClass,
2145 LPFILETIME lpftLastWriteTime)
2147 return RegEnumKeyExA(hKey, dwIndex, lpName, lpcbName, lpReserved, lpClass,
2148 lpcbClass, lpftLastWriteTime);
2151 static long WINAPI expQueryPerformanceCounter(long long* z)
2153 longcount(z);
2154 dbgprintf("QueryPerformanceCounter(0x%x) => 1 ( %Ld )\n", z, *z);
2155 return 1;
2159 * dummy function RegQueryInfoKeyA(), required by vss codecs
2161 static DWORD WINAPI expRegQueryInfoKeyA( HKEY hkey, LPSTR class, LPDWORD class_len, LPDWORD reserved,
2162 LPDWORD subkeys, LPDWORD max_subkey, LPDWORD max_class,
2163 LPDWORD values, LPDWORD max_value, LPDWORD max_data,
2164 LPDWORD security, FILETIME *modif )
2166 return ERROR_SUCCESS;
2170 * return CPU clock (in kHz), using linux's /proc filesystem (/proc/cpuinfo)
2172 static double linux_cpuinfo_freq(void)
2174 double freq=-1;
2175 FILE *f;
2176 char line[200];
2177 char *s,*value;
2179 f = fopen ("/proc/cpuinfo", "r");
2180 if (f != NULL) {
2181 while (fgets(line,sizeof(line),f)!=NULL) {
2182 /* NOTE: the ':' is the only character we can rely on */
2183 if (!(value = strchr(line,':')))
2184 continue;
2185 /* terminate the valuename */
2186 *value++ = '\0';
2187 /* skip any leading spaces */
2188 while (*value==' ') value++;
2189 if ((s=strchr(value,'\n')))
2190 *s='\0';
2192 if (!strncasecmp(line, "cpu MHz",strlen("cpu MHz"))
2193 && sscanf(value, "%lf", &freq) == 1) {
2194 freq*=1000;
2195 break;
2198 fclose(f);
2200 return freq;
2204 static double solaris_kstat_freq(void)
2206 #if defined(HAVE_LIBKSTAT) && defined(KSTAT_DATA_INT32)
2208 * try to extract the CPU speed from the solaris kernel's kstat data
2210 kstat_ctl_t *kc;
2211 kstat_t *ksp;
2212 kstat_named_t *kdata;
2213 int mhz = 0;
2215 kc = kstat_open();
2216 if (kc != NULL)
2218 ksp = kstat_lookup(kc, "cpu_info", 0, "cpu_info0");
2220 /* kstat found and name/value pairs? */
2221 if (ksp != NULL && ksp->ks_type == KSTAT_TYPE_NAMED)
2223 /* read the kstat data from the kernel */
2224 if (kstat_read(kc, ksp, NULL) != -1)
2227 * lookup desired "clock_MHz" entry, check the expected
2228 * data type
2230 kdata = (kstat_named_t *)kstat_data_lookup(ksp, "clock_MHz");
2231 if (kdata != NULL && kdata->data_type == KSTAT_DATA_INT32)
2232 mhz = kdata->value.i32;
2235 kstat_close(kc);
2238 if (mhz > 0)
2239 return mhz * 1000.;
2240 #endif /* HAVE_LIBKSTAT */
2241 return -1; // kstat stuff is not available, CPU freq is unknown
2245 * Measure CPU freq using the pentium's time stamp counter register (TSC)
2247 static double tsc_freq(void)
2249 static double ofreq=0.0;
2250 int i;
2251 int x,y;
2252 i=time(NULL);
2253 if (ofreq != 0.0) return ofreq;
2254 while(i==time(NULL));
2255 x=localcount();
2256 i++;
2257 while(i==time(NULL));
2258 y=localcount();
2259 ofreq = (double)(y-x)/1000.;
2260 return ofreq;
2263 static double CPU_Freq(void)
2265 double freq;
2267 if ((freq = linux_cpuinfo_freq()) > 0)
2268 return freq;
2270 if ((freq = solaris_kstat_freq()) > 0)
2271 return freq;
2273 return tsc_freq();
2276 static long WINAPI expQueryPerformanceFrequency(long long* z)
2278 *z=(long long)CPU_Freq();
2279 dbgprintf("QueryPerformanceFrequency(0x%x) => 1 ( %Ld )\n", z, *z);
2280 return 1;
2282 static long WINAPI exptimeGetTime(void)
2284 struct timeval t;
2285 long result;
2286 gettimeofday(&t, 0);
2287 result=1000*t.tv_sec+t.tv_usec/1000;
2288 dbgprintf("timeGetTime() => %d\n", result);
2289 return result;
2291 static void* WINAPI expLocalHandle(void* v)
2293 dbgprintf("LocalHandle(0x%x) => 0x%x\n", v, v);
2294 return v;
2297 static void* WINAPI expGlobalHandle(void* v)
2299 dbgprintf("GlobalHandle(0x%x) => 0x%x\n", v, v);
2300 return v;
2302 static int WINAPI expGlobalUnlock(void* v)
2304 dbgprintf("GlobalUnlock(0x%x) => 1\n", v);
2305 return 1;
2307 static void* WINAPI expGlobalFree(void* v)
2309 dbgprintf("GlobalFree(0x%x) => 0\n", v);
2310 my_release(v);
2311 //free(v);
2312 return 0;
2315 static void* WINAPI expGlobalReAlloc(void* v, int size, int flags)
2317 void* result=my_realloc(v, size);
2318 //void* result=realloc(v, size);
2319 dbgprintf("GlobalReAlloc(0x%x, size %d, flags 0x%x) => 0x%x\n", v,size,flags,result);
2320 return result;
2323 static int WINAPI expLocalUnlock(void* v)
2325 dbgprintf("LocalUnlock(0x%x) => 1\n", v);
2326 return 1;
2329 static void* WINAPI expLocalFree(void* v)
2331 dbgprintf("LocalFree(0x%x) => 0\n", v);
2332 my_release(v);
2333 return 0;
2335 static HRSRC WINAPI expFindResourceA(HMODULE module, char* name, char* type)
2337 HRSRC result;
2339 result=FindResourceA(module, name, type);
2340 dbgprintf("FindResourceA(module 0x%x, name 0x%x(%s), type 0x%x(%s)) => 0x%x\n",
2341 module, name, HIWORD(name) ? name : "UNICODE", type, HIWORD(type) ? type : "UNICODE", result);
2342 return result;
2345 static HGLOBAL WINAPI expLoadResource(HMODULE module, HRSRC res)
2347 HGLOBAL result=LoadResource(module, res);
2348 dbgprintf("LoadResource(module 0x%x, resource 0x%x) => 0x%x\n", module, res, result);
2349 return result;
2351 static void* WINAPI expLockResource(long res)
2353 void* result=LockResource(res);
2354 dbgprintf("LockResource(0x%x) => 0x%x\n", res, result);
2355 return result;
2357 static int WINAPI expFreeResource(long res)
2359 int result=FreeResource(res);
2360 dbgprintf("FreeResource(0x%x) => %d\n", res, result);
2361 return result;
2363 //bool fun(HANDLE)
2364 //!0 on success
2365 static int WINAPI expCloseHandle(long v1)
2367 dbgprintf("CloseHandle(0x%x) => 1\n", v1);
2368 /* do not close stdin,stdout and stderr */
2369 if (v1 > 2)
2370 if (!close(v1))
2371 return 0;
2372 return 1;
2375 static const char* WINAPI expGetCommandLineA(void)
2377 dbgprintf("GetCommandLineA() => \"c:\\aviplay.exe\"\n");
2378 return "c:\\aviplay.exe";
2380 static short envs[]={'p', 'a', 't', 'h', ' ', 'c', ':', '\\', 0, 0};
2381 static LPWSTR WINAPI expGetEnvironmentStringsW(void)
2383 dbgprintf("GetEnvironmentStringsW() => 0\n", envs);
2384 return 0;
2386 static void * WINAPI expRtlZeroMemory(void *p, size_t len)
2388 void* result=memset(p,0,len);
2389 dbgprintf("RtlZeroMemory(0x%x, len %d) => 0x%x\n",p,len,result);
2390 return result;
2392 static void * WINAPI expRtlMoveMemory(void *dst, void *src, size_t len)
2394 void* result=memmove(dst,src,len);
2395 dbgprintf("RtlMoveMemory (dest 0x%x, src 0x%x, len %d) => 0x%x\n",dst,src,len,result);
2396 return result;
2399 static void * WINAPI expRtlFillMemory(void *p, int ch, size_t len)
2401 void* result=memset(p,ch,len);
2402 dbgprintf("RtlFillMemory(0x%x, char 0x%x, len %d) => 0x%x\n",p,ch,len,result);
2403 return result;
2405 static int WINAPI expFreeEnvironmentStringsW(short* strings)
2407 dbgprintf("FreeEnvironmentStringsW(0x%x) => 1\n", strings);
2408 return 1;
2410 static int WINAPI expFreeEnvironmentStringsA(char* strings)
2412 dbgprintf("FreeEnvironmentStringsA(0x%x) => 1\n", strings);
2413 return 1;
2416 static const char ch_envs[]=
2417 "__MSVCRT_HEAP_SELECT=__GLOBAL_HEAP_SELECTED,1\r\n"
2418 "PATH=C:\\;C:\\windows\\;C:\\windows\\system\r\n";
2419 static LPCSTR WINAPI expGetEnvironmentStrings(void)
2421 dbgprintf("GetEnvironmentStrings() => 0x%x\n", ch_envs);
2422 return (LPCSTR)ch_envs;
2423 // dbgprintf("GetEnvironmentStrings() => 0\n");
2424 // return 0;
2427 static int WINAPI expGetStartupInfoA(STARTUPINFOA *s)
2429 dbgprintf("GetStartupInfoA(0x%x) => 1\n");
2430 memset(s, 0, sizeof(*s));
2431 s->cb=sizeof(*s);
2432 // s->lpReserved="Reserved";
2433 // s->lpDesktop="Desktop";
2434 // s->lpTitle="Title";
2435 // s->dwX=s->dwY=0;
2436 // s->dwXSize=s->dwYSize=200;
2437 s->dwFlags=s->wShowWindow=1;
2438 // s->hStdInput=s->hStdOutput=s->hStdError=0x1234;
2439 dbgprintf(" cb=%d\n", s->cb);
2440 dbgprintf(" lpReserved='%s'\n", s->lpReserved);
2441 dbgprintf(" lpDesktop='%s'\n", s->lpDesktop);
2442 dbgprintf(" lpTitle='%s'\n", s->lpTitle);
2443 dbgprintf(" dwX=%d dwY=%d dwXSize=%d dwYSize=%d\n",
2444 s->dwX, s->dwY, s->dwXSize, s->dwYSize);
2445 dbgprintf(" dwXCountChars=%d dwYCountChars=%d dwFillAttribute=%d\n",
2446 s->dwXCountChars, s->dwYCountChars, s->dwFillAttribute);
2447 dbgprintf(" dwFlags=0x%x wShowWindow=0x%x cbReserved2=0x%x\n",
2448 s->dwFlags, s->wShowWindow, s->cbReserved2);
2449 dbgprintf(" lpReserved2=0x%x hStdInput=0x%x hStdOutput=0x%x hStdError=0x%x\n",
2450 s->lpReserved2, s->hStdInput, s->hStdOutput, s->hStdError);
2451 return 1;
2454 static int WINAPI expGetStdHandle(int z)
2456 dbgprintf("GetStdHandle(0x%x) => 0x%x\n", z+0x1234);
2457 return z+0x1234;
2460 #ifdef CONFIG_QTX_CODECS
2461 #define FILE_HANDLE_quicktimeqts ((HANDLE)0x444)
2462 #define FILE_HANDLE_quicktimeqtx ((HANDLE)0x445)
2463 #endif
2465 static int WINAPI expGetFileType(int handle)
2467 dbgprintf("GetFileType(0x%x) => 0x3 = pipe\n", handle);
2468 return 0x3;
2470 #ifdef CONFIG_QTX_CODECS
2471 static int WINAPI expGetFileAttributesA(char *filename)
2473 dbgprintf("GetFileAttributesA(%s) => FILE_ATTR_NORMAL\n", filename);
2474 if (strstr(filename, "QuickTime.qts"))
2475 return FILE_ATTRIBUTE_SYSTEM;
2476 return FILE_ATTRIBUTE_NORMAL;
2478 #endif
2479 static int WINAPI expSetHandleCount(int count)
2481 dbgprintf("SetHandleCount(0x%x) => 1\n", count);
2482 return 1;
2484 static int WINAPI expGetACP(void)
2486 dbgprintf("GetACP() => 0\n");
2487 return 0;
2489 static int WINAPI expGetModuleFileNameA(int module, char* s, int len)
2491 WINE_MODREF *mr;
2492 int result;
2493 //printf("File name of module %X (%s) requested\n", module, s);
2495 if (module == 0 && len >= 12)
2497 /* return caller program name */
2498 strcpy(s, "aviplay.dll");
2499 result=1;
2501 else if(s==0)
2502 result=0;
2503 else
2504 if(len<35)
2505 result=0;
2506 else
2508 result=1;
2509 strcpy(s, "c:\\windows\\system\\");
2510 mr=MODULE32_LookupHMODULE(module);
2511 if(mr==0)//oops
2512 strcat(s, "aviplay.dll");
2513 else
2514 if(strrchr(mr->filename, '/')==NULL)
2515 strcat(s, mr->filename);
2516 else
2517 strcat(s, strrchr(mr->filename, '/')+1);
2519 if(!s)
2520 dbgprintf("GetModuleFileNameA(0x%x, 0x%x, %d) => %d\n",
2521 module, s, len, result);
2522 else
2523 dbgprintf("GetModuleFileNameA(0x%x, 0x%x, %d) => %d ( '%s' )\n",
2524 module, s, len, result, s);
2525 return result;
2528 static int WINAPI expGetModuleBaseNameA(int process, int module, char* s, int len)
2530 int result = 0;
2532 if (s && len) {
2533 av_strlcpy(s, "aviplay.dll", len);
2534 result = strlen(s);
2537 dbgprintf("GetModuleBaseNameA(0x%x, 0x%x, 0x%x, %d) => %d\n",
2538 process, module, s, len, result);
2540 return result;
2543 static int WINAPI expSetUnhandledExceptionFilter(void* filter)
2545 dbgprintf("SetUnhandledExceptionFilter(0x%x) => 1\n", filter);
2546 return 1;//unsupported and probably won't ever be supported
2549 static int WINAPI expLoadLibraryA(char* name)
2551 int result = 0;
2552 char* lastbc;
2553 if (!name)
2554 return -1;
2555 // we skip to the last backslash
2556 // this is effectively eliminating weird characters in
2557 // the text output windows
2559 lastbc = strrchr(name, '\\');
2560 if (lastbc)
2562 int i;
2563 lastbc++;
2564 for (i = 0; 1 ;i++)
2566 name[i] = *lastbc++;
2567 if (!name[i])
2568 break;
2571 if(strncmp(name, "c:\\windows\\", 11)==0) name += 11;
2572 if(strncmp(name, ".\\", 2)==0) name += 2;
2574 dbgprintf("Entering LoadLibraryA(%s)\n", name);
2576 // PIMJ and VIVO audio are loading kernel32.dll
2577 if (strcasecmp(name, "kernel32.dll") == 0 || strcasecmp(name, "kernel32") == 0)
2578 return MODULE_HANDLE_kernel32;
2579 // return ERROR_SUCCESS; /* yeah, we have also the kernel32 calls */
2580 /* exported -> do not return failed! */
2582 if (strcasecmp(name, "user32.dll") == 0 || strcasecmp(name, "user32") == 0)
2583 // return MODULE_HANDLE_kernel32;
2584 return MODULE_HANDLE_user32;
2586 #ifdef CONFIG_QTX_CODECS
2587 if (strcasecmp(name, "wininet.dll") == 0 || strcasecmp(name, "wininet") == 0)
2588 return MODULE_HANDLE_wininet;
2589 if (strcasecmp(name, "ddraw.dll") == 0 || strcasecmp(name, "ddraw") == 0)
2590 return MODULE_HANDLE_ddraw;
2591 if (strcasecmp(name, "advapi32.dll") == 0 || strcasecmp(name, "advapi32") == 0)
2592 return MODULE_HANDLE_advapi32;
2593 #endif
2595 if (strcasecmp(name, "comdlg32.dll") == 0 || strcasecmp(name, "comdlg32") == 0)
2596 return MODULE_HANDLE_comdlg32;
2597 if (strcasecmp(name, "msvcrt.dll") == 0 || strcasecmp(name, "msvcrt") == 0)
2598 return MODULE_HANDLE_msvcrt;
2599 if (strcasecmp(name, "ole32.dll") == 0 || strcasecmp(name, "ole32") == 0)
2600 return MODULE_HANDLE_ole32;
2601 if (strcasecmp(name, "winmm.dll") == 0 || strcasecmp(name, "winmm") == 0)
2602 return MODULE_HANDLE_winmm;
2603 if (strcasecmp(name, "psapi.dll") == 0 || strcasecmp(name, "psapi") == 0)
2604 return MODULE_HANDLE_psapi;
2606 result=LoadLibraryA(name);
2607 dbgprintf("Returned LoadLibraryA(0x%x='%s'), def_path=%s => 0x%x\n", name, name, def_path, result);
2609 return result;
2612 static int WINAPI expFreeLibrary(int module)
2614 #ifdef CONFIG_QTX_CODECS
2615 int result=0; /* FIXME:XXX: qtx svq3 frees up qt.qts */
2616 #else
2617 int result=FreeLibrary(module);
2618 #endif
2619 dbgprintf("FreeLibrary(0x%x) => %d\n", module, result);
2620 return result;
2623 static void* WINAPI expGetProcAddress(HMODULE mod, char* name)
2625 void* result;
2626 switch(mod){
2627 case MODULE_HANDLE_kernel32:
2628 result=LookupExternalByName("kernel32.dll", name); break;
2629 case MODULE_HANDLE_user32:
2630 result=LookupExternalByName("user32.dll", name); break;
2631 #ifdef CONFIG_QTX_CODECS
2632 case MODULE_HANDLE_wininet:
2633 result=LookupExternalByName("wininet.dll", name); break;
2634 case MODULE_HANDLE_ddraw:
2635 result=LookupExternalByName("ddraw.dll", name); break;
2636 case MODULE_HANDLE_advapi32:
2637 result=LookupExternalByName("advapi32.dll", name); break;
2638 #endif
2639 case MODULE_HANDLE_comdlg32:
2640 result=LookupExternalByName("comdlg32.dll", name); break;
2641 case MODULE_HANDLE_msvcrt:
2642 result=LookupExternalByName("msvcrt.dll", name); break;
2643 case MODULE_HANDLE_ole32:
2644 result=LookupExternalByName("ole32.dll", name); break;
2645 case MODULE_HANDLE_winmm:
2646 result=LookupExternalByName("winmm.dll", name); break;
2647 case MODULE_HANDLE_psapi:
2648 result=LookupExternalByName("psapi.dll", name); break;
2649 default:
2650 result=GetProcAddress(mod, name);
2652 if((unsigned int)name > 0xffff)
2653 dbgprintf("GetProcAddress(0x%x, '%s') => 0x%x\n", mod, name, result);
2654 else
2655 dbgprintf("GetProcAddress(0x%x, '%d') => 0x%x\n", mod, (int)name, result);
2656 return result;
2659 static long WINAPI expCreateFileMappingA(int hFile, void* lpAttr,
2660 long flProtect, long dwMaxHigh,
2661 long dwMaxLow, const char* name)
2663 long result=CreateFileMappingA(hFile, lpAttr, flProtect, dwMaxHigh, dwMaxLow, name);
2664 if(!name)
2665 dbgprintf("CreateFileMappingA(file 0x%x, lpAttr 0x%x,"
2666 "flProtect 0x%x, dwMaxHigh 0x%x, dwMaxLow 0x%x, name 0) => %d\n",
2667 hFile, lpAttr, flProtect, dwMaxHigh, dwMaxLow, result);
2668 else
2669 dbgprintf("CreateFileMappingA(file 0x%x, lpAttr 0x%x,"
2670 "flProtect 0x%x, dwMaxHigh 0x%x, dwMaxLow 0x%x, name 0x%x='%s') => %d\n",
2671 hFile, lpAttr, flProtect, dwMaxHigh, dwMaxLow, name, name, result);
2672 return result;
2675 static long WINAPI expOpenFileMappingA(long hFile, long hz, const char* name)
2677 long result=OpenFileMappingA(hFile, hz, name);
2678 if(!name)
2679 dbgprintf("OpenFileMappingA(0x%x, 0x%x, 0) => %d\n",
2680 hFile, hz, result);
2681 else
2682 dbgprintf("OpenFileMappingA(0x%x, 0x%x, 0x%x='%s') => %d\n",
2683 hFile, hz, name, name, result);
2684 return result;
2687 static void* WINAPI expMapViewOfFile(HANDLE file, DWORD mode, DWORD offHigh,
2688 DWORD offLow, DWORD size)
2690 dbgprintf("MapViewOfFile(0x%x, 0x%x, 0x%x, 0x%x, size %d) => 0x%x\n",
2691 file,mode,offHigh,offLow,size,(char*)file+offLow);
2692 return (char*)file+offLow;
2695 static void* WINAPI expUnmapViewOfFile(void* view)
2697 dbgprintf("UnmapViewOfFile(0x%x) => 0\n", view);
2698 return 0;
2701 static void* WINAPI expSleep(int time)
2703 #if HAVE_NANOSLEEP
2704 /* solaris doesn't have thread safe usleep */
2705 struct timespec tsp;
2706 tsp.tv_sec = time / 1000000;
2707 tsp.tv_nsec = (time % 1000000) * 1000;
2708 nanosleep(&tsp, NULL);
2709 #else
2710 usleep(time);
2711 #endif
2712 dbgprintf("Sleep(%d) => 0\n", time);
2713 return 0;
2716 // why does IV32 codec want to call this? I don't know ...
2717 static int WINAPI expCreateCompatibleDC(int hdc)
2719 int dc = 0;//0x81;
2720 //dbgprintf("CreateCompatibleDC(%d) => 0x81\n", hdc);
2721 dbgprintf("CreateCompatibleDC(%d) => %d\n", hdc, dc);
2722 return dc;
2725 static int WINAPI expGetDeviceCaps(int hdc, int unk)
2727 dbgprintf("GetDeviceCaps(0x%x, %d) => 0\n", hdc, unk);
2728 #ifdef CONFIG_QTX_CODECS
2729 #define BITSPIXEL 12
2730 #define PLANES 14
2731 if (unk == BITSPIXEL)
2732 return 24;
2733 if (unk == PLANES)
2734 return 1;
2735 #endif
2736 return 1;
2739 static WIN_BOOL WINAPI expDeleteDC(int hdc)
2741 dbgprintf("DeleteDC(0x%x) => 0\n", hdc);
2742 if (hdc == 0x81)
2743 return 1;
2744 return 0;
2747 static WIN_BOOL WINAPI expDeleteObject(int hdc)
2749 dbgprintf("DeleteObject(0x%x) => 1\n", hdc);
2750 /* FIXME - implement code here */
2751 return 1;
2754 /* btvvc32.drv wants this one */
2755 static void* WINAPI expGetWindowDC(int hdc)
2757 dbgprintf("GetWindowDC(%d) => 0x0\n", hdc);
2758 return 0;
2761 #ifdef CONFIG_QTX_CODECS
2762 static int WINAPI expGetWindowRect(HWND win, RECT *r)
2764 dbgprintf("GetWindowRect(0x%x, 0x%x) => 1\n", win, r);
2765 /* (win == 0) => desktop */
2766 r->right = PSEUDO_SCREEN_WIDTH;
2767 r->left = 0;
2768 r->bottom = PSEUDO_SCREEN_HEIGHT;
2769 r->top = 0;
2770 return 1;
2773 static int WINAPI expMonitorFromWindow(HWND win, int flags)
2775 dbgprintf("MonitorFromWindow(0x%x, 0x%x) => 0\n", win, flags);
2776 return 0;
2779 static int WINAPI expMonitorFromRect(RECT *r, int flags)
2781 dbgprintf("MonitorFromRect(0x%x, 0x%x) => 0\n", r, flags);
2782 return 0;
2785 static int WINAPI expMonitorFromPoint(void *p, int flags)
2787 dbgprintf("MonitorFromPoint(0x%x, 0x%x) => 0\n", p, flags);
2788 return 0;
2791 static int WINAPI expEnumDisplayMonitors(void *dc, RECT *r,
2792 int WINAPI (*callback_proc)(), void *callback_param)
2794 dbgprintf("EnumDisplayMonitors(0x%x, 0x%x, 0x%x, 0x%x) => ?\n",
2795 dc, r, callback_proc, callback_param);
2796 return callback_proc(0, dc, r, callback_param);
2799 #if 0
2800 typedef struct tagMONITORINFO {
2801 DWORD cbSize;
2802 RECT rcMonitor;
2803 RECT rcWork;
2804 DWORD dwFlags;
2805 } MONITORINFO, *LPMONITORINFO;
2806 #endif
2808 #define CCHDEVICENAME 8
2809 typedef struct tagMONITORINFOEX {
2810 DWORD cbSize;
2811 RECT rcMonitor;
2812 RECT rcWork;
2813 DWORD dwFlags;
2814 TCHAR szDevice[CCHDEVICENAME];
2815 } MONITORINFOEX, *LPMONITORINFOEX;
2817 static int WINAPI expGetMonitorInfoA(void *mon, LPMONITORINFO lpmi)
2819 dbgprintf("GetMonitorInfoA(0x%x, 0x%x) => 1\n", mon, lpmi);
2821 lpmi->rcMonitor.right = lpmi->rcWork.right = PSEUDO_SCREEN_WIDTH;
2822 lpmi->rcMonitor.left = lpmi->rcWork.left = 0;
2823 lpmi->rcMonitor.bottom = lpmi->rcWork.bottom = PSEUDO_SCREEN_HEIGHT;
2824 lpmi->rcMonitor.top = lpmi->rcWork.top = 0;
2826 lpmi->dwFlags = 1; /* primary monitor */
2828 if (lpmi->cbSize == sizeof(MONITORINFOEX))
2830 LPMONITORINFOEX lpmiex = (LPMONITORINFOEX)lpmi;
2831 dbgprintf("MONITORINFOEX!\n");
2832 strncpy(lpmiex->szDevice, "Monitor1", CCHDEVICENAME);
2835 return 1;
2838 static int WINAPI expEnumDisplayDevicesA(const char *device, int devnum,
2839 void *dispdev, int flags)
2841 dbgprintf("EnumDisplayDevicesA(0x%x = %s, %d, 0x%x, %x) => 1\n",
2842 device, device, devnum, dispdev, flags);
2843 return 1;
2846 static int WINAPI expIsWindowVisible(HWND win)
2848 dbgprintf("IsWindowVisible(0x%x) => 1\n", win);
2849 return 1;
2852 static HWND WINAPI expGetActiveWindow(void)
2854 dbgprintf("GetActiveWindow() => 0\n");
2855 return (HWND)0;
2858 static int WINAPI expGetClassNameA(HWND win, LPTSTR classname, int maxcount)
2860 strncat(classname, "QuickTime", maxcount);
2861 dbgprintf("GetClassNameA(0x%x, 0x%x, %d) => %d\n",
2862 win, classname, maxcount, strlen(classname));
2863 return strlen(classname);
2866 #define LPWNDCLASS void *
2867 static int WINAPI expGetClassInfoA(HINSTANCE inst, LPCSTR classname, LPWNDCLASS wndclass)
2869 dbgprintf("GetClassInfoA(0x%x, 0x%x = %s, 0x%x) => 1\n", inst,
2870 classname, classname, wndclass);
2871 return 1;
2874 static int WINAPI expGetWindowLongA(HWND win, int index)
2876 dbgprintf("GetWindowLongA(0x%x, %d) => 0\n", win, index);
2877 return 1;
2880 static int WINAPI expGetObjectA(HGDIOBJ hobj, int objsize, LPVOID obj)
2882 dbgprintf("GetObjectA(0x%x, %d, 0x%x) => %d\n", hobj, objsize, obj, objsize);
2883 return objsize;
2886 static int WINAPI expCreateRectRgn(int x, int y, int width, int height)
2888 dbgprintf("CreateRectRgn(%d, %d, %d, %d) => 0\n", x, y, width, height);
2889 return 0;
2892 static int WINAPI expEnumWindows(int (*callback_func)(), void *callback_param)
2894 int i, i2;
2895 dbgprintf("EnumWindows(0x%x, 0x%x) => 1\n", callback_func, callback_param);
2896 i = callback_func(0, callback_param);
2897 i2 = callback_func(1, callback_param);
2898 return i && i2;
2901 static int WINAPI expGetWindowThreadProcessId(HWND win, int *pid_data)
2903 int tid = pthread_self();
2904 dbgprintf("GetWindowThreadProcessId(0x%x, 0x%x) => %d\n",
2905 win, pid_data, tid);
2906 if (pid_data)
2907 *(int*)pid_data = tid;
2908 return tid;
2911 //HWND WINAPI CreateWindowExA(DWORD,LPCSTR,LPCSTR,DWORD,INT,INT,
2912 // INT,INT,HWND,HMENU,HINSTANCE,LPVOID);
2914 static HWND WINAPI expCreateWindowExA(int exstyle, const char *classname,
2915 const char *winname, int style, int x, int y, int w, int h,
2916 HWND parent, HMENU menu, HINSTANCE inst, LPVOID param)
2918 printf("CreateWindowEx() called\n");
2919 dbgprintf("CreateWindowEx(%d, 0x%x = %s, 0x%x = %s, %d, %d, %d, %d, %d, 0x%x, 0x%x, 0x%x, 0x%x) => 1\n",
2920 exstyle, classname, classname, winname, winname, style, x, y, w, h,
2921 parent, menu, inst, param);
2922 printf("CreateWindowEx() called okey\n");
2923 return 1;
2926 static int WINAPI expwaveOutGetNumDevs(void)
2928 dbgprintf("waveOutGetNumDevs() => 0\n");
2929 return 0;
2931 #endif
2934 * Returns the number of milliseconds, modulo 2^32, since the start
2935 * of the wineserver.
2937 static int WINAPI expGetTickCount(void)
2939 static int tcstart = 0;
2940 struct timeval t;
2941 int tc;
2942 gettimeofday( &t, NULL );
2943 tc = ((t.tv_sec * 1000) + (t.tv_usec / 1000)) - tcstart;
2944 if (tcstart == 0)
2946 tcstart = 0;
2947 tc = 0;
2949 dbgprintf("GetTickCount() => %d\n", tc);
2950 return tc;
2953 static int WINAPI expCreateFontA(void)
2955 dbgprintf("CreateFontA() => 0x0\n");
2956 return 1;
2959 /* tried to get pvmjpg work in a different way - no success */
2960 static int WINAPI expDrawTextA(int hDC, char* lpString, int nCount,
2961 LPRECT lpRect, unsigned int uFormat)
2963 dbgprintf("expDrawTextA(%p,...) => 8\n", hDC);
2964 return 8;
2967 static int WINAPI expGetPrivateProfileIntA(const char* appname,
2968 const char* keyname,
2969 int default_value,
2970 const char* filename)
2972 int size=255;
2973 char buffer[256];
2974 char* fullname;
2975 int result;
2977 buffer[255]=0;
2978 if(!(appname && keyname && filename) )
2980 dbgprintf("GetPrivateProfileIntA('%s', '%s', %d, '%s') => %d\n", appname, keyname, default_value, filename, default_value );
2981 return default_value;
2983 fullname=malloc(50+strlen(appname)+strlen(keyname)+strlen(filename));
2984 strcpy(fullname, "Software\\IniFileMapping\\");
2985 strcat(fullname, appname);
2986 strcat(fullname, "\\");
2987 strcat(fullname, keyname);
2988 strcat(fullname, "\\");
2989 strcat(fullname, filename);
2990 result=RegQueryValueExA(HKEY_LOCAL_MACHINE, fullname, NULL, NULL, (int*)buffer, &size);
2991 if((size>=0)&&(size<256))
2992 buffer[size]=0;
2993 // printf("GetPrivateProfileIntA(%s, %s, %s) -> %s\n", appname, keyname, filename, buffer);
2994 free(fullname);
2995 if(result)
2996 result=default_value;
2997 else
2998 result=atoi(buffer);
2999 dbgprintf("GetPrivateProfileIntA('%s', '%s', %d, '%s') => %d\n", appname, keyname, default_value, filename, result);
3000 return result;
3002 static int WINAPI expGetProfileIntA(const char* appname,
3003 const char* keyname,
3004 int default_value)
3006 dbgprintf("GetProfileIntA -> ");
3007 return expGetPrivateProfileIntA(appname, keyname, default_value, "default");
3010 static int WINAPI expGetPrivateProfileStringA(const char* appname,
3011 const char* keyname,
3012 const char* def_val,
3013 char* dest, unsigned int len,
3014 const char* filename)
3016 int result;
3017 int size;
3018 char* fullname;
3019 dbgprintf("GetPrivateProfileStringA('%s', '%s', def_val '%s', 0x%x, 0x%x, '%s')", appname, keyname, def_val, dest, len, filename );
3020 if(!(appname && keyname && filename) ) return 0;
3021 fullname=malloc(50+strlen(appname)+strlen(keyname)+strlen(filename));
3022 strcpy(fullname, "Software\\IniFileMapping\\");
3023 strcat(fullname, appname);
3024 strcat(fullname, "\\");
3025 strcat(fullname, keyname);
3026 strcat(fullname, "\\");
3027 strcat(fullname, filename);
3028 size=len;
3029 result=RegQueryValueExA(HKEY_LOCAL_MACHINE, fullname, NULL, NULL, (int*)dest, &size);
3030 free(fullname);
3031 if(result)
3033 strncpy(dest, def_val, size);
3034 if (strlen(def_val)< size) size = strlen(def_val);
3036 dbgprintf(" => %d ( '%s' )\n", size, dest);
3037 return size;
3039 static int WINAPI expWritePrivateProfileStringA(const char* appname,
3040 const char* keyname,
3041 const char* string,
3042 const char* filename)
3044 char* fullname;
3045 dbgprintf("WritePrivateProfileStringA('%s', '%s', '%s', '%s')", appname, keyname, string, filename );
3046 if(!(appname && keyname && filename) )
3048 dbgprintf(" => -1\n");
3049 return -1;
3051 fullname=malloc(50+strlen(appname)+strlen(keyname)+strlen(filename));
3052 strcpy(fullname, "Software\\IniFileMapping\\");
3053 strcat(fullname, appname);
3054 strcat(fullname, "\\");
3055 strcat(fullname, keyname);
3056 strcat(fullname, "\\");
3057 strcat(fullname, filename);
3058 RegSetValueExA(HKEY_LOCAL_MACHINE, fullname, 0, REG_SZ, (int*)string, strlen(string));
3059 // printf("RegSetValueExA(%s,%d)\n", string, strlen(string));
3060 // printf("WritePrivateProfileStringA(%s, %s, %s, %s)\n", appname, keyname, string, filename );
3061 free(fullname);
3062 dbgprintf(" => 0\n");
3063 return 0;
3066 unsigned int GetPrivateProfileIntA_(const char* appname, const char* keyname, INT default_value, const char* filename)
3068 return expGetPrivateProfileIntA(appname, keyname, default_value, filename);
3070 int GetPrivateProfileStringA_(const char* appname, const char* keyname,
3071 const char* def_val, char* dest, unsigned int len, const char* filename)
3073 return expGetPrivateProfileStringA(appname, keyname, def_val, dest, len, filename);
3075 int WritePrivateProfileStringA_(const char* appname, const char* keyname,
3076 const char* string, const char* filename)
3078 return expWritePrivateProfileStringA(appname, keyname, string, filename);
3083 static int WINAPI expDefDriverProc(int private, int id, int msg, int arg1, int arg2)
3085 dbgprintf("DefDriverProc(0x%x, 0x%x, 0x%x, 0x%x, 0x%x) => 0\n", private, id, msg, arg1, arg2);
3086 return 0;
3089 static int WINAPI expSizeofResource(int v1, int v2)
3091 int result=SizeofResource(v1, v2);
3092 dbgprintf("SizeofResource(0x%x, 0x%x) => %d\n", v1, v2, result);
3093 return result;
3096 static int WINAPI expGetLastError(void)
3098 int result=GetLastError();
3099 dbgprintf("GetLastError() => 0x%x\n", result);
3100 return result;
3103 static void WINAPI expSetLastError(int error)
3105 dbgprintf("SetLastError(0x%x)\n", error);
3106 SetLastError(error);
3109 static int WINAPI expStringFromGUID2(GUID* guid, char* str, int cbMax)
3111 int result=snprintf(str, cbMax, "%.8x-%.4x-%.4x-%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x",
3112 guid->f1, guid->f2, guid->f3,
3113 (unsigned char)guid->f4[0], (unsigned char)guid->f4[1],
3114 (unsigned char)guid->f4[2], (unsigned char)guid->f4[3],
3115 (unsigned char)guid->f4[4], (unsigned char)guid->f4[5],
3116 (unsigned char)guid->f4[6], (unsigned char)guid->f4[7]);
3117 dbgprintf("StringFromGUID2(0x%x, 0x%x='%s', %d) => %d\n", guid, str, str, cbMax, result);
3118 return result;
3122 static int WINAPI expGetFileVersionInfoSizeA(const char* name, int* lpHandle)
3124 dbgprintf("GetFileVersionInfoSizeA(0x%x='%s', 0x%X) => 0\n", name, name, lpHandle);
3125 return 0;
3128 static int WINAPI expIsBadStringPtrW(const short* string, int nchars)
3130 int result;
3131 if(string==0)result=1; else result=0;
3132 dbgprintf("IsBadStringPtrW(0x%x, %d) => %d", string, nchars, result);
3133 if(string)wch_print(string);
3134 return result;
3136 static int WINAPI expIsBadStringPtrA(const char* string, int nchars)
3138 return expIsBadStringPtrW((const short*)string, nchars);
3140 static long WINAPI expInterlockedExchangeAdd( long* dest, long incr )
3142 long ret;
3143 __asm__ volatile
3145 "lock; xaddl %0,(%1)"
3146 : "=r" (ret)
3147 : "r" (dest), "0" (incr)
3148 : "memory"
3150 return ret;
3153 static long WINAPI expInterlockedCompareExchange( unsigned long* dest, unsigned long exchange, unsigned long comperand)
3155 unsigned long retval = *dest;
3156 if(*dest == comperand)
3157 *dest = exchange;
3158 return retval;
3161 static long WINAPI expInterlockedIncrement( long* dest )
3163 long result=expInterlockedExchangeAdd( dest, 1 ) + 1;
3164 dbgprintf("InterlockedIncrement(0x%x => %d) => %d\n", dest, *dest, result);
3165 return result;
3167 static long WINAPI expInterlockedDecrement( long* dest )
3169 long result=expInterlockedExchangeAdd( dest, -1 ) - 1;
3170 dbgprintf("InterlockedDecrement(0x%x => %d) => %d\n", dest, *dest, result);
3171 return result;
3174 static void WINAPI expOutputDebugStringA( const char* string )
3176 dbgprintf("OutputDebugStringA(0x%x='%s')\n", string);
3177 fprintf(stderr, "DEBUG: %s\n", string);
3180 static int WINAPI expGetDC(int hwnd)
3182 dbgprintf("GetDC(0x%x) => 1\n", hwnd);
3183 return 1;
3186 static int WINAPI expReleaseDC(int hwnd, int hdc)
3188 dbgprintf("ReleaseDC(0x%x, 0x%x) => 1\n", hwnd, hdc);
3189 return 1;
3192 static int WINAPI expGetDesktopWindow(void)
3194 dbgprintf("GetDesktopWindow() => 0\n");
3195 return 0;
3198 static int cursor[100];
3200 static int WINAPI expLoadCursorA(int handle,LPCSTR name)
3202 dbgprintf("LoadCursorA(%d, 0x%x='%s') => 0x%x\n", handle, name, (int)&cursor[0]);
3203 return (int)&cursor[0];
3205 static int WINAPI expSetCursor(void *cursor)
3207 dbgprintf("SetCursor(0x%x) => 0x%x\n", cursor, cursor);
3208 return (int)cursor;
3210 static int WINAPI expGetCursorPos(void *cursor)
3212 dbgprintf("GetCursorPos(0x%x) => 0x%x\n", cursor, cursor);
3213 return 1;
3215 #ifdef CONFIG_QTX_CODECS
3216 static int show_cursor = 0;
3217 static int WINAPI expShowCursor(int show)
3219 dbgprintf("ShowCursor(%d) => %d\n", show, show);
3220 if (show)
3221 show_cursor++;
3222 else
3223 show_cursor--;
3224 return show_cursor;
3226 #endif
3227 static int WINAPI expRegisterWindowMessageA(char *message)
3229 dbgprintf("RegisterWindowMessageA(%s)\n", message);
3230 return 1;
3232 static int WINAPI expGetProcessVersion(int pid)
3234 dbgprintf("GetProcessVersion(%d)\n", pid);
3235 return 1;
3237 static int WINAPI expGetCurrentThread(void)
3239 #warning FIXME!
3240 dbgprintf("GetCurrentThread() => %x\n", 0xcfcf9898);
3241 return 0xcfcf9898;
3243 static int WINAPI expGetOEMCP(void)
3245 dbgprintf("GetOEMCP()\n");
3246 return 1;
3248 static int WINAPI expGetCPInfo(int cp,void *info)
3250 dbgprintf("GetCPInfo()\n");
3251 return 0;
3253 #ifdef CONFIG_QTX_CODECS
3254 #define SM_CXSCREEN 0
3255 #define SM_CYSCREEN 1
3256 #define SM_XVIRTUALSCREEN 76
3257 #define SM_YVIRTUALSCREEN 77
3258 #define SM_CXVIRTUALSCREEN 78
3259 #define SM_CYVIRTUALSCREEN 79
3260 #define SM_CMONITORS 80
3261 #endif
3262 static int WINAPI expGetSystemMetrics(int index)
3264 dbgprintf("GetSystemMetrics(%d)\n", index);
3265 #ifdef CONFIG_QTX_CODECS
3266 switch(index)
3268 case SM_XVIRTUALSCREEN:
3269 case SM_YVIRTUALSCREEN:
3270 return 0;
3271 case SM_CXSCREEN:
3272 case SM_CXVIRTUALSCREEN:
3273 return PSEUDO_SCREEN_WIDTH;
3274 case SM_CYSCREEN:
3275 case SM_CYVIRTUALSCREEN:
3276 return PSEUDO_SCREEN_HEIGHT;
3277 case SM_CMONITORS:
3278 return 1;
3280 #endif
3281 return 1;
3283 static int WINAPI expGetSysColor(int index)
3285 dbgprintf("GetSysColor(%d) => 1\n", index);
3286 return 1;
3288 static int WINAPI expGetSysColorBrush(int index)
3290 dbgprintf("GetSysColorBrush(%d)\n", index);
3291 return 1;
3296 static int WINAPI expGetSystemPaletteEntries(int hdc, int iStartIndex, int nEntries, void* lppe)
3298 dbgprintf("GetSystemPaletteEntries(0x%x, 0x%x, 0x%x, 0x%x) => 0\n",
3299 hdc, iStartIndex, nEntries, lppe);
3300 return 0;
3304 typedef struct TIME_ZONE_INFORMATION {
3305 long Bias;
3306 char StandardName[32];
3307 SYSTEMTIME StandardDate;
3308 long StandardBias;
3309 char DaylightName[32];
3310 SYSTEMTIME DaylightDate;
3311 long DaylightBias;
3312 } TIME_ZONE_INFORMATION, *LPTIME_ZONE_INFORMATION;
3315 static int WINAPI expGetTimeZoneInformation(LPTIME_ZONE_INFORMATION lpTimeZoneInformation)
3317 const short name[]={'C', 'e', 'n', 't', 'r', 'a', 'l', ' ', 'S', 't', 'a',
3318 'n', 'd', 'a', 'r', 'd', ' ', 'T', 'i', 'm', 'e', 0};
3319 const short pname[]={'C', 'e', 'n', 't', 'r', 'a', 'l', ' ', 'D', 'a', 'y',
3320 'l', 'i', 'g', 'h', 't', ' ', 'T', 'i', 'm', 'e', 0};
3321 dbgprintf("GetTimeZoneInformation(0x%x) => TIME_ZONE_ID_STANDARD\n");
3322 memset(lpTimeZoneInformation, 0, sizeof(TIME_ZONE_INFORMATION));
3323 lpTimeZoneInformation->Bias=360;//GMT-6
3324 memcpy(lpTimeZoneInformation->StandardName, name, sizeof(name));
3325 lpTimeZoneInformation->StandardDate.wMonth=10;
3326 lpTimeZoneInformation->StandardDate.wDay=5;
3327 lpTimeZoneInformation->StandardDate.wHour=2;
3328 lpTimeZoneInformation->StandardBias=0;
3329 memcpy(lpTimeZoneInformation->DaylightName, pname, sizeof(pname));
3330 lpTimeZoneInformation->DaylightDate.wMonth=4;
3331 lpTimeZoneInformation->DaylightDate.wDay=1;
3332 lpTimeZoneInformation->DaylightDate.wHour=2;
3333 lpTimeZoneInformation->DaylightBias=-60;
3334 return TIME_ZONE_ID_STANDARD;
3337 static void WINAPI expGetLocalTime(SYSTEMTIME* systime)
3339 time_t local_time;
3340 struct tm *local_tm;
3341 struct timeval tv;
3343 dbgprintf("GetLocalTime(0x%x)\n");
3344 gettimeofday(&tv, NULL);
3345 local_time=tv.tv_sec;
3346 local_tm=localtime(&local_time);
3348 systime->wYear = local_tm->tm_year + 1900;
3349 systime->wMonth = local_tm->tm_mon + 1;
3350 systime->wDayOfWeek = local_tm->tm_wday;
3351 systime->wDay = local_tm->tm_mday;
3352 systime->wHour = local_tm->tm_hour;
3353 systime->wMinute = local_tm->tm_min;
3354 systime->wSecond = local_tm->tm_sec;
3355 systime->wMilliseconds = (tv.tv_usec / 1000) % 1000;
3356 dbgprintf(" Year: %d\n Month: %d\n Day of week: %d\n"
3357 " Day: %d\n Hour: %d\n Minute: %d\n Second: %d\n"
3358 " Milliseconds: %d\n",
3359 systime->wYear, systime->wMonth, systime->wDayOfWeek, systime->wDay,
3360 systime->wHour, systime->wMinute, systime->wSecond, systime->wMilliseconds);
3363 static int WINAPI expGetSystemTime(SYSTEMTIME* systime)
3365 time_t local_time;
3366 struct tm *local_tm;
3367 struct timeval tv;
3369 dbgprintf("GetSystemTime(0x%x)\n", systime);
3370 gettimeofday(&tv, NULL);
3371 local_time=tv.tv_sec;
3372 local_tm=gmtime(&local_time);
3374 systime->wYear = local_tm->tm_year + 1900;
3375 systime->wMonth = local_tm->tm_mon + 1;
3376 systime->wDayOfWeek = local_tm->tm_wday;
3377 systime->wDay = local_tm->tm_mday;
3378 systime->wHour = local_tm->tm_hour;
3379 systime->wMinute = local_tm->tm_min;
3380 systime->wSecond = local_tm->tm_sec;
3381 systime->wMilliseconds = (tv.tv_usec / 1000) % 1000;
3382 dbgprintf(" Year: %d\n Month: %d\n Day of week: %d\n"
3383 " Day: %d\n Hour: %d\n Minute: %d\n Second: %d\n"
3384 " Milliseconds: %d\n",
3385 systime->wYear, systime->wMonth, systime->wDayOfWeek, systime->wDay,
3386 systime->wHour, systime->wMinute, systime->wSecond, systime->wMilliseconds);
3387 return 0;
3390 #define SECS_1601_TO_1970 ((369 * 365 + 89) * 86400ULL)
3391 static void WINAPI expGetSystemTimeAsFileTime(FILETIME* systime)
3393 struct timeval tv;
3394 unsigned long long secs;
3396 dbgprintf("GetSystemTime(0x%x)\n", systime);
3397 gettimeofday(&tv, NULL);
3398 secs = (tv.tv_sec + SECS_1601_TO_1970) * 10000000;
3399 secs += tv.tv_usec * 10;
3400 systime->dwLowDateTime = secs & 0xffffffff;
3401 systime->dwHighDateTime = (secs >> 32);
3404 static int WINAPI expGetEnvironmentVariableA(const char* name, char* field, int size)
3406 //char *p;
3407 // printf("%s %x %x\n", name, field, size);
3408 if(field)field[0]=0;
3410 p = getenv(name);
3411 if (p) strncpy(field,p,size);
3413 if (strcmp(name,"__MSVCRT_HEAP_SELECT")==0)
3414 strcpy(field,"__GLOBAL_HEAP_SELECTED,1");
3415 dbgprintf("GetEnvironmentVariableA(0x%x='%s', 0x%x, %d) => %d\n", name, name, field, size, strlen(field));
3416 return strlen(field);
3419 static int WINAPI expSetEnvironmentVariableA(const char *name, const char *value)
3421 dbgprintf("SetEnvironmentVariableA(%s, %s)\n", name, value);
3422 return 0;
3425 static void* WINAPI expCoTaskMemAlloc(ULONG cb)
3427 return my_mreq(cb, 0);
3429 static void WINAPI expCoTaskMemFree(void* cb)
3431 my_release(cb);
3437 void* CoTaskMemAlloc(unsigned long cb)
3439 return expCoTaskMemAlloc(cb);
3441 void CoTaskMemFree(void* cb)
3443 expCoTaskMemFree(cb);
3446 struct COM_OBJECT_INFO
3448 GUID clsid;
3449 long (*GetClassObject) (GUID* clsid, const GUID* iid, void** ppv);
3452 static struct COM_OBJECT_INFO* com_object_table=0;
3453 static int com_object_size=0;
3454 int RegisterComClass(const GUID* clsid, GETCLASSOBJECT gcs)
3456 if(!clsid || !gcs)
3457 return -1;
3458 com_object_table=realloc(com_object_table, sizeof(struct COM_OBJECT_INFO)*(++com_object_size));
3459 com_object_table[com_object_size-1].clsid=*clsid;
3460 com_object_table[com_object_size-1].GetClassObject=gcs;
3461 return 0;
3464 int UnregisterComClass(const GUID* clsid, GETCLASSOBJECT gcs)
3466 int found = 0;
3467 int i = 0;
3468 if(!clsid || !gcs)
3469 return -1;
3471 if (com_object_table == 0)
3472 printf("Warning: UnregisterComClass() called without any registered class\n");
3473 while (i < com_object_size)
3475 if (found && i > 0)
3477 memcpy(&com_object_table[i - 1].clsid,
3478 &com_object_table[i].clsid, sizeof(GUID));
3479 com_object_table[i - 1].GetClassObject =
3480 com_object_table[i].GetClassObject;
3482 else if (memcmp(&com_object_table[i].clsid, clsid, sizeof(GUID)) == 0
3483 && com_object_table[i].GetClassObject == gcs)
3485 found++;
3487 i++;
3489 if (found)
3491 if (--com_object_size == 0)
3493 free(com_object_table);
3494 com_object_table = 0;
3497 return 0;
3501 const GUID IID_IUnknown =
3503 0x00000000, 0x0000, 0x0000,
3504 {0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}
3506 const GUID IID_IClassFactory =
3508 0x00000001, 0x0000, 0x0000,
3509 {0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}
3512 static long WINAPI expCoCreateInstance(GUID* rclsid, struct IUnknown* pUnkOuter,
3513 long dwClsContext, const GUID* riid, void** ppv)
3515 int i;
3516 struct COM_OBJECT_INFO* ci=0;
3517 for(i=0; i<com_object_size; i++)
3518 if(!memcmp(rclsid, &com_object_table[i].clsid, sizeof(GUID)))
3519 ci=&com_object_table[i];
3520 if(!ci)return REGDB_E_CLASSNOTREG;
3521 // in 'real' world we should mess with IClassFactory here
3522 i=ci->GetClassObject(rclsid, riid, ppv);
3523 return i;
3526 long CoCreateInstance(GUID* rclsid, struct IUnknown* pUnkOuter,
3527 long dwClsContext, const GUID* riid, void** ppv)
3529 return expCoCreateInstance(rclsid, pUnkOuter, dwClsContext, riid, ppv);
3532 static int WINAPI expIsRectEmpty(CONST RECT *lprc)
3534 int r = 0;
3535 int w,h;
3536 //trapbug();
3537 if (lprc)
3539 w = lprc->right - lprc->left;
3540 h = lprc->bottom - lprc->top;
3541 if (w <= 0 || h <= 0)
3542 r = 1;
3544 else
3545 r = 1;
3547 dbgprintf("IsRectEmpty(%p) => %s\n", lprc, (r) ? "TRUE" : "FALSE");
3548 //printf("Rect: left: %d, top: %d, right: %d, bottom: %d\n", lprc->left, lprc->top, lprc->right, lprc->bottom);
3549 // return 0; // wmv9?
3550 return r; // TM20
3553 static int _adjust_fdiv=0; //what's this? - used to adjust division
3554 static int _winver = 0x510; // windows version
3559 static unsigned int WINAPI expGetTempPathA(unsigned int len, char* path)
3561 dbgprintf("GetTempPathA(%d, 0x%x)", len, path);
3562 if(len<5)
3564 dbgprintf(" => 0\n");
3565 return 0;
3567 strcpy(path, "/tmp");
3568 dbgprintf(" => 5 ( '/tmp' )\n");
3569 return 5;
3572 FYI:
3573 typedef struct
3575 DWORD dwFileAttributes;
3576 FILETIME ftCreationTime;
3577 FILETIME ftLastAccessTime;
3578 FILETIME ftLastWriteTime;
3579 DWORD nFileSizeHigh;
3580 DWORD nFileSizeLow;
3581 DWORD dwReserved0;
3582 DWORD dwReserved1;
3583 CHAR cFileName[260];
3584 CHAR cAlternateFileName[14];
3585 } WIN32_FIND_DATAA, *LPWIN32_FIND_DATAA;
3588 static DIR* qtx_dir=NULL;
3590 static WIN_BOOL WINAPI expFindNextFileA(HANDLE h,LPWIN32_FIND_DATAA lpfd)
3592 #ifdef CONFIG_QTX_CODECS
3593 dbgprintf("FindNextFileA(0x%x, 0x%x) => 0\n", h, lpfd);
3594 if(h==FILE_HANDLE_quicktimeqtx){
3595 struct dirent* d;
3596 if(!qtx_dir) return 0;
3597 while((d=readdir(qtx_dir))){
3598 char* x=strrchr(d->d_name,'.');
3599 if(!x) continue;
3600 if(strcmp(x,".qtx")) continue;
3601 strcpy(lpfd->cFileName,d->d_name);
3602 // sprintf(lpfd->cAlternateFileName,"%-8s.qtx",d->d_name);
3603 strcpy(lpfd->cAlternateFileName,"foobar.qtx");
3604 dbgprintf("### FindNext: %s\n",lpfd->cFileName);
3605 return 1;
3607 closedir(qtx_dir); qtx_dir=NULL;
3608 return 0;
3610 #endif
3611 return 0;
3614 static HANDLE WINAPI expFindFirstFileA(LPCSTR s, LPWIN32_FIND_DATAA lpfd)
3616 dbgprintf("FindFirstFileA(0x%x='%s', 0x%x) => 0\n", s, s, lpfd);
3617 // printf("\n### FindFirstFileA('%s')...\n",s);
3618 #ifdef CONFIG_QTX_CODECS
3619 if(strstr(s, "quicktime\\*.QTX")){
3620 dbgprintf("FindFirstFileA(0x%x='%s', 0x%x) => QTX\n", s, s, lpfd);
3621 dbgprintf("\n### Searching for QuickTime plugins (*.qtx) at %s...\n",def_path);
3622 qtx_dir=opendir(def_path);
3623 if(!qtx_dir) return (HANDLE)-1;
3624 memset(lpfd,0,sizeof(*lpfd));
3625 if(expFindNextFileA(FILE_HANDLE_quicktimeqtx,lpfd))
3626 return FILE_HANDLE_quicktimeqtx;
3627 printf("loader: Couldn't find the QuickTime plugins (.qtx files) at %s\n",def_path);
3628 return (HANDLE)-1;
3630 #if 0
3631 if(strstr(s, "QuickTime.qts")){
3632 dbgprintf("FindFirstFileA(0x%x='%s', 0x%x) => QTS\n", s, s, lpfd);
3633 // if(!strcmp(s,"C:\\windows\\QuickTime.qts\\QuickTime.qts\\*.QTX"))
3634 // return (HANDLE)-1;
3635 strcpy(lpfd->cFileName, "QuickTime.qts");
3636 strcpy(lpfd->cAlternateFileName, "QuickT~1.qts");
3637 return FILE_HANDLE_quicktimeqts;
3639 #endif
3640 #endif
3641 if(strstr(s, "*.vwp")){
3642 // hack for VoxWare codec plugins:
3643 strcpy(lpfd->cFileName, "msms001.vwp");
3644 strcpy(lpfd->cAlternateFileName, "msms001.vwp");
3645 return (HANDLE)0;
3647 // return 'file not found'
3648 return (HANDLE)-1;
3651 static WIN_BOOL WINAPI expFindClose(HANDLE h)
3653 dbgprintf("FindClose(0x%x) => 0\n", h);
3654 #ifdef CONFIG_QTX_CODECS
3655 // if(h==FILE_HANDLE_quicktimeqtx && qtx_dir){
3656 // closedir(qtx_dir);
3657 // qtx_dir=NULL;
3658 // }
3659 #endif
3660 return 0;
3662 static UINT WINAPI expSetErrorMode(UINT i)
3664 dbgprintf("SetErrorMode(%d) => 0\n", i);
3665 return 0;
3667 static UINT WINAPI expGetWindowsDirectoryA(LPSTR s,UINT c)
3669 char windir[]="c:\\windows";
3670 int result;
3671 strncpy(s, windir, c);
3672 result=1+((c<strlen(windir))?c:strlen(windir));
3673 dbgprintf("GetWindowsDirectoryA(0x%x, %d) => %d\n", s, c, result);
3674 return result;
3676 #ifdef CONFIG_QTX_CODECS
3677 static UINT WINAPI expGetCurrentDirectoryA(UINT c, LPSTR s)
3679 char curdir[]="c:\\";
3680 int result;
3681 strncpy(s, curdir, c);
3682 result=1+((c<strlen(curdir))?c:strlen(curdir));
3683 dbgprintf("GetCurrentDirectoryA(0x%x, %d) => %d\n", s, c, result);
3684 return result;
3687 static int WINAPI expSetCurrentDirectoryA(const char *pathname)
3689 dbgprintf("SetCurrentDirectoryA(0x%x = %s) => 1\n", pathname, pathname);
3690 #if 0
3691 if (strrchr(pathname, '\\'))
3692 chdir(strcat(strrchr(pathname, '\\')+1, '/'));
3693 else
3694 chdir(pathname);
3695 #endif
3696 return 1;
3699 static int WINAPI expCreateDirectoryA(const char *pathname, void *sa)
3701 dbgprintf("CreateDirectory(0x%x = %s, 0x%x) => 1\n",
3702 pathname, pathname, sa);
3703 #if 0
3704 p = strrchr(pathname, '\\')+1;
3705 strcpy(&buf[0], p); /* should be strncpy */
3706 if (!strlen(p))
3708 buf[0] = '.';
3709 buf[1] = 0;
3711 #if 0
3712 if (strrchr(pathname, '\\'))
3713 mkdir(strcat(strrchr(pathname, '\\')+1, '/'), 666);
3714 else
3715 mkdir(pathname, 666);
3716 #endif
3717 mkdir(&buf);
3718 #endif
3719 return 1;
3721 #endif
3722 static WIN_BOOL WINAPI expDeleteFileA(LPCSTR s)
3724 dbgprintf("DeleteFileA(0x%x='%s') => 0\n", s, s);
3725 return 0;
3727 static WIN_BOOL WINAPI expFileTimeToLocalFileTime(const FILETIME* cpf, LPFILETIME pf)
3729 dbgprintf("FileTimeToLocalFileTime(0x%x, 0x%x) => 0\n", cpf, pf);
3730 return 0;
3733 static UINT WINAPI expGetTempFileNameA(LPCSTR cs1,LPCSTR cs2,UINT i,LPSTR ps)
3735 char mask[16]="/tmp/AP_XXXXXX";
3736 int result;
3737 dbgprintf("GetTempFileNameA(0x%x='%s', 0x%x='%s', %d, 0x%x)", cs1, cs1, cs2, cs2, i, ps);
3738 if(i && i<10)
3740 dbgprintf(" => -1\n");
3741 return -1;
3743 result=mkstemp(mask);
3744 sprintf(ps, "AP%d", result);
3745 dbgprintf(" => %d\n", strlen(ps));
3746 return strlen(ps);
3749 // This func might need proper implementation if we want AngelPotion codec.
3750 // They try to open APmpeg4v1.apl with it.
3751 // DLL will close opened file with CloseHandle().
3753 static HANDLE WINAPI expCreateFileA(LPCSTR cs1,DWORD i1,DWORD i2,
3754 LPSECURITY_ATTRIBUTES p1, DWORD i3,DWORD i4,HANDLE i5)
3756 dbgprintf("CreateFileA(0x%x='%s', %d, %d, 0x%x, %d, %d, 0x%x)\n", cs1, cs1, i1,
3757 i2, p1, i3, i4, i5);
3758 if((!cs1) || (strlen(cs1)<2))return -1;
3760 #ifdef CONFIG_QTX_CODECS
3761 if(strstr(cs1, "QuickTime.qts"))
3763 int result;
3764 char* tmp=malloc(strlen(def_path)+50);
3765 strcpy(tmp, def_path);
3766 strcat(tmp, "/");
3767 strcat(tmp, "QuickTime.qts");
3768 result=open(tmp, O_RDONLY);
3769 free(tmp);
3770 return result;
3772 if(strstr(cs1, ".qtx"))
3774 int result;
3775 char* tmp=malloc(strlen(def_path)+250);
3776 char* x=strrchr(cs1,'\\');
3777 sprintf(tmp,"%s/%s",def_path,x?(x+1):cs1);
3778 // printf("### Open: %s -> %s\n",cs1,tmp);
3779 result=open(tmp, O_RDONLY);
3780 free(tmp);
3781 return result;
3783 #endif
3785 if(strncmp(cs1, "AP", 2) == 0)
3787 int result;
3788 char* tmp=malloc(strlen(def_path)+50);
3789 strcpy(tmp, def_path);
3790 strcat(tmp, "/");
3791 strcat(tmp, "APmpg4v1.apl");
3792 result=open(tmp, O_RDONLY);
3793 free(tmp);
3794 return result;
3796 if (strstr(cs1, "vp3") || strstr(cs1, ".fpf"))
3798 int r;
3799 int flg = 0;
3800 char* tmp=malloc(20 + strlen(cs1));
3801 strcpy(tmp, "/tmp/");
3802 strcat(tmp, cs1);
3803 r = 4;
3804 while (tmp[r])
3806 if (tmp[r] == ':' || tmp[r] == '\\')
3807 tmp[r] = '_';
3808 r++;
3810 if (GENERIC_READ & i1)
3811 flg |= O_RDONLY;
3812 else if (GENERIC_WRITE & i1)
3814 flg |= O_WRONLY | O_CREAT;
3815 printf("Warning: openning filename %s %d (flags; 0x%x) for write\n", tmp, r, flg);
3817 r=open(tmp, flg, S_IRWXU);
3818 free(tmp);
3819 return r;
3822 // Needed by wnvplay1.dll
3823 if (strstr(cs1, "WINNOV.bmp"))
3825 int r;
3826 r=open("/dev/null", O_RDONLY);
3827 return r;
3830 #if 0
3831 /* we need this for some virtualdub filters */
3833 int r;
3834 int flg = 0;
3835 if (GENERIC_READ & i1)
3836 flg |= O_RDONLY;
3837 else if (GENERIC_WRITE & i1)
3839 flg |= O_WRONLY;
3840 printf("Warning: openning filename %s %d (flags; 0x%x) for write\n", cs1, r, flg);
3842 r=open(cs1, flg);
3843 return r;
3845 #endif
3847 return atoi(cs1+2);
3849 static UINT WINAPI expGetSystemDirectoryA(
3850 char* lpBuffer, // address of buffer for system directory
3851 UINT uSize // size of directory buffer
3853 dbgprintf("GetSystemDirectoryA(%p,%d)\n", lpBuffer,uSize);
3854 if(!lpBuffer) strcpy(lpBuffer,".");
3855 return 1;
3858 static char sysdir[]=".";
3859 static LPCSTR WINAPI expGetSystemDirectoryA(void)
3861 dbgprintf("GetSystemDirectoryA() => 0x%x='%s'\n", sysdir, sysdir);
3862 return sysdir;
3865 static DWORD WINAPI expGetFullPathNameA
3867 LPCTSTR lpFileName,
3868 DWORD nBufferLength,
3869 LPTSTR lpBuffer,
3870 LPTSTR lpFilePart
3872 if(!lpFileName) return 0;
3873 dbgprintf("GetFullPathNameA('%s',%d,%p,%p)\n",lpFileName,nBufferLength,
3874 lpBuffer, lpFilePart);
3875 #if 0
3876 #ifdef CONFIG_QTX_CODECS
3877 strcpy(lpFilePart, "Quick123.qts");
3878 #else
3879 strcpy(lpFilePart, lpFileName);
3880 #endif
3881 #else
3882 if (strrchr(lpFileName, '\\'))
3883 lpFilePart = strrchr(lpFileName, '\\');
3884 else
3885 lpFilePart = (LPTSTR)lpFileName;
3886 #endif
3887 strcpy(lpBuffer, lpFileName);
3888 // strncpy(lpBuffer, lpFileName, rindex(lpFileName, '\\')-lpFileName);
3889 return strlen(lpBuffer);
3892 static DWORD WINAPI expGetShortPathNameA
3894 LPCSTR longpath,
3895 LPSTR shortpath,
3896 DWORD shortlen
3898 if(!longpath) return 0;
3899 dbgprintf("GetShortPathNameA('%s',%p,%d)\n",longpath,shortpath,shortlen);
3900 strcpy(shortpath,longpath);
3901 return strlen(shortpath);
3904 static WIN_BOOL WINAPI expReadFile(HANDLE h,LPVOID pv,DWORD size,LPDWORD rd,LPOVERLAPPED unused)
3906 int result;
3907 dbgprintf("ReadFile(%d, 0x%x, %d -> 0x%x)\n", h, pv, size, rd);
3908 result=read(h, pv, size);
3909 if(rd)*rd=result;
3910 if(!result)return 0;
3911 return 1;
3914 static WIN_BOOL WINAPI expWriteFile(HANDLE h,LPCVOID pv,DWORD size,LPDWORD wr,LPOVERLAPPED unused)
3916 int result;
3917 dbgprintf("WriteFile(%d, 0x%x, %d -> 0x%x)\n", h, pv, size, wr);
3918 if(h==1234)h=1;
3919 result=write(h, pv, size);
3920 if(wr)*wr=result;
3921 if(!result)return 0;
3922 return 1;
3924 static DWORD WINAPI expSetFilePointer(HANDLE h, LONG val, LPLONG ext, DWORD whence)
3926 int wh;
3927 dbgprintf("SetFilePointer(%d, 0x%x, 0x%x = %d, %d)\n", h, val, ext, ext ? *ext : NULL, whence);
3928 //why would DLL want temporary file with >2Gb size?
3929 switch(whence)
3931 case FILE_BEGIN:
3932 wh=SEEK_SET;break;
3933 case FILE_END:
3934 wh=SEEK_END;break;
3935 case FILE_CURRENT:
3936 wh=SEEK_CUR;break;
3937 default:
3938 return -1;
3940 #ifdef CONFIG_QTX_CODECS
3941 if (val == 0 && ext != 0)
3942 val = val&(*ext);
3943 #endif
3944 return lseek(h, val, wh);
3947 static HDRVR WINAPI expOpenDriverA(LPCSTR szDriverName, LPCSTR szSectionName,
3948 LPARAM lParam2)
3950 dbgprintf("OpenDriverA(0x%x='%s', 0x%x='%s', 0x%x) => -1\n", szDriverName, szDriverName, szSectionName, szSectionName, lParam2);
3951 return -1;
3953 static HDRVR WINAPI expOpenDriver(LPCSTR szDriverName, LPCSTR szSectionName,
3954 LPARAM lParam2)
3956 dbgprintf("OpenDriver(0x%x='%s', 0x%x='%s', 0x%x) => -1\n", szDriverName, szDriverName, szSectionName, szSectionName, lParam2);
3957 return -1;
3961 static WIN_BOOL WINAPI expGetProcessAffinityMask(HANDLE hProcess,
3962 LPDWORD lpProcessAffinityMask,
3963 LPDWORD lpSystemAffinityMask)
3965 dbgprintf("GetProcessAffinityMask(0x%x, 0x%x, 0x%x) => 1\n",
3966 hProcess, lpProcessAffinityMask, lpSystemAffinityMask);
3967 if(lpProcessAffinityMask)*lpProcessAffinityMask=1;
3968 if(lpSystemAffinityMask)*lpSystemAffinityMask=1;
3969 return 1;
3972 // Fake implementation: does nothing, but does it right :)
3973 static WIN_BOOL WINAPI expSetProcessAffinityMask(HANDLE hProcess,
3974 LPDWORD dwProcessAffinityMask)
3976 dbgprintf("SetProcessAffinityMask(0x%x, 0x%x) => 1\n",
3977 hProcess, dwProcessAffinityMask);
3979 return 1;
3982 static int WINAPI expMulDiv(int nNumber, int nNumerator, int nDenominator)
3984 static const long long max_int=0x7FFFFFFFLL;
3985 static const long long min_int=-0x80000000LL;
3986 long long tmp=(long long)nNumber*(long long)nNumerator;
3987 dbgprintf("expMulDiv %d * %d / %d\n", nNumber, nNumerator, nDenominator);
3988 if(!nDenominator)return 1;
3989 tmp/=nDenominator;
3990 if(tmp<min_int) return 1;
3991 if(tmp>max_int) return 1;
3992 return (int)tmp;
3995 static LONG WINAPI explstrcmpiA(const char* str1, const char* str2)
3997 LONG result=strcasecmp(str1, str2);
3998 dbgprintf("strcmpi(0x%x='%s', 0x%x='%s') => %d\n", str1, str1, str2, str2, result);
3999 return result;
4002 static LONG WINAPI explstrlenA(const char* str1)
4004 LONG result=strlen(str1);
4005 dbgprintf("strlen(0x%x='%.50s') => %d\n", str1, str1, result);
4006 return result;
4009 static LONG WINAPI explstrcpyA(char* str1, const char* str2)
4011 int result= (int) strcpy(str1, str2);
4012 dbgprintf("strcpy(0x%.50x, 0x%.50x='%.50s') => %d\n", str1, str2, str2, result);
4013 return result;
4015 static LONG WINAPI explstrcpynA(char* str1, const char* str2,int len)
4017 int result;
4018 if (strlen(str2)>len)
4019 result = (int) strncpy(str1, str2,len);
4020 else
4021 result = (int) strcpy(str1,str2);
4022 dbgprintf("strncpy(0x%x, 0x%x='%s' len %d strlen %d) => %x\n", str1, str2, str2,len, strlen(str2),result);
4023 return result;
4025 static LONG WINAPI explstrcatA(char* str1, const char* str2)
4027 int result= (int) strcat(str1, str2);
4028 dbgprintf("strcat(0x%x, 0x%x='%s') => %d\n", str1, str2, str2, result);
4029 return result;
4033 static LONG WINAPI expInterlockedExchange(long *dest, long l)
4035 long retval = *dest;
4036 *dest = l;
4037 return retval;
4040 static void WINAPI expInitCommonControls(void)
4042 dbgprintf("InitCommonControls called!\n");
4043 return;
4046 #ifdef CONFIG_QTX_CODECS
4047 /* needed by QuickTime.qts */
4048 static HWND WINAPI expCreateUpDownControl (DWORD style, INT x, INT y, INT cx, INT cy,
4049 HWND parent, INT id, HINSTANCE inst,
4050 HWND buddy, INT maxVal, INT minVal, INT curVal)
4052 dbgprintf("CreateUpDownControl(...)\n");
4053 return 0;
4055 #endif
4057 /* alex: implement this call! needed for 3ivx */
4058 static HRESULT WINAPI expCoCreateFreeThreadedMarshaler(void *pUnkOuter, void **ppUnkInner)
4060 dbgprintf("CoCreateFreeThreadedMarshaler(%p, %p) called!\n",
4061 pUnkOuter, ppUnkInner);
4062 // return 0;
4063 return ERROR_CALL_NOT_IMPLEMENTED;
4067 static int WINAPI expDuplicateHandle(HANDLE hSourceProcessHandle, // handle to source process
4068 HANDLE hSourceHandle, // handle to duplicate
4069 HANDLE hTargetProcessHandle, // handle to target process
4070 HANDLE* lpTargetHandle, // duplicate handle
4071 DWORD dwDesiredAccess, // requested access
4072 int bInheritHandle, // handle inheritance option
4073 DWORD dwOptions // optional actions
4076 dbgprintf("DuplicateHandle(%p, %p, %p, %p, 0x%x, %d, %d) called\n",
4077 hSourceProcessHandle, hSourceHandle, hTargetProcessHandle,
4078 lpTargetHandle, dwDesiredAccess, bInheritHandle, dwOptions);
4079 *lpTargetHandle = hSourceHandle;
4080 return 1;
4083 static HRESULT WINAPI expCoInitializeEx(LPVOID lpReserved, DWORD dwCoInit)
4085 dbgprintf("CoInitializeEx(%p, %d) called\n", lpReserved, dwCoInit);
4086 return S_OK;
4089 // required by PIM1 codec (used by win98 PCTV Studio capture sw)
4090 static HRESULT WINAPI expCoInitialize(
4091 LPVOID lpReserved /* [in] pointer to win32 malloc interface
4092 (obsolete, should be NULL) */
4096 * Just delegate to the newer method.
4098 return expCoInitializeEx(lpReserved, COINIT_APARTMENTTHREADED);
4101 static void WINAPI expCoUninitialize(void)
4103 dbgprintf("CoUninitialize() called\n");
4106 /* allow static linking */
4107 HRESULT WINAPI CoInitializeEx(LPVOID lpReserved, DWORD dwCoInit)
4109 return expCoInitializeEx(lpReserved, dwCoInit);
4111 HRESULT WINAPI CoInitialize(LPVOID lpReserved)
4113 return expCoInitialize(lpReserved);
4115 void WINAPI CoUninitialize(void)
4117 expCoUninitialize();
4120 static DWORD WINAPI expSetThreadAffinityMask
4122 HANDLE hThread,
4123 DWORD dwThreadAffinityMask
4125 return 0;
4129 * no WINAPI functions - CDECL
4131 static void* expmalloc(int size)
4133 //printf("malloc");
4134 // return malloc(size);
4135 void* result=my_mreq(size,0);
4136 dbgprintf("malloc(0x%x) => 0x%x\n", size,result);
4137 if(result==0)
4138 printf("WARNING: malloc() failed\n");
4139 return result;
4141 static void expfree(void* mem)
4143 // return free(mem);
4144 dbgprintf("free(%p)\n", mem);
4145 my_release(mem);
4147 /* needed by atrac3.acm */
4148 static void *expcalloc(int num, int size)
4150 void* result=my_mreq(num*size,1);
4151 dbgprintf("calloc(%d,%d) => %p\n", num,size,result);
4152 if(result==0)
4153 printf("WARNING: calloc() failed\n");
4154 return result;
4156 static void* expnew(int size)
4158 // printf("NEW:: Call from address %08x\n STACK DUMP:\n", *(-1+(int*)&size));
4159 // printf("%08x %08x %08x %08x\n",
4160 // size, *(1+(int*)&size),
4161 // *(2+(int*)&size),*(3+(int*)&size));
4162 void* result;
4163 assert(size >= 0);
4165 result=my_mreq(size,0);
4166 dbgprintf("new(%d) => %p\n", size, result);
4167 if (result==0)
4168 printf("WARNING: new() failed\n");
4169 return result;
4172 static int expdelete(void* memory)
4174 dbgprintf("delete(%p)\n", memory);
4175 my_release(memory);
4176 return 0;
4180 * local definition - we need only the last two members at this point
4181 * otherwice we would have to introduce here GUIDs and some more types..
4183 typedef struct __attribute__((__packed__))
4185 char hay[0x40];
4186 unsigned long cbFormat; //0x40
4187 char* pbFormat; //0x44
4188 } MY_MEDIA_TYPE;
4189 static HRESULT WINAPI expMoCopyMediaType(MY_MEDIA_TYPE* dest, const MY_MEDIA_TYPE* src)
4191 if (!dest || !src)
4192 return E_POINTER;
4193 memcpy(dest, src, sizeof(MY_MEDIA_TYPE));
4194 if (dest->cbFormat)
4196 dest->pbFormat = (char*) my_mreq(dest->cbFormat, 0);
4197 if (!dest->pbFormat)
4198 return E_OUTOFMEMORY;
4199 memcpy(dest->pbFormat, src->pbFormat, dest->cbFormat);
4201 return S_OK;
4203 static HRESULT WINAPI expMoInitMediaType(MY_MEDIA_TYPE* dest, DWORD cbFormat)
4205 if (!dest)
4206 return E_POINTER;
4207 memset(dest, 0, sizeof(MY_MEDIA_TYPE));
4208 if (cbFormat)
4210 dest->pbFormat = (char*) my_mreq(cbFormat, 0);
4211 if (!dest->pbFormat)
4212 return E_OUTOFMEMORY;
4214 return S_OK;
4216 static HRESULT WINAPI expMoCreateMediaType(MY_MEDIA_TYPE** dest, DWORD cbFormat)
4218 if (!dest)
4219 return E_POINTER;
4220 *dest = my_mreq(sizeof(MY_MEDIA_TYPE), 0);
4221 return expMoInitMediaType(*dest, cbFormat);
4223 static HRESULT WINAPI expMoDuplicateMediaType(MY_MEDIA_TYPE** dest, const void* src)
4225 if (!dest)
4226 return E_POINTER;
4227 *dest = my_mreq(sizeof(MY_MEDIA_TYPE), 0);
4228 return expMoCopyMediaType(*dest, src);
4230 static HRESULT WINAPI expMoFreeMediaType(MY_MEDIA_TYPE* dest)
4232 if (!dest)
4233 return E_POINTER;
4234 if (dest->pbFormat)
4236 my_release(dest->pbFormat);
4237 dest->pbFormat = 0;
4238 dest->cbFormat = 0;
4240 return S_OK;
4242 static HRESULT WINAPI expMoDeleteMediaType(MY_MEDIA_TYPE* dest)
4244 if (!dest)
4245 return E_POINTER;
4246 expMoFreeMediaType(dest);
4247 my_release(dest);
4248 return S_OK;
4251 static int exp_snprintf( char *str, int size, const char *format, ... )
4253 int x;
4254 va_list va;
4255 va_start(va, format);
4256 x=snprintf(str,size,format,va);
4257 dbgprintf("_snprintf( 0x%x, %d, %s, ... ) => %d\n",str,size,format,x);
4258 va_end(va);
4259 return x;
4262 #if 0
4263 static int exp_initterm(int v1, int v2)
4265 dbgprintf("_initterm(0x%x, 0x%x) => 0\n", v1, v2);
4266 return 0;
4268 #else
4269 /* merged from wine - 2002.04.21 */
4270 typedef void (*INITTERMFUNC)();
4271 static int exp_initterm(INITTERMFUNC *start, INITTERMFUNC *end)
4273 dbgprintf("_initterm(0x%x, 0x%x) %p\n", start, end, *start);
4274 while (start < end)
4276 if (*start)
4278 //printf("call _initfunc: from: %p %d\n", *start);
4279 // ok this trick with push/pop is necessary as otherwice
4280 // edi/esi registers are being trashed
4281 void* p = *start;
4282 __asm__ volatile
4284 "pushl %%ebx \n\t"
4285 "pushl %%ecx \n\t"
4286 "pushl %%edx \n\t"
4287 "pushl %%edi \n\t"
4288 "pushl %%esi \n\t"
4289 "call *%%eax \n\t"
4290 "popl %%esi \n\t"
4291 "popl %%edi \n\t"
4292 "popl %%edx \n\t"
4293 "popl %%ecx \n\t"
4294 "popl %%ebx \n\t"
4296 : "a"(p)
4297 : "memory"
4299 //printf("done %p %d:%d\n", end);
4301 start++;
4303 return 0;
4305 #endif
4307 /* Fake _initterm_e from msvcr80.dll, needed by sirenacm.dll
4308 * NOTE: If I make this an alias for _initterm, then sirenacm.dll tries to call
4309 other uninmplemented functions; keep this in mind if some future codec needs
4310 a real implementation of this function */
4311 static int exp_initterm_e(INITTERMFUNC *start, INITTERMFUNC *end)
4313 dbgprintf("_initterm_e(0x%x, 0x%x)\n", start, end);
4314 return 0;
4317 static void* exp__dllonexit(void)
4319 // FIXME extract from WINE
4320 return NULL;
4323 static int expwsprintfA(char* string, const char* format, ...)
4325 va_list va;
4326 int result;
4327 va_start(va, format);
4328 result = vsprintf(string, format, va);
4329 dbgprintf("wsprintfA(0x%x, '%s', ...) => %d\n", string, format, result);
4330 va_end(va);
4331 return result;
4334 static int expsprintf(char* str, const char* format, ...)
4336 va_list args;
4337 int r;
4338 dbgprintf("sprintf(0x%x, %s)\n", str, format);
4339 va_start(args, format);
4340 r = vsprintf(str, format, args);
4341 va_end(args);
4342 return r;
4344 static int expsscanf(const char* str, const char* format, ...)
4346 va_list args;
4347 int r;
4348 dbgprintf("sscanf(%s, %s)\n", str, format);
4349 va_start(args, format);
4350 r = vsscanf(str, format, args);
4351 va_end(args);
4352 return r;
4354 static void* expfopen(const char* path, const char* mode)
4356 printf("fopen: \"%s\" mode:%s\n", path, mode);
4357 //return fopen(path, mode);
4358 return fdopen(0, mode); // everything on screen
4360 static int expfprintf(void* stream, const char* format, ...)
4362 va_list args;
4363 int r = 0;
4364 dbgprintf("fprintf(%p, %s, ...)\n", stream, format);
4365 va_start(args, format);
4366 r = vfprintf((FILE*) stream, format, args);
4367 va_end(args);
4368 return r;
4371 static int expprintf(const char* format, ...)
4373 va_list args;
4374 int r;
4375 dbgprintf("printf(%s, ...)\n", format);
4376 va_start(args, format);
4377 r = vprintf(format, args);
4378 va_end(args);
4379 return r;
4382 static char* expgetenv(const char* varname)
4384 char* v = getenv(varname);
4385 dbgprintf("getenv(%s) => %s\n", varname, v);
4386 return v;
4389 static void* expwcscpy(WCHAR* dst, const WCHAR* src)
4391 WCHAR* p = dst;
4392 while ((*p++ = *src++))
4394 return dst;
4397 static char* expstrrchr(char* string, int value)
4399 char* result=strrchr(string, value);
4400 if(result)
4401 dbgprintf("strrchr(0x%x='%s', %d) => 0x%x='%s'", string, string, value, result, result);
4402 else
4403 dbgprintf("strrchr(0x%x='%s', %d) => 0", string, string, value);
4404 return result;
4407 static char* expstrchr(char* string, int value)
4409 char* result=strchr(string, value);
4410 if(result)
4411 dbgprintf("strchr(0x%x='%s', %d) => 0x%x='%s'", string, string, value, result, result);
4412 else
4413 dbgprintf("strchr(0x%x='%s', %d) => 0", string, string, value);
4414 return result;
4416 static int expstrlen(char* str)
4418 int result=strlen(str);
4419 dbgprintf("strlen(0x%x='%s') => %d\n", str, str, result);
4420 return result;
4422 static char* expstrcpy(char* str1, const char* str2)
4424 char* result= strcpy(str1, str2);
4425 dbgprintf("strcpy(0x%x, 0x%x='%s') => %p\n", str1, str2, str2, result);
4426 return result;
4428 static char* expstrncpy(char* str1, const char* str2, size_t count)
4430 char* result= strncpy(str1, str2, count);
4431 dbgprintf("strncpy(0x%x, 0x%x='%s', %d) => %p\n", str1, str2, str2, count, result);
4432 return result;
4434 static int expstrcmp(const char* str1, const char* str2)
4436 int result=strcmp(str1, str2);
4437 dbgprintf("strcmp(0x%x='%s', 0x%x='%s') => %d\n", str1, str1, str2, str2, result);
4438 return result;
4440 static int expstrncmp(const char* str1, const char* str2,int x)
4442 int result=strncmp(str1, str2,x);
4443 dbgprintf("strcmp(0x%x='%s', 0x%x='%s') => %d\n", str1, str1, str2, str2, result);
4444 return result;
4446 static char* expstrcat(char* str1, const char* str2)
4448 char* result = strcat(str1, str2);
4449 dbgprintf("strcat(0x%x='%s', 0x%x='%s') => %p\n", str1, str1, str2, str2, result);
4450 return result;
4452 static char* exp_strdup(const char* str1)
4454 int l = strlen(str1);
4455 char* result = (char*) my_mreq(l + 1,0);
4456 if (result)
4457 strcpy(result, str1);
4458 dbgprintf("_strdup(0x%x='%s') => %p\n", str1, str1, result);
4459 return result;
4461 static int expisalnum(int c)
4463 int result= (int) isalnum(c);
4464 dbgprintf("isalnum(0x%x='%c' => %d\n", c, c, result);
4465 return result;
4467 static int expisspace(int c)
4469 int result= (int) isspace(c);
4470 dbgprintf("isspace(0x%x='%c' => %d\n", c, c, result);
4471 return result;
4473 static int expisalpha(int c)
4475 int result= (int) isalpha(c);
4476 dbgprintf("isalpha(0x%x='%c' => %d\n", c, c, result);
4477 return result;
4479 static int expisdigit(int c)
4481 int result= (int) isdigit(c);
4482 dbgprintf("isdigit(0x%x='%c' => %d\n", c, c, result);
4483 return result;
4485 static void* expmemmove(void* dest, void* src, int n)
4487 void* result = memmove(dest, src, n);
4488 dbgprintf("memmove(0x%x, 0x%x, %d) => %p\n", dest, src, n, result);
4489 return result;
4491 static int expmemcmp(void* dest, void* src, int n)
4493 int result = memcmp(dest, src, n);
4494 dbgprintf("memcmp(0x%x, 0x%x, %d) => %d\n", dest, src, n, result);
4495 return result;
4497 static void* expmemcpy(void* dest, void* src, int n)
4499 void *result = memcpy(dest, src, n);
4500 dbgprintf("memcpy(0x%x, 0x%x, %d) => %p\n", dest, src, n, result);
4501 return result;
4503 static void* expmemset(void* dest, int c, size_t n)
4505 void *result = memset(dest, c, n);
4506 dbgprintf("memset(0x%x, %d, %d) => %p\n", dest, c, n, result);
4507 return result;
4509 static time_t exptime(time_t* t)
4511 time_t result = time(t);
4512 dbgprintf("time(0x%x) => %d\n", t, result);
4513 return result;
4516 static int exprand(void)
4518 return rand();
4521 static void expsrand(int seed)
4523 srand(seed);
4526 #if 1
4528 // preferred compilation with -O2 -ffast-math !
4530 static double explog10(double x)
4532 /*printf("Log10 %f => %f 0x%Lx\n", x, log10(x), *((int64_t*)&x));*/
4533 return log10(x);
4536 static double expcos(double x)
4538 /*printf("Cos %f => %f 0x%Lx\n", x, cos(x), *((int64_t*)&x));*/
4539 return cos(x);
4542 #else
4544 static void explog10(void)
4546 __asm__ volatile
4548 "fldl 8(%esp) \n\t"
4549 "fldln2 \n\t"
4550 "fxch %st(1) \n\t"
4551 "fyl2x \n\t"
4555 static void expcos(void)
4557 __asm__ volatile
4559 "fldl 8(%esp) \n\t"
4560 "fcos \n\t"
4564 #endif
4566 // this seem to be the only how to make this function working properly
4567 // ok - I've spent tremendous amount of time (many many many hours
4568 // of debuging fixing & testing - it's almost unimaginable - kabi
4570 // _ftol - operated on the float value which is already on the FPU stack
4572 static void exp_ftol(void)
4574 __asm__ volatile
4576 "sub $12, %esp \n\t"
4577 "fstcw -2(%ebp) \n\t"
4578 "wait \n\t"
4579 "movw -2(%ebp), %ax \n\t"
4580 "orb $0x0C, %ah \n\t"
4581 "movw %ax, -4(%ebp) \n\t"
4582 "fldcw -4(%ebp) \n\t"
4583 "fistpl -12(%ebp) \n\t"
4584 "fldcw -2(%ebp) \n\t"
4585 "movl -12(%ebp), %eax \n\t"
4586 //Note: gcc 3.03 does not do the following op if it
4587 // knows that ebp=esp
4588 "movl %ebp, %esp \n\t"
4592 #define FPU_DOUBLES(var1,var2) double var1,var2; \
4593 __asm__ volatile( "fstpl %0;fwait" : "=m" (var2) : ); \
4594 __asm__ volatile( "fstpl %0;fwait" : "=m" (var1) : )
4596 static double exp_CIpow(void)
4598 FPU_DOUBLES(x,y);
4600 dbgprintf("_CIpow(%lf, %lf)\n", x, y);
4601 return pow(x, y);
4604 static double exppow(double x, double y)
4606 /*printf("Pow %f %f 0x%Lx 0x%Lx => %f\n", x, y, *((int64_t*)&x), *((int64_t*)&y), pow(x, y));*/
4607 return pow(x, y);
4610 static double expldexp(double x, int expo)
4612 /*printf("Cos %f => %f 0x%Lx\n", x, cos(x), *((int64_t*)&x));*/
4613 return ldexp(x, expo);
4616 static double expfrexp(double x, int* expo)
4618 /*printf("Cos %f => %f 0x%Lx\n", x, cos(x), *((int64_t*)&x));*/
4619 return frexp(x, expo);
4624 static int exp_stricmp(const char* s1, const char* s2)
4626 return strcasecmp(s1, s2);
4629 /* from declaration taken from Wine sources - this fountion seems to be
4630 * undocumented in any M$ doc */
4631 static int exp_setjmp3(void* jmpbuf, int x)
4633 //dbgprintf("!!!!UNIMPLEMENTED: setjmp3(%p, %d) => 0\n", jmpbuf, x);
4634 //return 0;
4635 __asm__ volatile
4637 //"mov 4(%%esp), %%edx \n\t"
4638 "mov (%%esp), %%eax \n\t"
4639 "mov %%eax, (%%edx) \n\t" // store ebp
4641 //"mov %%ebp, (%%edx) \n\t"
4642 "mov %%ebx, 4(%%edx) \n\t"
4643 "mov %%edi, 8(%%edx) \n\t"
4644 "mov %%esi, 12(%%edx) \n\t"
4645 "mov %%esp, 16(%%edx) \n\t"
4647 "mov 4(%%esp), %%eax \n\t"
4648 "mov %%eax, 20(%%edx) \n\t"
4650 "movl $0x56433230, 32(%%edx) \n\t" // VC20 ??
4651 "movl $0, 36(%%edx) \n\t"
4652 : // output
4653 : "d"(jmpbuf) // input
4654 : "eax"
4656 __asm__ volatile
4658 "mov %%fs:0, %%eax \n\t" // unsure
4659 "mov %%eax, 24(%%edx) \n\t"
4660 "cmp $0xffffffff, %%eax \n\t"
4661 "jnz l1 \n\t"
4662 "mov %%eax, 28(%%edx) \n\t"
4663 "l1: \n\t"
4666 : "eax"
4669 return 0;
4672 static DWORD WINAPI expGetCurrentProcessId(void)
4674 dbgprintf("GetCurrentProcessId(void) => %d\n", getpid());
4675 return getpid(); //(DWORD)NtCurrentTeb()->pid;
4679 typedef struct {
4680 UINT wPeriodMin;
4681 UINT wPeriodMax;
4682 } TIMECAPS, *LPTIMECAPS;
4684 static MMRESULT WINAPI exptimeGetDevCaps(LPTIMECAPS lpCaps, UINT wSize)
4686 dbgprintf("timeGetDevCaps(%p, %u) !\n", lpCaps, wSize);
4688 lpCaps->wPeriodMin = 1;
4689 lpCaps->wPeriodMax = 65535;
4690 return 0;
4693 static MMRESULT WINAPI exptimeBeginPeriod(UINT wPeriod)
4695 dbgprintf("timeBeginPeriod(%u) !\n", wPeriod);
4697 if (wPeriod < 1 || wPeriod > 65535) return 96+1; //TIMERR_NOCANDO;
4698 return 0;
4701 #ifdef CONFIG_QTX_CODECS
4702 static MMRESULT WINAPI exptimeEndPeriod(UINT wPeriod)
4704 dbgprintf("timeEndPeriod(%u) !\n", wPeriod);
4706 if (wPeriod < 1 || wPeriod > 65535) return 96+1; //TIMERR_NOCANDO;
4707 return 0;
4709 #endif
4711 static void WINAPI expGlobalMemoryStatus(
4712 LPMEMORYSTATUS lpmem
4714 static MEMORYSTATUS cached_memstatus;
4715 static int cache_lastchecked = 0;
4716 SYSTEM_INFO si;
4717 FILE *f;
4719 if (time(NULL)==cache_lastchecked) {
4720 memcpy(lpmem,&cached_memstatus,sizeof(MEMORYSTATUS));
4721 return;
4724 f = fopen( "/proc/meminfo", "r" );
4725 if (f)
4727 char buffer[256];
4728 int total, used, free, shared, buffers, cached;
4730 lpmem->dwLength = sizeof(MEMORYSTATUS);
4731 lpmem->dwTotalPhys = lpmem->dwAvailPhys = 0;
4732 lpmem->dwTotalPageFile = lpmem->dwAvailPageFile = 0;
4733 while (fgets( buffer, sizeof(buffer), f ))
4735 /* old style /proc/meminfo ... */
4736 if (sscanf( buffer, "Mem: %d %d %d %d %d %d", &total, &used, &free, &shared, &buffers, &cached ))
4738 lpmem->dwTotalPhys += total;
4739 lpmem->dwAvailPhys += free + buffers + cached;
4741 if (sscanf( buffer, "Swap: %d %d %d", &total, &used, &free ))
4743 lpmem->dwTotalPageFile += total;
4744 lpmem->dwAvailPageFile += free;
4747 /* new style /proc/meminfo ... */
4748 if (sscanf(buffer, "MemTotal: %d", &total))
4749 lpmem->dwTotalPhys = total*1024;
4750 if (sscanf(buffer, "MemFree: %d", &free))
4751 lpmem->dwAvailPhys = free*1024;
4752 if (sscanf(buffer, "SwapTotal: %d", &total))
4753 lpmem->dwTotalPageFile = total*1024;
4754 if (sscanf(buffer, "SwapFree: %d", &free))
4755 lpmem->dwAvailPageFile = free*1024;
4756 if (sscanf(buffer, "Buffers: %d", &buffers))
4757 lpmem->dwAvailPhys += buffers*1024;
4758 if (sscanf(buffer, "Cached: %d", &cached))
4759 lpmem->dwAvailPhys += cached*1024;
4761 fclose( f );
4763 if (lpmem->dwTotalPhys)
4765 DWORD TotalPhysical = lpmem->dwTotalPhys+lpmem->dwTotalPageFile;
4766 DWORD AvailPhysical = lpmem->dwAvailPhys+lpmem->dwAvailPageFile;
4767 lpmem->dwMemoryLoad = (TotalPhysical-AvailPhysical)
4768 / (TotalPhysical / 100);
4770 } else
4772 /* FIXME: should do something for other systems */
4773 lpmem->dwMemoryLoad = 0;
4774 lpmem->dwTotalPhys = 16*1024*1024;
4775 lpmem->dwAvailPhys = 16*1024*1024;
4776 lpmem->dwTotalPageFile = 16*1024*1024;
4777 lpmem->dwAvailPageFile = 16*1024*1024;
4779 expGetSystemInfo(&si);
4780 lpmem->dwTotalVirtual = si.lpMaximumApplicationAddress-si.lpMinimumApplicationAddress;
4781 /* FIXME: we should track down all the already allocated VM pages and substract them, for now arbitrarily remove 64KB so that it matches NT */
4782 lpmem->dwAvailVirtual = lpmem->dwTotalVirtual-64*1024;
4783 memcpy(&cached_memstatus,lpmem,sizeof(MEMORYSTATUS));
4784 cache_lastchecked = time(NULL);
4786 /* it appears some memory display programs want to divide by these values */
4787 if(lpmem->dwTotalPageFile==0)
4788 lpmem->dwTotalPageFile++;
4790 if(lpmem->dwAvailPageFile==0)
4791 lpmem->dwAvailPageFile++;
4794 static INT WINAPI expGetThreadPriority(HANDLE hthread)
4796 dbgprintf("GetThreadPriority(%p)\n",hthread);
4797 return 0;
4800 /**********************************************************************
4801 * SetThreadPriority [KERNEL32.@] Sets priority for thread.
4803 * RETURNS
4804 * Success: TRUE
4805 * Failure: FALSE
4807 static WIN_BOOL WINAPI expSetThreadPriority(
4808 HANDLE hthread, /* [in] Handle to thread */
4809 INT priority) /* [in] Thread priority level */
4811 dbgprintf("SetThreadPriority(%p,%d)\n",hthread,priority);
4812 return TRUE;
4815 static void WINAPI expTerminateProcess( DWORD process, DWORD status )
4817 printf("EXIT - process %ld code %ld\n", process, status);
4818 exit(status);
4821 static void WINAPI expExitProcess( DWORD status )
4823 printf("EXIT - code %ld\n",status);
4824 exit(status);
4827 static INT WINAPI expMessageBoxA(HWND hWnd, LPCSTR text, LPCSTR title, UINT type){
4828 printf("MSGBOX '%s' '%s' (%d)\n",text,title,type);
4829 #ifdef CONFIG_QTX_CODECS
4830 if (type == MB_ICONHAND && !strlen(text) && !strlen(title))
4831 return IDIGNORE;
4832 #endif
4833 return IDOK;
4836 /* these are needed for mss1 */
4839 * \brief this symbol is defined within exp_EH_prolog_dummy
4840 * \param dest jump target
4842 void exp_EH_prolog(void *dest);
4843 void exp_EH_prolog_dummy(void);
4844 //! just a dummy function that acts a container for the asm section
4845 void exp_EH_prolog_dummy(void) {
4846 __asm__ volatile (
4847 // take care, this "function" may not change flags or
4848 // registers besides eax (which is also why we can't use
4849 // exp_EH_prolog_dummy directly)
4850 MANGLE(exp_EH_prolog)": \n\t"
4851 "pop %eax \n\t"
4852 "push %ebp \n\t"
4853 "mov %esp, %ebp \n\t"
4854 "lea -12(%esp), %esp \n\t"
4855 "jmp *%eax \n\t"
4859 #include <netinet/in.h>
4860 static WINAPI inline unsigned long int exphtonl(unsigned long int hostlong)
4862 // dbgprintf("htonl(%x) => %x\n", hostlong, htonl(hostlong));
4863 return htonl(hostlong);
4866 static WINAPI inline unsigned long int expntohl(unsigned long int netlong)
4868 // dbgprintf("ntohl(%x) => %x\n", netlong, ntohl(netlong));
4869 return ntohl(netlong);
4872 static char* WINAPI expSysAllocStringLen(char *pch, unsigned cch)
4874 char *str;
4875 dbgprintf("SysAllocStringLen('%s', %d)\n", pch, cch);
4876 str = malloc(cch * 2 + sizeof(unsigned) + 2);
4877 *(unsigned *)str = cch;
4878 str += sizeof(unsigned);
4879 if (pch)
4880 memcpy(str, pch, cch * 2);
4881 str[cch * 2] = 0;
4882 str[cch * 2 + 1] = 0;
4883 return str;
4886 static void WINAPI expSysFreeString(char *str)
4888 if (str) {
4889 free(str - sizeof(unsigned));
4893 static void WINAPI expVariantInit(void* p)
4895 printf("InitCommonControls called!\n");
4896 return;
4899 static int WINAPI expRegisterClassA(const void/*WNDCLASSA*/ *wc)
4901 dbgprintf("RegisterClassA(%p) => random id\n", wc);
4902 return time(NULL); /* be precise ! */
4905 static int WINAPI expUnregisterClassA(const char *className, HINSTANCE hInstance)
4907 dbgprintf("UnregisterClassA(%s, %p) => 0\n", className, hInstance);
4908 return 0;
4911 #ifdef CONFIG_QTX_CODECS
4912 /* should be fixed bcs it's not fully strlen equivalent */
4913 static int expSysStringByteLen(void *str)
4915 dbgprintf("SysStringByteLen(%p) => %d\n", str, strlen(str));
4916 return strlen(str);
4919 static int expDirectDrawCreate(void)
4921 dbgprintf("DirectDrawCreate(...) => NULL\n");
4922 return 0;
4925 #if 1
4926 typedef struct tagPALETTEENTRY {
4927 BYTE peRed;
4928 BYTE peGreen;
4929 BYTE peBlue;
4930 BYTE peFlags;
4931 } PALETTEENTRY;
4933 typedef struct tagLOGPALETTE {
4934 WORD palVersion;
4935 WORD palNumEntries;
4936 PALETTEENTRY palPalEntry[1];
4937 } LOGPALETTE;
4939 static HPALETTE WINAPI expCreatePalette(CONST LOGPALETTE *lpgpl)
4941 HPALETTE test;
4942 int i;
4944 dbgprintf("CreatePalette(%x) => NULL\n", lpgpl);
4946 i = sizeof(LOGPALETTE)+((lpgpl->palNumEntries-1)*sizeof(PALETTEENTRY));
4947 test = malloc(i);
4948 memcpy((void *)test, lpgpl, i);
4950 return test;
4952 #else
4953 static int expCreatePalette(void)
4955 dbgprintf("CreatePalette(...) => NULL\n");
4956 return NULL;
4958 #endif
4960 static int WINAPI expGetClientRect(HWND win, RECT *r)
4962 dbgprintf("GetClientRect(0x%x, 0x%x) => 1\n", win, r);
4963 r->right = PSEUDO_SCREEN_WIDTH;
4964 r->left = 0;
4965 r->bottom = PSEUDO_SCREEN_HEIGHT;
4966 r->top = 0;
4967 return 1;
4970 #if 0
4971 typedef struct tagPOINT {
4972 LONG x;
4973 LONG y;
4974 } POINT, *PPOINT;
4975 #endif
4977 static int WINAPI expClientToScreen(HWND win, POINT *p)
4979 dbgprintf("ClientToScreen(0x%x, 0x%x = %d,%d) => 1\n", win, p, p->x, p->y);
4980 p->x = 0;
4981 p->y = 0;
4982 return 1;
4984 #endif
4986 /* for m3jpeg */
4987 static int WINAPI expSetThreadIdealProcessor(HANDLE thread, int proc)
4989 dbgprintf("SetThreadIdealProcessor(0x%x, %x) => 0\n", thread, proc);
4990 return 0;
4993 static int WINAPI expMessageBeep(int type)
4995 dbgprintf("MessageBeep(%d) => 1\n", type);
4996 return 1;
4999 static int WINAPI expDialogBoxParamA(void *inst, const char *name,
5000 HWND parent, void *dialog_func, void *init_param)
5002 dbgprintf("DialogBoxParamA(0x%x, 0x%x = %s, 0x%x, 0x%x, 0x%x) => 0x42424242\n",
5003 inst, name, name, parent, dialog_func, init_param);
5004 return 0x42424242;
5007 static void WINAPI expRegisterClipboardFormatA(const char *name) {
5008 dbgprintf("RegisterClipboardFormatA(0x%x = %s)\n", name, name);
5011 /* needed by imagepower mjpeg2k */
5012 static void *exprealloc(void *ptr, size_t size)
5014 dbgprintf("realloc(0x%x, %x)\n", ptr, size);
5015 if (!ptr)
5016 return my_mreq(size,0);
5017 else
5018 return my_realloc(ptr, size);
5021 /* Fake GetOpenFileNameA from comdlg32.dll for ViVD codec */
5022 static WIN_BOOL WINAPI expGetOpenFileNameA(/*LPOPENFILENAMEA*/ void* lpfn)
5024 return 1;
5027 static char * WINAPI expPathFindExtensionA(const char *path) {
5028 char *ext;
5029 if (!path)
5030 ext = NULL;
5031 else {
5032 ext = strrchr(path, '.');
5033 if (!ext)
5034 ext = &path[strlen(path)];
5036 dbgprintf("PathFindExtensionA(0x%x = %s) => 0x%x, %s\n", path, path, ext, ext);
5037 return ext;
5040 static char * WINAPI expPathFindFileNameA(const char *path) {
5041 char *name;
5042 if (!path || strlen(path) < 2)
5043 name = path;
5044 else {
5045 name = strrchr(path - 1, '\\');
5046 if (!name)
5047 name = path;
5049 dbgprintf("PathFindFileNameA(0x%x = %s) => 0x%x, %s\n", path, path, name, name);
5050 return name;
5053 static double expfloor(double x)
5055 dbgprintf("floor(%lf)\n", x);
5056 return floor(x);
5059 #define FPU_DOUBLE(var) double var; \
5060 __asm__ volatile( "fstpl %0;fwait" : "=m" (var) : )
5062 static double exp_CIcos(void)
5064 FPU_DOUBLE(x);
5066 dbgprintf("_CIcos(%lf)\n", x);
5067 return cos(x);
5070 static double exp_CIsin(void)
5072 FPU_DOUBLE(x);
5074 dbgprintf("_CIsin(%lf)\n", x);
5075 return sin(x);
5078 static double exp_CIsqrt(void)
5080 FPU_DOUBLE(x);
5082 dbgprintf("_CIsqrt(%lf)\n", x);
5083 return sqrt(x);
5086 /* Needed by rp8 sipr decoder */
5087 static LPSTR WINAPI expCharNextA(LPCSTR ptr)
5089 if (!*ptr) return (LPSTR)ptr;
5090 // dbgprintf("CharNextA(0x%08x), %s\n", ptr, ptr);
5091 return (LPSTR)(ptr + 1);
5094 // Fake implementation, needed by wvc1dmod.dll
5095 static int WINAPI expPropVariantClear(void *pvar)
5097 // dbgprintf("PropVariantclear (0x%08x), %s\n", ptr, ptr);
5098 return 1;
5101 // This define is fake, the real thing is a struct
5102 #define LPDEVMODEA void*
5103 // Dummy implementation, always return 1
5104 // Required for frapsvid.dll 2.8.1, return value does not matter
5105 static WIN_BOOL WINAPI expEnumDisplaySettingsA(LPCSTR name ,DWORD n,
5106 LPDEVMODEA devmode)
5108 dbgprintf("EnumDisplaySettingsA (dummy) => 1\n");
5109 return 1;
5112 // Fake implementation of _decode_pointer from msvcr80.dll, needed by sirenacm.dll
5113 // NOTE: undocumented function, probably the declaration is not right
5114 static int exp_decode_pointer(void *ptr)
5116 dbgprintf("_decode_pointer (0x%08x)\n", ptr);
5117 return 0;
5120 /* Fake implementation of sdt::_Lockit::_Lockit(void) from msvcp60.dll
5121 Needed by SCLS.DLL */
5122 static int exp_0Lockit_dummy(void)
5124 dbgprintf("0Lockit_dummy (??0_Lockit@std@@QAE@XZ)\n");
5125 return 0;
5128 /* Fake implementation of sdt::_Lockit::~_Lockit(void) from msvcp60.dll
5129 Needed by SCLS.DLL */
5130 static int exp_1Lockit_dummy(void)
5132 dbgprintf("1Lockit_dummy (??1_Lockit@std@@QAE@XZ)\n");
5133 return 0;
5136 static void * WINAPI expEncodePointer(void *p)
5138 return p;
5141 static void * WINAPI expDecodePointer(void *p)
5143 return p;
5146 static DWORD WINAPI expGetThreadLocale(void)
5148 return 0;
5152 * Very incomplete implementation, return an error for almost all cases.
5154 static DWORD WINAPI expGetLocaleInfoA(DWORD locale, DWORD lctype, char* lpLCData, int cchData)
5156 if (lctype == 0x1004) { // LOCALE_IDEFAULTANSICODEPAGE
5157 if (cchData < 4)
5158 return cchData == 0 ? 4 : 0;
5159 strcpy(lpLCData, "437");
5160 return 4;
5162 return 0;
5165 struct exports
5167 char name[64];
5168 int id;
5169 void* func;
5171 struct libs
5173 char name[64];
5174 int length;
5175 struct exports* exps;
5178 #define FF(X,Y) \
5179 {#X, Y, (void*)exp##X},
5181 #define UNDEFF(X, Y) \
5182 {#X, Y, (void*)-1},
5184 struct exports exp_kernel32[]=
5186 FF(GetVolumeInformationA,-1)
5187 FF(GetDriveTypeA,-1)
5188 FF(GetLogicalDriveStringsA,-1)
5189 FF(IsBadWritePtr, 357)
5190 FF(IsBadReadPtr, 354)
5191 FF(IsBadStringPtrW, -1)
5192 FF(IsBadStringPtrA, -1)
5193 FF(DisableThreadLibraryCalls, -1)
5194 FF(CreateThread, -1)
5195 FF(ResumeThread, -1)
5196 FF(CreateEventA, -1)
5197 FF(CreateEventW, -1)
5198 FF(SetEvent, -1)
5199 FF(ResetEvent, -1)
5200 FF(WaitForSingleObject, -1)
5201 #ifdef CONFIG_QTX_CODECS
5202 FF(WaitForMultipleObjects, -1)
5203 FF(ExitThread, -1)
5204 #endif
5205 FF(GetSystemInfo, -1)
5206 FF(GetVersion, 332)
5207 FF(HeapCreate, 461)
5208 FF(HeapAlloc, -1)
5209 FF(HeapDestroy, -1)
5210 FF(HeapFree, -1)
5211 FF(HeapSize, -1)
5212 FF(HeapReAlloc,-1)
5213 FF(GetProcessHeap, -1)
5214 FF(VirtualAlloc, -1)
5215 FF(VirtualFree, -1)
5216 FF(InitializeCriticalSection, -1)
5217 FF(InitializeCriticalSectionAndSpinCount, -1)
5218 FF(EnterCriticalSection, -1)
5219 FF(LeaveCriticalSection, -1)
5220 FF(DeleteCriticalSection, -1)
5221 FF(TlsAlloc, -1)
5222 FF(TlsFree, -1)
5223 FF(TlsGetValue, -1)
5224 FF(TlsSetValue, -1)
5225 FF(GetCurrentThreadId, -1)
5226 FF(GetCurrentProcess, -1)
5227 FF(LocalAlloc, -1)
5228 FF(LocalReAlloc,-1)
5229 FF(LocalLock, -1)
5230 FF(GlobalAlloc, -1)
5231 FF(GlobalReAlloc, -1)
5232 FF(GlobalLock, -1)
5233 FF(GlobalSize, -1)
5234 FF(MultiByteToWideChar, 427)
5235 FF(WideCharToMultiByte, -1)
5236 FF(GetVersionExA, -1)
5237 FF(GetVersionExW, -1)
5238 FF(CreateSemaphoreA, -1)
5239 FF(CreateSemaphoreW, -1)
5240 FF(QueryPerformanceCounter, -1)
5241 FF(QueryPerformanceFrequency, -1)
5242 FF(LocalHandle, -1)
5243 FF(LocalUnlock, -1)
5244 FF(LocalFree, -1)
5245 FF(GlobalHandle, -1)
5246 FF(GlobalUnlock, -1)
5247 FF(GlobalFree, -1)
5248 FF(LoadResource, -1)
5249 FF(ReleaseSemaphore, -1)
5250 FF(CreateMutexA, -1)
5251 FF(CreateMutexW, -1)
5252 FF(ReleaseMutex, -1)
5253 FF(SignalObjectAndWait, -1)
5254 FF(FindResourceA, -1)
5255 FF(LockResource, -1)
5256 FF(FreeResource, -1)
5257 FF(SizeofResource, -1)
5258 FF(CloseHandle, -1)
5259 FF(GetCommandLineA, -1)
5260 FF(GetEnvironmentStringsW, -1)
5261 FF(FreeEnvironmentStringsW, -1)
5262 FF(FreeEnvironmentStringsA, -1)
5263 FF(GetEnvironmentStrings, -1)
5264 FF(GetStartupInfoA, -1)
5265 FF(GetStdHandle, -1)
5266 FF(GetFileType, -1)
5267 #ifdef CONFIG_QTX_CODECS
5268 FF(GetFileAttributesA, -1)
5269 #endif
5270 FF(SetHandleCount, -1)
5271 FF(GetACP, -1)
5272 FF(GetModuleFileNameA, -1)
5273 FF(SetUnhandledExceptionFilter, -1)
5274 FF(LoadLibraryA, -1)
5275 FF(GetProcAddress, -1)
5276 FF(FreeLibrary, -1)
5277 FF(CreateFileMappingA, -1)
5278 FF(OpenFileMappingA, -1)
5279 FF(MapViewOfFile, -1)
5280 FF(UnmapViewOfFile, -1)
5281 FF(Sleep, -1)
5282 FF(GetModuleHandleA, -1)
5283 FF(GetModuleHandleW, -1)
5284 FF(GetProfileIntA, -1)
5285 FF(GetPrivateProfileIntA, -1)
5286 FF(GetPrivateProfileStringA, -1)
5287 FF(WritePrivateProfileStringA, -1)
5288 FF(GetLastError, -1)
5289 FF(SetLastError, -1)
5290 FF(InterlockedIncrement, -1)
5291 FF(InterlockedDecrement, -1)
5292 FF(GetTimeZoneInformation, -1)
5293 FF(OutputDebugStringA, -1)
5294 FF(GetLocalTime, -1)
5295 FF(GetSystemTime, -1)
5296 FF(GetSystemTimeAsFileTime, -1)
5297 FF(GetEnvironmentVariableA, -1)
5298 FF(SetEnvironmentVariableA, -1)
5299 FF(RtlZeroMemory,-1)
5300 FF(RtlMoveMemory,-1)
5301 FF(RtlFillMemory,-1)
5302 FF(GetTempPathA,-1)
5303 FF(FindFirstFileA,-1)
5304 FF(FindNextFileA,-1)
5305 FF(FindClose,-1)
5306 FF(FileTimeToLocalFileTime,-1)
5307 FF(DeleteFileA,-1)
5308 FF(ReadFile,-1)
5309 FF(WriteFile,-1)
5310 FF(SetFilePointer,-1)
5311 FF(GetTempFileNameA,-1)
5312 FF(CreateFileA,-1)
5313 FF(GetSystemDirectoryA,-1)
5314 FF(GetWindowsDirectoryA,-1)
5315 #ifdef CONFIG_QTX_CODECS
5316 FF(GetCurrentDirectoryA,-1)
5317 FF(SetCurrentDirectoryA,-1)
5318 FF(CreateDirectoryA,-1)
5319 #endif
5320 FF(GetShortPathNameA,-1)
5321 FF(GetFullPathNameA,-1)
5322 FF(SetErrorMode, -1)
5323 FF(IsProcessorFeaturePresent, -1)
5324 FF(IsDebuggerPresent, -1)
5325 FF(GetProcessAffinityMask, -1)
5326 FF(InterlockedExchange, -1)
5327 FF(InterlockedCompareExchange, -1)
5328 FF(MulDiv, -1)
5329 FF(lstrcmpiA, -1)
5330 FF(lstrlenA, -1)
5331 FF(lstrcpyA, -1)
5332 FF(lstrcatA, -1)
5333 FF(lstrcpynA,-1)
5334 FF(GetProcessVersion,-1)
5335 FF(GetCurrentThread,-1)
5336 FF(GetOEMCP,-1)
5337 FF(GetCPInfo,-1)
5338 FF(DuplicateHandle,-1)
5339 FF(GetTickCount, -1)
5340 FF(SetThreadAffinityMask,-1)
5341 FF(GetCurrentProcessId,-1)
5342 FF(GlobalMemoryStatus,-1)
5343 FF(GetThreadPriority,-1)
5344 FF(SetThreadPriority,-1)
5345 FF(TerminateProcess,-1)
5346 FF(ExitProcess,-1)
5347 {"LoadLibraryExA", -1, (void*)&LoadLibraryExA},
5348 FF(SetThreadIdealProcessor,-1)
5349 FF(SetProcessAffinityMask, -1)
5350 FF(EncodePointer, -1)
5351 FF(DecodePointer, -1)
5352 FF(GetThreadLocale, -1)
5353 FF(GetLocaleInfoA, -1)
5354 UNDEFF(FlsAlloc, -1)
5355 UNDEFF(FlsGetValue, -1)
5356 UNDEFF(FlsSetValue, -1)
5357 UNDEFF(FlsFree, -1)
5360 struct exports exp_msvcrt[]={
5361 FF(malloc, -1)
5362 FF(_initterm, -1)
5363 FF(__dllonexit, -1)
5364 FF(_snprintf,-1)
5365 FF(free, -1)
5366 {"??3@YAXPAX@Z", -1, expdelete},
5367 {"??2@YAPAXI@Z", -1, expnew},
5368 {"_adjust_fdiv", -1, (void*)&_adjust_fdiv},
5369 {"_winver",-1,(void*)&_winver},
5370 FF(strrchr, -1)
5371 FF(strchr, -1)
5372 FF(strlen, -1)
5373 FF(strcpy, -1)
5374 FF(strncpy, -1)
5375 FF(wcscpy, -1)
5376 FF(strcmp, -1)
5377 FF(strncmp, -1)
5378 FF(strcat, -1)
5379 FF(_stricmp,-1)
5380 FF(_strdup,-1)
5381 FF(_setjmp3,-1)
5382 FF(isalnum, -1)
5383 FF(isspace, -1)
5384 FF(isalpha, -1)
5385 FF(isdigit, -1)
5386 FF(memmove, -1)
5387 FF(memcmp, -1)
5388 FF(memset, -1)
5389 FF(memcpy, -1)
5390 FF(time, -1)
5391 FF(rand, -1)
5392 FF(srand, -1)
5393 FF(log10, -1)
5394 FF(pow, -1)
5395 FF(cos, -1)
5396 FF(_ftol,-1)
5397 FF(_CIpow,-1)
5398 FF(_CIcos,-1)
5399 FF(_CIsin,-1)
5400 FF(_CIsqrt,-1)
5401 FF(ldexp,-1)
5402 FF(frexp,-1)
5403 FF(sprintf,-1)
5404 FF(sscanf,-1)
5405 FF(fopen,-1)
5406 FF(fprintf,-1)
5407 FF(printf,-1)
5408 FF(getenv,-1)
5409 FF(floor,-1)
5410 /* needed by frapsvid.dll */
5411 {"strstr",-1,(char *)&strstr},
5412 {"qsort",-1,(void *)&qsort},
5413 FF(_EH_prolog,-1)
5414 FF(calloc,-1)
5415 {"ceil",-1,(void*)&ceil},
5416 /* needed by imagepower mjpeg2k */
5417 {"clock",-1,(void*)&clock},
5418 {"memchr",-1,(void*)&memchr},
5419 {"vfprintf",-1,(void*)&vfprintf},
5420 // {"realloc",-1,(void*)&realloc},
5421 FF(realloc,-1)
5422 {"puts",-1,(void*)&puts}
5424 struct exports exp_winmm[]={
5425 FF(GetDriverModuleHandle, -1)
5426 FF(timeGetTime, -1)
5427 FF(DefDriverProc, -1)
5428 FF(OpenDriverA, -1)
5429 FF(OpenDriver, -1)
5430 FF(timeGetDevCaps, -1)
5431 FF(timeBeginPeriod, -1)
5432 #ifdef CONFIG_QTX_CODECS
5433 FF(timeEndPeriod, -1)
5434 FF(waveOutGetNumDevs, -1)
5435 #endif
5437 struct exports exp_psapi[]={
5438 FF(GetModuleBaseNameA, -1)
5440 struct exports exp_user32[]={
5441 FF(LoadIconA,-1)
5442 FF(LoadStringA, -1)
5443 FF(wsprintfA, -1)
5444 FF(GetDC, -1)
5445 FF(GetDesktopWindow, -1)
5446 FF(ReleaseDC, -1)
5447 FF(IsRectEmpty, -1)
5448 FF(LoadCursorA,-1)
5449 FF(SetCursor,-1)
5450 FF(GetCursorPos,-1)
5451 #ifdef CONFIG_QTX_CODECS
5452 FF(ShowCursor,-1)
5453 #endif
5454 FF(RegisterWindowMessageA,-1)
5455 FF(GetSystemMetrics,-1)
5456 FF(GetSysColor,-1)
5457 FF(GetSysColorBrush,-1)
5458 FF(GetWindowDC, -1)
5459 FF(DrawTextA, -1)
5460 FF(MessageBoxA, -1)
5461 FF(RegisterClassA, -1)
5462 FF(UnregisterClassA, -1)
5463 #ifdef CONFIG_QTX_CODECS
5464 FF(GetWindowRect, -1)
5465 FF(MonitorFromWindow, -1)
5466 FF(MonitorFromRect, -1)
5467 FF(MonitorFromPoint, -1)
5468 FF(EnumDisplayMonitors, -1)
5469 FF(GetMonitorInfoA, -1)
5470 FF(EnumDisplayDevicesA, -1)
5471 FF(GetClientRect, -1)
5472 FF(ClientToScreen, -1)
5473 FF(IsWindowVisible, -1)
5474 FF(GetActiveWindow, -1)
5475 FF(GetClassNameA, -1)
5476 FF(GetClassInfoA, -1)
5477 FF(GetWindowLongA, -1)
5478 FF(EnumWindows, -1)
5479 FF(GetWindowThreadProcessId, -1)
5480 FF(CreateWindowExA, -1)
5481 #endif
5482 FF(MessageBeep, -1)
5483 FF(DialogBoxParamA, -1)
5484 FF(RegisterClipboardFormatA, -1)
5485 FF(CharNextA, -1)
5486 FF(EnumDisplaySettingsA, -1)
5488 struct exports exp_advapi32[]={
5489 FF(RegCloseKey, -1)
5490 FF(RegCreateKeyA, -1)
5491 FF(RegCreateKeyExA, -1)
5492 FF(RegEnumKeyExA, -1)
5493 FF(RegEnumValueA, -1)
5494 FF(RegOpenKeyA, -1)
5495 FF(RegOpenKeyExA, -1)
5496 FF(RegQueryValueExA, -1)
5497 FF(RegSetValueExA, -1)
5498 FF(RegQueryInfoKeyA, -1)
5500 struct exports exp_gdi32[]={
5501 FF(CreateCompatibleDC, -1)
5502 FF(CreateFontA, -1)
5503 FF(DeleteDC, -1)
5504 FF(DeleteObject, -1)
5505 FF(GetDeviceCaps, -1)
5506 FF(GetSystemPaletteEntries, -1)
5507 #ifdef CONFIG_QTX_CODECS
5508 FF(CreatePalette, -1)
5509 FF(GetObjectA, -1)
5510 FF(CreateRectRgn, -1)
5511 #endif
5513 struct exports exp_version[]={
5514 FF(GetFileVersionInfoSizeA, -1)
5516 struct exports exp_ole32[]={
5517 FF(CoCreateFreeThreadedMarshaler,-1)
5518 FF(CoCreateInstance, -1)
5519 FF(CoInitialize, -1)
5520 FF(CoInitializeEx, -1)
5521 FF(CoUninitialize, -1)
5522 FF(CoTaskMemAlloc, -1)
5523 FF(CoTaskMemFree, -1)
5524 FF(StringFromGUID2, -1)
5525 FF(PropVariantClear, -1)
5527 // do we really need crtdll ???
5528 // msvcrt is the correct place probably...
5529 struct exports exp_crtdll[]={
5530 FF(memcpy, -1)
5531 FF(wcscpy, -1)
5533 struct exports exp_comctl32[]={
5534 FF(StringFromGUID2, -1)
5535 FF(InitCommonControls, 17)
5536 #ifdef CONFIG_QTX_CODECS
5537 FF(CreateUpDownControl, 16)
5538 #endif
5540 struct exports exp_wsock32[]={
5541 FF(htonl,8)
5542 FF(ntohl,14)
5544 struct exports exp_msdmo[]={
5545 FF(memcpy, -1) // just test
5546 FF(MoCopyMediaType, -1)
5547 FF(MoCreateMediaType, -1)
5548 FF(MoDeleteMediaType, -1)
5549 FF(MoDuplicateMediaType, -1)
5550 FF(MoFreeMediaType, -1)
5551 FF(MoInitMediaType, -1)
5553 struct exports exp_oleaut32[]={
5554 FF(SysAllocStringLen, 4)
5555 FF(SysFreeString, 6)
5556 FF(VariantInit, 8)
5557 #ifdef CONFIG_QTX_CODECS
5558 FF(SysStringByteLen, 149)
5559 #endif
5562 /* realplayer8:
5563 DLL Name: PNCRT.dll
5564 vma: Hint/Ord Member-Name
5565 22ff4 615 free
5566 2302e 250 _ftol
5567 22fea 666 malloc
5568 2303e 609 fprintf
5569 2305e 167 _adjust_fdiv
5570 23052 280 _initterm
5572 22ffc 176 _beginthreadex
5573 23036 284 _iob
5574 2300e 85 __CxxFrameHandler
5575 23022 411 _purecall
5577 #ifdef REALPLAYER
5578 struct exports exp_pncrt[]={
5579 FF(malloc, -1) // just test
5580 FF(free, -1) // just test
5581 FF(fprintf, -1) // just test
5582 {"_adjust_fdiv", -1, (void*)&_adjust_fdiv},
5583 FF(_ftol,-1)
5584 FF(_initterm, -1)
5585 {"??3@YAXPAX@Z", -1, expdelete},
5586 {"??2@YAPAXI@Z", -1, expnew},
5587 FF(__dllonexit, -1)
5588 FF(strncpy, -1)
5589 FF(_CIpow,-1)
5590 FF(calloc,-1)
5591 FF(memmove, -1)
5592 FF(ldexp, -1)
5593 FF(frexp, -1)
5595 #endif
5597 #ifdef CONFIG_QTX_CODECS
5598 struct exports exp_ddraw[]={
5599 FF(DirectDrawCreate, -1)
5601 #endif
5603 struct exports exp_comdlg32[]={
5604 FF(GetOpenFileNameA, -1)
5607 struct exports exp_shlwapi[]={
5608 FF(PathFindExtensionA, -1)
5609 FF(PathFindFileNameA, -1)
5612 struct exports exp_msvcr80[]={
5613 FF(_CIpow,-1)
5614 FF(_CIsin,-1)
5615 FF(_CIcos,-1)
5616 FF(_CIsqrt,-1)
5617 FF(memset,-1)
5618 FF(_initterm_e, -1)
5619 FF(_initterm, -1)
5620 FF(_decode_pointer, -1)
5621 /* needed by KGV1-VFW.dll */
5622 {"??2@YAPAXI@Z", -1, expnew},
5623 {"??3@YAXPAX@Z", -1, expdelete}
5626 struct exports exp_msvcp60[]={
5627 {"??0_Lockit@std@@QAE@XZ", -1, exp_0Lockit_dummy},
5628 {"??1_Lockit@std@@QAE@XZ", -1, exp_1Lockit_dummy}
5631 #define LL(X) \
5632 {#X".dll", sizeof(exp_##X)/sizeof(struct exports), exp_##X},
5634 struct libs libraries[]={
5635 LL(kernel32)
5636 LL(msvcrt)
5637 LL(winmm)
5638 LL(psapi)
5639 LL(user32)
5640 LL(advapi32)
5641 LL(gdi32)
5642 LL(version)
5643 LL(ole32)
5644 LL(oleaut32)
5645 LL(crtdll)
5646 LL(comctl32)
5647 LL(wsock32)
5648 LL(msdmo)
5649 #ifdef REALPLAYER
5650 LL(pncrt)
5651 #endif
5652 #ifdef CONFIG_QTX_CODECS
5653 LL(ddraw)
5654 #endif
5655 LL(comdlg32)
5656 LL(shlwapi)
5657 LL(msvcr80)
5658 LL(msvcp60)
5661 static WIN_BOOL WINAPI ext_stubs(void)
5663 // NOTE! these magic values will be replaced at runtime, make sure
5664 // add_stub can still find them if you change them.
5665 volatile int idx = 0x0deadabc;
5666 // make sure gcc does not do eip-relative call or something like that
5667 void (* volatile my_printf)(char *, char *) = (void *)0xdeadfbcd;
5668 my_printf("Called unk_%s\n", export_names[idx]);
5669 return 0;
5672 #define MAX_STUB_SIZE 0x60
5673 #define MAX_NUM_STUBS 200
5674 static int pos=0;
5675 static char *extcode = NULL;
5677 static void* add_stub(void)
5679 int i;
5680 int found = 0;
5681 // generated code in runtime!
5682 char* answ;
5683 if (!extcode)
5684 extcode = mmap_anon(NULL, MAX_NUM_STUBS * MAX_STUB_SIZE,
5685 PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE, 0);
5686 answ = extcode + pos * MAX_STUB_SIZE;
5687 if (pos >= MAX_NUM_STUBS) {
5688 printf("too many stubs, expect crash\n");
5689 return NULL;
5691 memcpy(answ, ext_stubs, MAX_STUB_SIZE);
5692 for (i = 0; i < MAX_STUB_SIZE - 3; i++) {
5693 int *magic = (int *)(answ + i);
5694 if (*magic == 0x0deadabc) {
5695 *magic = pos;
5696 found |= 1;
5698 if (*magic == 0xdeadfbcd) {
5699 *magic = (intptr_t)printf;
5700 found |= 2;
5703 if (found != 3) {
5704 printf("magic code not found in ext_subs, expect crash\n");
5705 return NULL;
5707 pos++;
5708 return (void*)answ;
5711 void* LookupExternal(const char* library, int ordinal)
5713 int i,j;
5714 if(library==0)
5716 printf("ERROR: library=0\n");
5717 return (void*)ext_unknown;
5719 // printf("%x %x\n", &unk_exp1, &unk_exp2);
5721 dbgprintf("External func %s:%d\n", library, ordinal);
5723 for(i=0; i<sizeof(libraries)/sizeof(struct libs); i++)
5725 if(strcasecmp(library, libraries[i].name))
5726 continue;
5727 for(j=0; j<libraries[i].length; j++)
5729 if(ordinal!=libraries[i].exps[j].id)
5730 continue;
5731 //printf("Hit: 0x%p\n", libraries[i].exps[j].func);
5732 return libraries[i].exps[j].func;
5736 #ifndef LOADLIB_TRY_NATIVE
5737 /* hack for truespeech and vssh264*/
5738 if (!strcmp(library, "tsd32.dll") || !strcmp(library,"vssh264dec.dll") || !strcmp(library,"LCMW2.dll") || !strcmp(library,"VDODEC32.dll"))
5739 #endif
5740 /* ok, this is a hack, and a big memory leak. should be fixed. - alex */
5742 int hand;
5743 WINE_MODREF *wm;
5744 void *func;
5746 hand = LoadLibraryA(library);
5747 if (!hand)
5748 goto no_dll;
5749 wm = MODULE32_LookupHMODULE(hand);
5750 if (!wm)
5752 FreeLibrary(hand);
5753 goto no_dll;
5755 func = PE_FindExportedFunction(wm, (LPCSTR) ordinal, 0);
5756 if (!func)
5758 printf("No such ordinal in external dll\n");
5759 FreeLibrary((int)hand);
5760 goto no_dll;
5763 printf("External dll loaded (offset: 0x%x, func: %p)\n",
5764 hand, func);
5765 return func;
5768 no_dll:
5769 if(pos>150)return 0;
5770 snprintf(export_names[pos], sizeof(export_names[pos]), "%s:%d", library, ordinal);
5771 return add_stub();
5774 void* LookupExternalByName(const char* library, const char* name)
5776 int i,j;
5777 // return (void*)ext_unknown;
5778 if(library==0)
5780 printf("ERROR: library=0\n");
5781 return (void*)ext_unknown;
5783 if((unsigned long)name<=0xffff)
5785 return LookupExternal(library, (int)name);
5787 dbgprintf("External func %s:%s\n", library, name);
5788 for(i=0; i<sizeof(libraries)/sizeof(struct libs); i++)
5790 if(strcasecmp(library, libraries[i].name))
5791 continue;
5792 for(j=0; j<libraries[i].length; j++)
5794 if(strcmp(name, libraries[i].exps[j].name))
5795 continue;
5796 if((unsigned int)(libraries[i].exps[j].func) == -1)
5797 return NULL; //undefined func
5798 // printf("Hit: 0x%08X\n", libraries[i].exps[j].func);
5799 return libraries[i].exps[j].func;
5803 #ifndef LOADLIB_TRY_NATIVE
5804 /* hack for vss h264 */
5805 if (!strcmp(library,"vssh264core.dll") || !strcmp(library,"3ivx.dll"))
5806 #endif
5807 /* ok, this is a hack, and a big memory leak. should be fixed. - alex */
5809 int hand;
5810 WINE_MODREF *wm;
5811 void *func;
5813 hand = LoadLibraryA(library);
5814 if (!hand)
5815 goto no_dll_byname;
5816 wm = MODULE32_LookupHMODULE(hand);
5817 if (!wm)
5819 FreeLibrary(hand);
5820 goto no_dll_byname;
5822 func = PE_FindExportedFunction(wm, name, 0);
5823 if (!func)
5825 printf("No such name in external dll\n");
5826 FreeLibrary((int)hand);
5827 goto no_dll_byname;
5830 printf("External dll loaded (offset: 0x%x, func: %p)\n",
5831 hand, func);
5832 return func;
5835 no_dll_byname:
5836 if(pos>150)return 0;// to many symbols
5837 snprintf(export_names[pos], sizeof(export_names[pos]), "%s", name);
5838 return add_stub();
5841 void my_garbagecollection(void)
5843 #ifdef GARBAGE
5844 int unfree = 0, unfreecnt = 0;
5846 int max_fatal = 8;
5847 free_registry();
5848 while (last_alloc)
5850 alloc_header* mem = last_alloc + 1;
5851 unfree += my_size(mem);
5852 unfreecnt++;
5853 if (my_release(mem) != 0)
5854 // avoid endless loop when memory is trashed
5855 if (--max_fatal < 0)
5856 break;
5858 dbgprintf("Total Unfree %d bytes cnt %d [%p,%d]\n",unfree, unfreecnt, last_alloc, alccnt);
5859 #endif
5860 g_tls = NULL;
5861 pthread_mutex_lock(&list_lock);
5862 list = NULL;
5863 pthread_mutex_unlock(&list_lock);