dvdcss: Handle failing ioctls more gracefully
[mplayer/glamo.git] / loader / win32.c
blob71c46e70fb394252ecf4b20c5514b77cc3597898
1 /***********************************************************
3 Win32 emulation code. Functions that emulate
4 responses from corresponding Win32 API calls.
5 Since we are not going to be able to load
6 virtually any DLL, we can only implement this
7 much, adding needed functions with each new codec.
9 Basic principle of implementation: it's not good
10 for DLL to know too much about its environment.
12 ************************************************************/
15 * Modified for use with MPlayer, detailed changelog at
16 * http://svn.mplayerhq.hu/mplayer/trunk/
19 #include "config.h"
20 #include "mangle.h"
22 #define REALPLAYER
23 //#define LOADLIB_TRY_NATIVE
25 /* Hack to make sure the correct function declaration in com.h is used when
26 * this file is built for the test applications with WIN32_LOADER disabled. */
27 #ifndef WIN32_LOADER
28 #define WIN32_LOADER
29 #endif
31 #ifdef CONFIG_QTX_CODECS
32 #define PSEUDO_SCREEN_WIDTH /*640*/800
33 #define PSEUDO_SCREEN_HEIGHT /*480*/600
34 #endif
36 #include "wine/winbase.h"
37 #include "wine/winreg.h"
38 #include "wine/winnt.h"
39 #include "wine/winerror.h"
40 #include "wine/debugtools.h"
41 #include "wine/module.h"
42 #include "wine/winuser.h"
43 #include "wine/objbase.h"
45 #include <stdio.h>
46 #include "win32.h"
48 #include "registry.h"
49 #include "loader.h"
50 #include "com.h"
51 #include "ext.h"
52 #include "path.h"
54 #include <stdlib.h>
55 #include <assert.h>
56 #include <stdarg.h>
57 #include <ctype.h>
58 #include <pthread.h>
59 #include <errno.h>
60 #include <time.h>
61 #include <math.h>
62 #include <unistd.h>
63 #include <fcntl.h>
64 #include <sys/types.h>
65 #include <dirent.h>
66 #include <sys/time.h>
67 #include <sys/stat.h>
68 #ifdef HAVE_KSTAT
69 #include <kstat.h>
70 #endif
72 #ifdef HAVE_SYS_MMAN_H
73 #include <sys/mman.h>
74 #else
75 #include "osdep/mmap.h"
76 #endif
77 #include "osdep/mmap_anon.h"
78 #include "libavutil/avstring.h"
80 static void do_cpuid(unsigned int ax, unsigned int *regs)
82 __asm__ volatile
84 "pushl %%ebx; pushl %%ecx; pushl %%edx;"
85 ".byte 0x0f, 0xa2;"
86 "movl %%eax, (%2);"
87 "movl %%ebx, 4(%2);"
88 "movl %%ecx, 8(%2);"
89 "movl %%edx, 12(%2);"
90 "popl %%edx; popl %%ecx; popl %%ebx;"
91 : "=a" (ax)
92 : "0" (ax), "S" (regs)
95 static unsigned int c_localcount_tsc(void)
97 int a;
98 __asm__ volatile
100 "rdtsc\n\t"
101 :"=a"(a)
103 :"edx"
105 return a;
107 static void c_longcount_tsc(long long* z)
109 __asm__ volatile
111 "pushl %%ebx\n\t"
112 "movl %%eax, %%ebx\n\t"
113 "rdtsc\n\t"
114 "movl %%eax, 0(%%ebx)\n\t"
115 "movl %%edx, 4(%%ebx)\n\t"
116 "popl %%ebx\n\t"
117 ::"a"(z)
118 :"edx"
121 static unsigned int c_localcount_notsc(void)
123 struct timeval tv;
124 unsigned limit=~0;
125 limit/=1000000;
126 gettimeofday(&tv, 0);
127 return limit*tv.tv_usec;
129 static void c_longcount_notsc(long long* z)
131 struct timeval tv;
132 unsigned long long result;
133 unsigned limit=~0;
134 if(!z)return;
135 limit/=1000000;
136 gettimeofday(&tv, 0);
137 result=tv.tv_sec;
138 result<<=32;
139 result+=limit*tv.tv_usec;
140 *z=result;
142 static unsigned int localcount_stub(void);
143 static void longcount_stub(long long*);
144 static unsigned int (*localcount)()=localcount_stub;
145 static void (*longcount)(long long*)=longcount_stub;
147 static pthread_mutex_t memmut = PTHREAD_MUTEX_INITIALIZER;
149 static unsigned int localcount_stub(void)
151 unsigned int regs[4];
152 do_cpuid(1, regs);
153 if ((regs[3] & 0x00000010) != 0)
155 localcount=c_localcount_tsc;
156 longcount=c_longcount_tsc;
158 else
160 localcount=c_localcount_notsc;
161 longcount=c_longcount_notsc;
163 return localcount();
165 static void longcount_stub(long long* z)
167 unsigned int regs[4];
168 do_cpuid(1, regs);
169 if ((regs[3] & 0x00000010) != 0)
171 localcount=c_localcount_tsc;
172 longcount=c_longcount_tsc;
174 else
176 localcount=c_localcount_notsc;
177 longcount=c_longcount_notsc;
179 longcount(z);
182 #include "mp_msg.h"
183 int LOADER_DEBUG=1; // active only if compiled with -DDETAILED_OUT
184 //#define DETAILED_OUT
185 static inline void dbgprintf(char* fmt, ...)
187 #ifdef DETAILED_OUT
188 if(LOADER_DEBUG)
190 FILE* f;
191 va_list va;
192 va_start(va, fmt);
193 f=fopen("./log", "a");
194 vprintf(fmt, va);
195 fflush(stdout);
196 if(f)
198 vfprintf(f, fmt, va);
199 fsync(fileno(f));
200 fclose(f);
202 va_end(va);
204 #endif
205 if ( mp_msg_test(MSGT_WIN32,MSGL_DBG3) )
207 va_list va;
209 va_start(va, fmt);
210 vprintf(fmt, va);
211 // mp_dbg(MSGT_WIN32, MSGL_DBG3, fmt, va);
212 va_end(va);
213 fflush(stdout);
218 char export_names[300][32]={
219 "name1",
220 //"name2",
221 //"name3"
223 //#define min(x,y) ((x)<(y)?(x):(y))
225 void destroy_event(void* event);
227 struct th_list_t;
228 typedef struct th_list_t{
229 int id;
230 void* thread;
231 struct th_list_t* next;
232 struct th_list_t* prev;
233 } th_list;
236 // have to be cleared by GARBAGE COLLECTOR
237 //static unsigned char* heap=NULL;
238 //static int heap_counter=0;
239 static tls_t* g_tls=NULL;
240 static th_list* list=NULL;
241 static pthread_mutex_t list_lock = PTHREAD_MUTEX_INITIALIZER;
243 #if 0
244 static void test_heap(void)
246 int offset=0;
247 if(heap==0)
248 return;
249 while(offset<heap_counter)
251 if(*(int*)(heap+offset)!=0x433476)
253 printf("Heap corruption at address %d\n", offset);
254 return;
256 offset+=8+*(int*)(heap+offset+4);
258 for(;offset<min(offset+1000, 20000000); offset++)
259 if(heap[offset]!=0xCC)
261 printf("Free heap corruption at address %d\n", offset);
264 #endif
265 #undef MEMORY_DEBUG
267 #ifdef MEMORY_DEBUG
269 static void* my_mreq(int size, int to_zero)
271 static int test=0;
272 test++;
273 if(test%10==0)printf("Memory: %d bytes allocated\n", heap_counter);
274 // test_heap();
275 if(heap==NULL)
277 heap=malloc(20000000);
278 memset(heap, 0xCC,20000000);
280 if(heap==0)
282 printf("No enough memory\n");
283 return 0;
285 if(heap_counter+size>20000000)
287 printf("No enough memory\n");
288 return 0;
290 *(int*)(heap+heap_counter)=0x433476;
291 heap_counter+=4;
292 *(int*)(heap+heap_counter)=size;
293 heap_counter+=4;
294 printf("Allocated %d bytes of memory: sys %d, user %d-%d\n", size, heap_counter-8, heap_counter, heap_counter+size);
295 if(to_zero)
296 memset(heap+heap_counter, 0, size);
297 else
298 memset(heap+heap_counter, 0xcc, size); // make crash reproducable
299 heap_counter+=size;
300 return heap+heap_counter-size;
302 static int my_release(char* memory)
304 // test_heap();
305 if(memory==NULL)
307 printf("ERROR: free(0)\n");
308 return 0;
310 if(*(int*)(memory-8)!=0x433476)
312 printf("MEMORY CORRUPTION !!!!!!!!!!!!!!!!!!!\n");
313 return 0;
315 printf("Freed %d bytes of memory\n", *(int*)(memory-4));
316 // memset(memory-8, *(int*)(memory-4), 0xCC);
317 return 0;
320 #else
321 #define GARBAGE
322 typedef struct alloc_header_t alloc_header;
323 struct alloc_header_t
325 // let's keep allocated data 16 byte aligned
326 alloc_header* prev;
327 alloc_header* next;
328 long deadbeef;
329 long size;
330 long type;
331 long reserved1;
332 long reserved2;
333 long reserved3;
336 #ifdef GARBAGE
337 static alloc_header* last_alloc = NULL;
338 static int alccnt = 0;
339 #endif
341 #define AREATYPE_CLIENT 0
342 #define AREATYPE_EVENT 1
343 #define AREATYPE_MUTEX 2
344 #define AREATYPE_COND 3
345 #define AREATYPE_CRITSECT 4
347 /* -- critical sections -- */
348 struct CRITSECT
350 pthread_t id;
351 pthread_mutex_t mutex;
352 pthread_cond_t unlocked;
353 int lock_count;
354 long deadbeef;
357 void* mreq_private(int size, int to_zero, int type);
358 void* mreq_private(int size, int to_zero, int type)
360 int nsize = size + sizeof(alloc_header);
361 alloc_header* header = malloc(nsize);
362 if (!header)
363 return 0;
364 if (to_zero)
365 memset(header, 0, nsize);
366 #ifdef GARBAGE
367 pthread_mutex_lock(&memmut);
368 if (last_alloc)
370 last_alloc->next = header; /* set next */
373 header->prev = last_alloc;
374 header->next = 0;
375 last_alloc = header;
376 alccnt++;
377 pthread_mutex_unlock(&memmut);
378 #endif
379 header->deadbeef = 0xdeadbeef;
380 header->size = size;
381 header->type = type;
383 //if (alccnt < 40000) printf("MY_REQ: %p\t%d t:%d (cnt:%d)\n", header, size, type, alccnt);
384 return header + 1;
387 static int my_release(void* memory)
389 alloc_header* header = (alloc_header*) memory - 1;
390 #ifdef GARBAGE
391 alloc_header* prevmem;
392 alloc_header* nextmem;
394 if (memory == 0)
395 return 0;
397 if (header->deadbeef != (long) 0xdeadbeef)
399 dbgprintf("FATAL releasing corrupted memory! %p 0x%lx (%d)\n", header, header->deadbeef, alccnt);
400 return 0;
403 pthread_mutex_lock(&memmut);
405 switch(header->type)
407 case AREATYPE_EVENT:
408 destroy_event(memory);
409 break;
410 case AREATYPE_COND:
411 pthread_cond_destroy((pthread_cond_t*)memory);
412 break;
413 case AREATYPE_MUTEX:
414 pthread_mutex_destroy((pthread_mutex_t*)memory);
415 break;
416 case AREATYPE_CRITSECT:
417 pthread_mutex_destroy(&((struct CRITSECT*)memory)->mutex);
418 break;
419 default:
420 //memset(memory, 0xcc, header->size);
424 header->deadbeef = 0;
425 prevmem = header->prev;
426 nextmem = header->next;
428 if (prevmem)
429 prevmem->next = nextmem;
430 if (nextmem)
431 nextmem->prev = prevmem;
433 if (header == last_alloc)
434 last_alloc = prevmem;
436 alccnt--;
438 pthread_mutex_unlock(&memmut);
440 //if (alccnt < 40000) printf("MY_RELEASE: %p\t%ld (%d)\n", header, header->size, alccnt);
441 #else
442 if (memory == 0)
443 return 0;
444 #endif
445 //memset(header + 1, 0xcc, header->size);
446 free(header);
447 return 0;
449 #endif
451 static inline void* my_mreq(int size, int to_zero)
453 return mreq_private(size, to_zero, AREATYPE_CLIENT);
456 static int my_size(void* memory)
458 if(!memory) return 0;
459 return ((alloc_header*)memory)[-1].size;
462 static void* my_realloc(void* memory, int size)
464 void *ans = memory;
465 int osize;
466 if (memory == NULL)
467 return my_mreq(size, 0);
468 osize = my_size(memory);
469 if (osize < size)
471 ans = my_mreq(size, 0);
472 memcpy(ans, memory, osize);
473 my_release(memory);
475 return ans;
480 * WINE API - native implementation for several win32 libraries
484 static int WINAPI ext_unknown(void)
486 printf("Unknown func called\n");
487 return 0;
490 static int WINAPI expGetVolumeInformationA( const char *root, char *label,
491 unsigned int label_len, unsigned int *serial,
492 unsigned int *filename_len,unsigned int *flags,
493 char *fsname, unsigned int fsname_len )
495 dbgprintf("GetVolumeInformationA( %s, 0x%x, %ld, 0x%x, 0x%x, 0x%x, 0x%x, %ld) => 1\n",
496 root,label,label_len,serial,filename_len,flags,fsname,fsname_len);
497 //hack Do not return any real data - do nothing
498 return 1;
501 static unsigned int WINAPI expGetDriveTypeA( const char *root )
503 dbgprintf("GetDriveTypeA( %s ) => %d\n",root,DRIVE_FIXED);
504 // hack return as Fixed Drive Type
505 return DRIVE_FIXED;
508 static unsigned int WINAPI expGetLogicalDriveStringsA( unsigned int len, char *buffer )
510 dbgprintf("GetLogicalDriveStringsA(%d, 0x%x) => 4\n",len,buffer);
511 // hack only have one drive c:\ in this hack
512 *buffer++='c';
513 *buffer++=':';
514 *buffer++='\\';
515 *buffer++='\0';
516 *buffer= '\0';
517 return 4; // 1 drive * 4 bytes (includes null)
521 static int WINAPI expIsBadWritePtr(void* ptr, unsigned int count)
523 int result = (count == 0 || ptr != 0) ? 0 : 1;
524 dbgprintf("IsBadWritePtr(0x%x, 0x%x) => %d\n", ptr, count, result);
525 return result;
527 static int WINAPI expIsBadReadPtr(void* ptr, unsigned int count)
529 int result = (count == 0 || ptr != 0) ? 0 : 1;
530 dbgprintf("IsBadReadPtr(0x%x, 0x%x) => %d\n", ptr, count, result);
531 return result;
533 static int WINAPI expDisableThreadLibraryCalls(int module)
535 dbgprintf("DisableThreadLibraryCalls(0x%x) => 0\n", module);
536 return 0;
539 static HMODULE WINAPI expGetDriverModuleHandle(DRVR* pdrv)
541 HMODULE result;
542 if (pdrv==NULL)
543 result=0;
544 else
545 result=pdrv->hDriverModule;
546 dbgprintf("GetDriverModuleHandle(%p) => %p\n", pdrv, result);
547 return result;
550 #define MODULE_HANDLE_kernel32 ((HMODULE)0x120)
551 #define MODULE_HANDLE_user32 ((HMODULE)0x121)
552 #ifdef CONFIG_QTX_CODECS
553 #define MODULE_HANDLE_wininet ((HMODULE)0x122)
554 #define MODULE_HANDLE_ddraw ((HMODULE)0x123)
555 #define MODULE_HANDLE_advapi32 ((HMODULE)0x124)
556 #endif
557 #define MODULE_HANDLE_comdlg32 ((HMODULE)0x125)
558 #define MODULE_HANDLE_msvcrt ((HMODULE)0x126)
559 #define MODULE_HANDLE_ole32 ((HMODULE)0x127)
560 #define MODULE_HANDLE_winmm ((HMODULE)0x128)
561 #define MODULE_HANDLE_psapi ((HMODULE)0x129)
563 // Fake PE header, since some software (and the Microsoft CRT v8 and newer)
564 // assume GetModuleHandle(NULL) returns a pointer to a PE header.
565 // We simulate a very simple header with only one section.
567 // NOTE: If you have a section called .mixcrt, the Microsoft CRT will assume
568 // it's running in a POSIX binary, and stop using EncodePointer/DecodePointer.
569 static const struct {
570 IMAGE_DOS_HEADER doshdr;
571 IMAGE_NT_HEADERS nthdr;
572 IMAGE_SECTION_HEADER opthdr;
573 } __attribute__((__packed__)) mp_exe = {
574 .doshdr.e_lfanew = sizeof(IMAGE_DOS_HEADER),
575 .nthdr.FileHeader.NumberOfSections = 1,
576 .nthdr.FileHeader.SizeOfOptionalHeader =
577 sizeof(IMAGE_NT_HEADERS) - FIELD_OFFSET(IMAGE_NT_HEADERS, OptionalHeader), /* 0xe0 */
578 .opthdr.Name = ".text"
581 static HMODULE WINAPI expGetModuleHandleA(const char* name)
583 WINE_MODREF* wm;
584 HMODULE result;
585 if(!name)
586 result=(HMODULE)&mp_exe.doshdr;
587 else
589 wm=MODULE_FindModule(name);
590 if(wm==0)result=0;
591 else
592 result=(HMODULE)(wm->module);
594 if(!result)
596 if(name && (strcasecmp(name, "kernel32")==0 || !strcasecmp(name, "kernel32.dll")))
597 result=MODULE_HANDLE_kernel32;
598 #ifdef CONFIG_QTX_CODECS
599 if(name && strcasecmp(name, "user32")==0)
600 result=MODULE_HANDLE_user32;
601 #endif
603 dbgprintf("GetModuleHandleA('%s') => 0x%x\n", name, result);
604 return result;
607 static HMODULE WINAPI expGetModuleHandleW(const uint16_t* name)
609 char aname[256];
610 int pos = 0;
611 while (*name) {
612 if (*name > 256 || pos >= sizeof(aname) - 1)
613 return NULL;
614 aname[pos++] = *name++;
616 aname[pos] = 0;
617 return expGetModuleHandleA(aname);
620 static void* WINAPI expCreateThread(void* pSecAttr, long dwStackSize,
621 void* lpStartAddress, void* lpParameter,
622 long dwFlags, long* dwThreadId)
624 pthread_t *pth;
625 // printf("CreateThread:");
626 pth = (pthread_t*) my_mreq(sizeof(pthread_t), 0);
627 pthread_create(pth, NULL, (void*(*)(void*))lpStartAddress, lpParameter);
628 if(dwFlags)
629 printf( "WARNING: CreateThread flags not supported\n");
630 if(dwThreadId)
631 *dwThreadId=(long)pth;
632 pthread_mutex_lock(&list_lock);
633 if(list==NULL)
635 list=my_mreq(sizeof(th_list), 1);
636 list->next=list->prev=NULL;
638 else
640 list->next=my_mreq(sizeof(th_list), 0);
641 list->next->prev=list;
642 list->next->next=NULL;
643 list=list->next;
645 list->thread=pth;
646 pthread_mutex_unlock(&list_lock);
647 dbgprintf("CreateThread(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x) => 0x%x\n",
648 pSecAttr, dwStackSize, lpStartAddress, lpParameter, dwFlags, dwThreadId, pth);
649 return pth;
652 static DWORD WINAPI expResumeThread(HANDLE hThread)
654 int ret = 1;
655 dbgprintf("ResumeThread(0x%x) => 0x%x\n", hThread, ret);
656 return ret;
659 struct mutex_list_t;
661 struct mutex_list_t
663 char type;
664 pthread_mutex_t *pm;
665 pthread_cond_t *pc;
666 char state;
667 char reset;
668 char name[128];
669 int semaphore;
670 int lock_count;
671 pthread_t owner;
672 struct mutex_list_t* next;
673 struct mutex_list_t* prev;
675 typedef struct mutex_list_t mutex_list;
676 static mutex_list* mlist=NULL;
677 static pthread_mutex_t mlist_lock = PTHREAD_MUTEX_INITIALIZER;
679 void destroy_event(void* event)
681 pthread_mutex_lock(&mlist_lock);
682 mutex_list* pp=mlist;
683 // printf("garbage collector: destroy_event(%x)\n", event);
684 while(pp)
686 if(pp==(mutex_list*)event)
688 if(pp->next)
689 pp->next->prev=pp->prev;
690 if(pp->prev)
691 pp->prev->next=pp->next;
692 if(mlist==(mutex_list*)event)
693 mlist=mlist->prev;
695 pp=mlist;
696 while(pp)
698 printf("%x => ", pp);
699 pp=pp->prev;
701 printf("0\n");
703 pthread_mutex_unlock(&mlist_lock);
704 return;
706 pp=pp->prev;
708 pthread_mutex_unlock(&mlist_lock);
711 static void* WINAPI expCreateEventA(void* pSecAttr, char bManualReset,
712 char bInitialState, const char* name)
714 pthread_mutex_t *pm;
715 pthread_cond_t *pc;
716 void *ret;
718 mutex_list* pp;
719 pp=mlist;
720 while(pp)
722 printf("%x => ", pp);
723 pp=pp->prev;
725 printf("0\n");
727 pthread_mutex_lock(&mlist_lock);
728 if(mlist!=NULL)
730 mutex_list* pp=mlist;
731 if(name!=NULL)
734 if((strcmp(pp->name, name)==0) && (pp->type==0))
736 dbgprintf("CreateEventA(0x%x, 0x%x, 0x%x, 0x%x='%s') => 0x%x\n",
737 pSecAttr, bManualReset, bInitialState, name, name, pp->pm);
738 pthread_mutex_unlock(&mlist_lock);
739 return pp->pm;
741 }while((pp=pp->prev) != NULL);
743 pm=mreq_private(sizeof(pthread_mutex_t), 0, AREATYPE_MUTEX);
744 pthread_mutex_init(pm, NULL);
745 pc=mreq_private(sizeof(pthread_cond_t), 0, AREATYPE_COND);
746 pthread_cond_init(pc, NULL);
747 if(mlist==NULL)
749 mlist=mreq_private(sizeof(mutex_list), 00, AREATYPE_EVENT);
750 mlist->next=mlist->prev=NULL;
752 else
754 mlist->next=mreq_private(sizeof(mutex_list), 00, AREATYPE_EVENT);
755 mlist->next->prev=mlist;
756 mlist->next->next=NULL;
757 mlist=mlist->next;
759 mlist->type=0; /* Type Event */
760 mlist->pm=pm;
761 mlist->pc=pc;
762 mlist->state=bInitialState;
763 mlist->reset=!bManualReset;
764 if(name)
765 strncpy(mlist->name, name, 127);
766 else
767 mlist->name[0]=0;
768 if(pm==NULL)
769 dbgprintf("ERROR::: CreateEventA failure\n");
771 if(bInitialState)
772 pthread_mutex_lock(pm);
774 if(name)
775 dbgprintf("CreateEventA(0x%x, 0x%x, 0x%x, 0x%x='%s') => 0x%x\n",
776 pSecAttr, bManualReset, bInitialState, name, name, mlist);
777 else
778 dbgprintf("CreateEventA(0x%x, 0x%x, 0x%x, NULL) => 0x%x\n",
779 pSecAttr, bManualReset, bInitialState, mlist);
780 ret = mlist;
781 pthread_mutex_unlock(&mlist_lock);
782 return ret;
785 static void* WINAPI expCreateEventW(void* pSecAttr, char bManualReset,
786 char bInitialState, const WCHAR* name)
788 char ascii_name[256];
789 char *aname = NULL;
790 if (name) {
791 WideCharToMultiByte(65001, 0x0, name, -1, ascii_name, 256, NULL, NULL);
792 aname = ascii_name;
794 return expCreateEventA(pSecAttr, bManualReset, bInitialState, aname);
797 static void* WINAPI expSetEvent(void* event)
799 mutex_list *ml = (mutex_list *)event;
800 dbgprintf("SetEvent(%x) => 0x1\n", event);
801 pthread_mutex_lock(ml->pm);
802 if (ml->state == 0) {
803 ml->state = 1;
804 pthread_cond_signal(ml->pc);
806 pthread_mutex_unlock(ml->pm);
808 return (void *)1;
810 static void* WINAPI expResetEvent(void* event)
812 mutex_list *ml = (mutex_list *)event;
813 dbgprintf("ResetEvent(0x%x) => 0x1\n", event);
814 pthread_mutex_lock(ml->pm);
815 ml->state = 0;
816 pthread_mutex_unlock(ml->pm);
818 return (void *)1;
821 static void* WINAPI expWaitForSingleObject(void* object, int duration)
823 mutex_list *ml = (mutex_list *)object;
824 // FIXME FIXME FIXME - this value is sometime unititialize !!!
825 int ret = WAIT_FAILED;
826 mutex_list* pp;
827 th_list* tp;
828 if(object == (void*)0xcfcf9898)
831 From GetCurrentThread() documentation:
832 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.
834 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.
836 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.
838 dbgprintf("WaitForSingleObject(thread_handle) called\n");
839 return (void*)WAIT_FAILED;
841 dbgprintf("WaitForSingleObject(0x%x, duration %d) =>\n",object, duration);
843 // See if this is a thread.
844 pthread_mutex_lock(&list_lock);
845 tp=list;
846 while (tp && (tp->thread != object))
847 tp = tp->prev;
848 pthread_mutex_unlock(&list_lock);
849 if (tp) {
850 if (pthread_join(*(pthread_t*)object, NULL) == 0) {
851 return (void*)WAIT_OBJECT_0;
852 } else {
853 return (void*)WAIT_FAILED;
857 // loop below was slightly fixed - its used just for checking if
858 // this object really exists in our list
859 if (!ml)
860 return (void*) ret;
861 pthread_mutex_lock(&mlist_lock);
862 pp=mlist;
863 while (pp && (pp->pm != ml->pm))
864 pp = pp->prev;
865 pthread_mutex_unlock(&mlist_lock);
866 if (!pp) {
867 dbgprintf("WaitForSingleObject: NotFound\n");
868 return (void*)ret;
871 pthread_mutex_lock(ml->pm);
873 switch(ml->type) {
874 case 0: /* Event */
875 if (duration == 0) { /* Check Only */
876 if (ml->state == 1) ret = WAIT_OBJECT_0;
877 else ret = WAIT_FAILED;
879 if (duration == -1) { /* INFINITE */
880 if (ml->state == 0)
881 pthread_cond_wait(ml->pc,ml->pm);
882 if (ml->reset)
883 ml->state = 0;
884 ret = WAIT_OBJECT_0;
886 if (duration > 0) { /* Timed Wait */
887 struct timespec abstime;
888 struct timeval now;
889 gettimeofday(&now, 0);
890 abstime.tv_sec = now.tv_sec + (now.tv_usec+duration)/1000000;
891 abstime.tv_nsec = ((now.tv_usec+duration)%1000000)*1000;
892 if (ml->state == 0)
893 ret=pthread_cond_timedwait(ml->pc,ml->pm,&abstime);
894 if (ret == ETIMEDOUT) ret = WAIT_TIMEOUT;
895 else ret = WAIT_OBJECT_0;
896 if (ml->reset)
897 ml->state = 0;
899 break;
900 case 1: /* Semaphore */
901 if (duration == 0) {
902 if(ml->semaphore==0) ret = WAIT_FAILED;
903 else {
904 ml->semaphore--;
905 ret = WAIT_OBJECT_0;
908 if (duration == -1) {
909 if (ml->semaphore==0)
910 pthread_cond_wait(ml->pc,ml->pm);
911 ml->semaphore--;
912 ret = WAIT_OBJECT_0;
914 break;
915 case 2: /* Mutex */
916 if (duration == 0) {
917 if(ml->lock_count > 0 && ml->owner != pthread_self()) ret = WAIT_FAILED;
918 else {
919 ml->lock_count++;
920 ml->owner = pthread_self();
921 ret = WAIT_OBJECT_0;
924 if (duration == -1) {
925 if (ml->lock_count > 0 && ml->owner != pthread_self()) {
926 pthread_cond_wait(ml->pc,ml->pm);
928 ml->lock_count++;
929 ml->owner = pthread_self();
930 ret = WAIT_OBJECT_0;
932 break;
934 pthread_mutex_unlock(ml->pm);
936 dbgprintf("WaitForSingleObject(0x%x, %d): 0x%x => 0x%x \n",object,duration,ml,ret);
937 return (void *)ret;
940 #ifdef CONFIG_QTX_CODECS
941 static void* WINAPI expWaitForMultipleObjects(int count, const void** objects,
942 int WaitAll, int duration)
944 int i;
945 void *object;
946 void *ret;
948 dbgprintf("WaitForMultipleObjects(%d, 0x%x, %d, duration %d) =>\n",
949 count, objects, WaitAll, duration);
951 for (i = 0; i < count; i++)
953 object = (void *)objects[i];
954 ret = expWaitForSingleObject(object, duration);
955 if (WaitAll)
956 dbgprintf("WaitAll flag not yet supported...\n");
957 else
958 return ret;
960 return NULL;
963 static void WINAPI expExitThread(int retcode)
965 dbgprintf("ExitThread(%d)\n", retcode);
966 pthread_exit(&retcode);
968 #endif
970 static int pf_set = 0;
971 static BYTE PF[64] = {0,};
973 static void DumpSystemInfo(const SYSTEM_INFO* si)
975 dbgprintf(" Processor architecture %d\n", si->u.s.wProcessorArchitecture);
976 dbgprintf(" Page size: %d\n", si->dwPageSize);
977 dbgprintf(" Minimum app address: %d\n", si->lpMinimumApplicationAddress);
978 dbgprintf(" Maximum app address: %d\n", si->lpMaximumApplicationAddress);
979 dbgprintf(" Active processor mask: 0x%x\n", si->dwActiveProcessorMask);
980 dbgprintf(" Number of processors: %d\n", si->dwNumberOfProcessors);
981 dbgprintf(" Processor type: 0x%x\n", si->dwProcessorType);
982 dbgprintf(" Allocation granularity: 0x%x\n", si->dwAllocationGranularity);
983 dbgprintf(" Processor level: 0x%x\n", si->wProcessorLevel);
984 dbgprintf(" Processor revision: 0x%x\n", si->wProcessorRevision);
987 static void WINAPI expGetSystemInfo(SYSTEM_INFO* si)
989 /* FIXME: better values for the two entries below... */
990 static int cache = 0;
991 static SYSTEM_INFO cachedsi;
992 dbgprintf("GetSystemInfo(%p) =>\n", si);
994 if (cache) {
995 goto exit;
997 memset(PF,0,sizeof(PF));
998 pf_set = 1;
1000 cachedsi.u.s.wProcessorArchitecture = PROCESSOR_ARCHITECTURE_INTEL;
1001 cachedsi.dwPageSize = getpagesize();
1003 /* FIXME: better values for the two entries below... */
1004 cachedsi.lpMinimumApplicationAddress = (void *)0x00000000;
1005 cachedsi.lpMaximumApplicationAddress = (void *)0x7FFFFFFF;
1006 cachedsi.dwActiveProcessorMask = 1;
1007 cachedsi.dwNumberOfProcessors = 1;
1008 cachedsi.dwProcessorType = PROCESSOR_INTEL_386;
1009 cachedsi.dwAllocationGranularity = 0x10000;
1010 cachedsi.wProcessorLevel = 5; /* pentium */
1011 cachedsi.wProcessorRevision = 0x0101;
1013 /* mplayer's way to detect PF's */
1015 #include "cpudetect.h"
1017 if (gCpuCaps.hasMMX)
1018 PF[PF_MMX_INSTRUCTIONS_AVAILABLE] = TRUE;
1019 if (gCpuCaps.hasSSE)
1020 PF[PF_XMMI_INSTRUCTIONS_AVAILABLE] = TRUE;
1021 if (gCpuCaps.hasSSE2)
1022 PF[PF_XMMI64_INSTRUCTIONS_AVAILABLE] = TRUE;
1023 if (gCpuCaps.has3DNow)
1024 PF[PF_AMD3D_INSTRUCTIONS_AVAILABLE] = TRUE;
1026 if (gCpuCaps.cpuType == 4)
1028 cachedsi.dwProcessorType = PROCESSOR_INTEL_486;
1029 cachedsi.wProcessorLevel = 4;
1031 else if (gCpuCaps.cpuType >= 5)
1033 cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
1034 cachedsi.wProcessorLevel = 5;
1036 else
1038 cachedsi.dwProcessorType = PROCESSOR_INTEL_386;
1039 cachedsi.wProcessorLevel = 3;
1041 cachedsi.wProcessorRevision = gCpuCaps.cpuStepping;
1042 cachedsi.dwNumberOfProcessors = 1; /* hardcoded */
1045 /* MPlayer: linux detection enabled (based on proc/cpuinfo) for checking
1046 fdiv_bug and fpu emulation flags -- alex/MPlayer */
1047 #ifdef __linux__
1049 char buf[20];
1050 char line[200];
1051 FILE *f = fopen ("/proc/cpuinfo", "r");
1053 if (!f)
1055 mp_msg(MSGT_WIN32, MSGL_WARN, "expGetSystemInfo: "
1056 "/proc/cpuinfo not readable! "
1057 "Expect bad performance and/or weird behaviour\n");
1058 goto exit;
1060 while (fgets(line,200,f)!=NULL) {
1061 char *s,*value;
1063 /* NOTE: the ':' is the only character we can rely on */
1064 if (!(value = strchr(line,':')))
1065 continue;
1066 /* terminate the valuename */
1067 *value++ = '\0';
1068 /* skip any leading spaces */
1069 while (*value==' ') value++;
1070 if ((s=strchr(value,'\n')))
1071 *s='\0';
1073 /* 2.1 method */
1074 if (!lstrncmpiA(line, "cpu family",strlen("cpu family"))) {
1075 if (isdigit (value[0])) {
1076 switch (value[0] - '0') {
1077 case 3: cachedsi.dwProcessorType = PROCESSOR_INTEL_386;
1078 cachedsi.wProcessorLevel= 3;
1079 break;
1080 case 4: cachedsi.dwProcessorType = PROCESSOR_INTEL_486;
1081 cachedsi.wProcessorLevel= 4;
1082 break;
1083 case 5: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
1084 cachedsi.wProcessorLevel= 5;
1085 break;
1086 case 6: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
1087 cachedsi.wProcessorLevel= 5;
1088 break;
1089 default:cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
1090 cachedsi.wProcessorLevel= 5;
1091 break;
1094 /* set the CPU type of the current processor */
1095 sprintf(buf,"CPU %ld",cachedsi.dwProcessorType);
1096 continue;
1098 /* old 2.0 method */
1099 if (!lstrncmpiA(line, "cpu",strlen("cpu"))) {
1100 if ( isdigit (value[0]) && value[1] == '8' &&
1101 value[2] == '6' && value[3] == 0
1103 switch (value[0] - '0') {
1104 case 3: cachedsi.dwProcessorType = PROCESSOR_INTEL_386;
1105 cachedsi.wProcessorLevel= 3;
1106 break;
1107 case 4: cachedsi.dwProcessorType = PROCESSOR_INTEL_486;
1108 cachedsi.wProcessorLevel= 4;
1109 break;
1110 case 5: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
1111 cachedsi.wProcessorLevel= 5;
1112 break;
1113 case 6: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
1114 cachedsi.wProcessorLevel= 5;
1115 break;
1116 default:cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
1117 cachedsi.wProcessorLevel= 5;
1118 break;
1121 /* set the CPU type of the current processor */
1122 sprintf(buf,"CPU %ld",cachedsi.dwProcessorType);
1123 continue;
1125 if (!lstrncmpiA(line,"fdiv_bug",strlen("fdiv_bug"))) {
1126 if (!lstrncmpiA(value,"yes",3))
1127 PF[PF_FLOATING_POINT_PRECISION_ERRATA] = TRUE;
1129 continue;
1131 if (!lstrncmpiA(line,"fpu",strlen("fpu"))) {
1132 if (!lstrncmpiA(value,"no",2))
1133 PF[PF_FLOATING_POINT_EMULATED] = TRUE;
1135 continue;
1137 if (!lstrncmpiA(line,"processor",strlen("processor"))) {
1138 /* processor number counts up...*/
1139 unsigned int x;
1141 if (sscanf(value,"%d",&x))
1142 if (x+1>cachedsi.dwNumberOfProcessors)
1143 cachedsi.dwNumberOfProcessors=x+1;
1145 /* Create a new processor subkey on a multiprocessor
1146 * system
1148 sprintf(buf,"%d",x);
1150 if (!lstrncmpiA(line,"stepping",strlen("stepping"))) {
1151 int x;
1153 if (sscanf(value,"%d",&x))
1154 cachedsi.wProcessorRevision = x;
1157 ( (!lstrncmpiA(line,"flags",strlen("flags")))
1158 || (!lstrncmpiA(line,"features",strlen("features"))) )
1160 if (strstr(value,"cx8"))
1161 PF[PF_COMPARE_EXCHANGE_DOUBLE] = TRUE;
1162 if (strstr(value,"mmx"))
1163 PF[PF_MMX_INSTRUCTIONS_AVAILABLE] = TRUE;
1164 if (strstr(value,"tsc"))
1165 PF[PF_RDTSC_INSTRUCTION_AVAILABLE] = TRUE;
1166 if (strstr(value,"xmm") || strstr(value,"sse"))
1167 PF[PF_XMMI_INSTRUCTIONS_AVAILABLE] = TRUE;
1168 if (strstr(value,"sse2"))
1169 PF[PF_XMMI64_INSTRUCTIONS_AVAILABLE] = TRUE;
1170 if (strstr(value,"3dnow"))
1171 PF[PF_AMD3D_INSTRUCTIONS_AVAILABLE] = TRUE;
1174 fclose (f);
1176 #endif /* __linux__ */
1177 cache = 1;
1178 exit:
1179 memcpy(si,&cachedsi,sizeof(*si));
1180 DumpSystemInfo(si);
1183 // avoid undefined expGetSystemInfo
1184 static WIN_BOOL WINAPI expIsProcessorFeaturePresent(DWORD v)
1186 WIN_BOOL result = 0;
1187 if (!pf_set)
1189 SYSTEM_INFO si;
1190 expGetSystemInfo(&si);
1192 if(v<64) result=PF[v];
1193 dbgprintf("IsProcessorFeaturePresent(0x%x) => 0x%x\n", v, result);
1194 return result;
1197 static WIN_BOOL WINAPI expIsDebuggerPresent(void)
1199 return 0;
1202 static long WINAPI expGetVersion(void)
1204 dbgprintf("GetVersion() => 0xC0000004\n");
1205 return 0xC0000004;//Windows 95
1208 static HANDLE WINAPI expHeapCreate(long flags, long init_size, long max_size)
1210 // printf("HeapCreate:");
1211 HANDLE result;
1212 if(init_size==0)
1213 result=(HANDLE)my_mreq(0x110000, 0);
1214 else
1215 result=(HANDLE)my_mreq((init_size + 0xfff) & 0x7ffff000 , 0);
1216 dbgprintf("HeapCreate(flags 0x%x, initial size %d, maximum size %d) => 0x%x\n", flags, init_size, max_size, result);
1217 return result;
1220 // this is another dirty hack
1221 // VP31 is releasing one allocated Heap chunk twice
1222 // we will silently ignore this second call...
1223 static void* heapfreehack = 0;
1224 static int heapfreehackshown = 0;
1225 //void trapbug(void);
1226 static void* WINAPI expHeapAlloc(HANDLE heap, int flags, int size)
1228 void* z;
1230 Morgan's m3jpeg32.dll v. 2.0 encoder expects that request for
1231 HeapAlloc returns area larger than size argument :-/
1233 actually according to M$ Doc HeapCreate size should be rounded
1234 to page boundaries thus we should simulate this
1236 //if (size == 22276) trapbug();
1237 z=my_mreq((size + 0xfff) & 0x7ffff000, (flags & HEAP_ZERO_MEMORY));
1238 if(z==0)
1239 printf("HeapAlloc failure\n");
1240 dbgprintf("HeapAlloc(heap 0x%x, flags 0x%x, size %d) => 0x%x\n", heap, flags, size, z);
1241 heapfreehack = 0; // reset
1242 return z;
1244 static long WINAPI expHeapDestroy(void* heap)
1246 dbgprintf("HeapDestroy(heap 0x%x) => 1\n", heap);
1247 my_release(heap);
1248 return 1;
1251 static long WINAPI expHeapFree(HANDLE heap, DWORD dwFlags, LPVOID lpMem)
1253 dbgprintf("HeapFree(0x%x, 0x%x, pointer 0x%x) => 1\n", heap, dwFlags, lpMem);
1254 if (heapfreehack != lpMem && lpMem != (void*)0xffffffff
1255 && lpMem != (void*)0xbdbdbdbd)
1256 // 0xbdbdbdbd is for i263_drv.drv && libefence
1257 // it seems to be reading from relased memory
1258 // EF_PROTECT_FREE doens't show any probleme
1259 my_release(lpMem);
1260 else
1262 if (!heapfreehackshown++)
1263 printf("Info: HeapFree deallocating same memory twice! (%p)\n", lpMem);
1265 heapfreehack = lpMem;
1266 return 1;
1268 static long WINAPI expHeapSize(int heap, int flags, void* pointer)
1270 long result=my_size(pointer);
1271 dbgprintf("HeapSize(heap 0x%x, flags 0x%x, pointer 0x%x) => %d\n", heap, flags, pointer, result);
1272 return result;
1274 static void* WINAPI expHeapReAlloc(HANDLE heap,int flags,void *lpMem,int size)
1276 long orgsize = my_size(lpMem);
1277 dbgprintf("HeapReAlloc() Size %ld org %d\n",orgsize,size);
1278 return my_realloc(lpMem, size);
1280 static long WINAPI expGetProcessHeap(void)
1282 dbgprintf("GetProcessHeap() => 1\n");
1283 return 1;
1285 static void* WINAPI expVirtualAlloc(void* v1, long v2, long v3, long v4)
1287 void* z = VirtualAlloc(v1, v2, v3, v4);
1288 if(z==0)
1289 printf("VirtualAlloc failure\n");
1290 dbgprintf("VirtualAlloc(0x%x, %d, %d, %d) => 0x%x \n",v1,v2,v3,v4, z);
1291 return z;
1293 static int WINAPI expVirtualFree(void* v1, int v2, int v3)
1295 int result = VirtualFree(v1,v2,v3);
1296 dbgprintf("VirtualFree(0x%x, %d, %d) => %d\n",v1,v2,v3, result);
1297 return result;
1300 /* we're building a table of critical sections. cs_win pointer uses the DLL
1301 cs_unix is the real structure, we're using cs_win only to identifying cs_unix */
1302 struct critsecs_list_t
1304 CRITICAL_SECTION *cs_win;
1305 struct CRITSECT *cs_unix;
1308 /* 'NEWTYPE' is working with VIVO, 3ivX and QTX dll (no more segfaults) -- alex */
1309 #undef CRITSECS_NEWTYPE
1310 //#define CRITSECS_NEWTYPE 1
1312 #ifdef CRITSECS_NEWTYPE
1313 /* increased due to ucod needs more than 32 entries */
1314 /* and 64 should be enough for everything */
1315 #define CRITSECS_LIST_MAX 64
1316 static struct critsecs_list_t critsecs_list[CRITSECS_LIST_MAX];
1318 static int critsecs_get_pos(CRITICAL_SECTION *cs_win)
1320 int i;
1322 for (i=0; i < CRITSECS_LIST_MAX; i++)
1323 if (critsecs_list[i].cs_win == cs_win)
1324 return i;
1325 return -1;
1328 static int critsecs_get_unused(void)
1330 int i;
1332 for (i=0; i < CRITSECS_LIST_MAX; i++)
1333 if (critsecs_list[i].cs_win == NULL)
1334 return i;
1335 return -1;
1338 struct CRITSECT *critsecs_get_unix(CRITICAL_SECTION *cs_win)
1340 int i;
1342 for (i=0; i < CRITSECS_LIST_MAX; i++)
1343 if (critsecs_list[i].cs_win == cs_win && critsecs_list[i].cs_unix)
1344 return critsecs_list[i].cs_unix;
1345 return NULL;
1347 #endif
1349 static void WINAPI expInitializeCriticalSection(CRITICAL_SECTION* c)
1351 dbgprintf("InitializeCriticalSection(0x%x)\n", c);
1352 /* if(sizeof(pthread_mutex_t)>sizeof(CRITICAL_SECTION))
1354 printf(" ERROR:::: sizeof(pthread_mutex_t) is %d, expected <=%d!\n",
1355 sizeof(pthread_mutex_t), sizeof(CRITICAL_SECTION));
1356 return;
1358 /* pthread_mutex_init((pthread_mutex_t*)c, NULL); */
1359 #ifdef CRITSECS_NEWTYPE
1361 struct CRITSECT *cs;
1362 int i = critsecs_get_unused();
1364 if (i < 0)
1366 printf("InitializeCriticalSection(%p) - no more space in list\n", c);
1367 return;
1369 dbgprintf("got unused space at %d\n", i);
1370 cs = malloc(sizeof(struct CRITSECT));
1371 if (!cs)
1373 printf("InitializeCriticalSection(%p) - out of memory\n", c);
1374 return;
1376 pthread_mutex_init(&cs->mutex, NULL);
1377 pthread_cond_init(&cs->unlocked, NULL);
1378 cs->lock_count = 0;
1379 critsecs_list[i].cs_win = c;
1380 critsecs_list[i].cs_unix = cs;
1381 dbgprintf("InitializeCriticalSection -> itemno=%d, cs_win=%p, cs_unix=%p\n",
1382 i, c, cs);
1384 #else
1386 struct CRITSECT* cs = mreq_private(sizeof(struct CRITSECT) + sizeof(CRITICAL_SECTION),
1387 0, AREATYPE_CRITSECT);
1388 pthread_mutex_init(&cs->mutex, NULL);
1389 pthread_cond_init(&cs->unlocked, NULL);
1390 cs->lock_count = 0;
1391 cs->deadbeef = 0xdeadbeef;
1392 *(void**)c = cs;
1394 #endif
1395 return;
1398 static WIN_BOOL WINAPI expInitializeCriticalSectionAndSpinCount(CRITICAL_SECTION* c, DWORD spin)
1400 expInitializeCriticalSection(c);
1401 return 1;
1404 static void WINAPI expEnterCriticalSection(CRITICAL_SECTION* c)
1406 #ifdef CRITSECS_NEWTYPE
1407 struct CRITSECT* cs = critsecs_get_unix(c);
1408 #else
1409 struct CRITSECT* cs = (*(struct CRITSECT**)c);
1410 #endif
1411 dbgprintf("EnterCriticalSection(0x%x) %p\n",c, cs);
1412 if (!cs)
1414 dbgprintf("entered uninitialized critisec!\n");
1415 expInitializeCriticalSection(c);
1416 #ifdef CRITSECS_NEWTYPE
1417 cs=critsecs_get_unix(c);
1418 #else
1419 cs = (*(struct CRITSECT**)c);
1420 #endif
1421 dbgprintf("Win32 Warning: Accessed uninitialized Critical Section (%p)!\n", c);
1423 pthread_mutex_lock(&(cs->mutex));
1424 if (cs->lock_count > 0 && cs->id == pthread_self()) {
1425 cs->lock_count++;
1426 } else {
1427 while (cs->lock_count != 0) {
1428 pthread_cond_wait(&(cs->unlocked), &(cs->mutex));
1430 cs->lock_count = 1;
1431 cs->id = pthread_self();
1433 pthread_mutex_unlock(&(cs->mutex));
1434 return;
1436 static void WINAPI expLeaveCriticalSection(CRITICAL_SECTION* c)
1438 #ifdef CRITSECS_NEWTYPE
1439 struct CRITSECT* cs = critsecs_get_unix(c);
1440 #else
1441 struct CRITSECT* cs = (*(struct CRITSECT**)c);
1442 #endif
1443 // struct CRITSECT* cs=(struct CRITSECT*)c;
1444 dbgprintf("LeaveCriticalSection(0x%x) 0x%x\n",c, cs);
1445 if (!cs)
1447 dbgprintf("Win32 Warning: Leaving uninitialized Critical Section %p!!\n", c);
1448 return;
1450 pthread_mutex_lock(&(cs->mutex));
1451 if (cs->lock_count == 0) {
1452 dbgprintf("Win32 Warning: Unlocking unlocked Critical Section %p!!\n", c);
1453 } else {
1454 cs->lock_count--;
1456 if (cs->lock_count == 0) {
1457 pthread_cond_signal(&(cs->unlocked));
1459 pthread_mutex_unlock(&(cs->mutex));
1460 return;
1463 static void expfree(void* mem); /* forward declaration */
1465 static void WINAPI expDeleteCriticalSection(CRITICAL_SECTION *c)
1467 #ifdef CRITSECS_NEWTYPE
1468 struct CRITSECT* cs = critsecs_get_unix(c);
1469 #else
1470 struct CRITSECT* cs= (*(struct CRITSECT**)c);
1471 #endif
1472 // struct CRITSECT* cs=(struct CRITSECT*)c;
1473 dbgprintf("DeleteCriticalSection(0x%x)\n",c);
1475 if (!cs)
1477 dbgprintf("Win32 Warning: Deleting uninitialized Critical Section %p!!\n", c);
1478 return;
1481 pthread_mutex_lock(&(cs->mutex));
1482 if (cs->lock_count > 0)
1484 dbgprintf("Win32 Warning: Deleting locked Critical Section %p!!\n", c);
1486 pthread_mutex_unlock(&(cs->mutex));
1488 #ifndef GARBAGE
1489 pthread_mutex_destroy(&(cs->mutex));
1490 pthread_cond_destroy(&(cs->unlocked));
1491 // released by GarbageCollector in my_relase otherwise
1492 #endif
1493 my_release(cs);
1494 #ifdef CRITSECS_NEWTYPE
1496 int i = critsecs_get_pos(c);
1498 if (i < 0)
1500 printf("DeleteCriticalSection(%p) error (critsec not found)\n", c);
1501 return;
1504 critsecs_list[i].cs_win = NULL;
1505 expfree(critsecs_list[i].cs_unix);
1506 critsecs_list[i].cs_unix = NULL;
1507 dbgprintf("DeleteCriticalSection -> itemno=%d\n", i);
1509 #endif
1510 return;
1512 static int WINAPI expGetCurrentThreadId(void)
1514 dbgprintf("GetCurrentThreadId() => %d\n", pthread_self());
1515 return pthread_self();
1517 static int WINAPI expGetCurrentProcess(void)
1519 dbgprintf("GetCurrentProcess() => %d\n", getpid());
1520 return getpid();
1523 #ifdef CONFIG_QTX_CODECS
1524 // this version is required for Quicktime codecs (.qtx/.qts) to work.
1525 // (they assume some pointers at FS: segment)
1527 extern void* fs_seg;
1529 //static int tls_count;
1530 static int tls_use_map[64];
1531 static int WINAPI expTlsAlloc(void)
1533 int i;
1534 for(i=0; i<64; i++)
1535 if(tls_use_map[i]==0)
1537 tls_use_map[i]=1;
1538 dbgprintf("TlsAlloc() => %d\n",i);
1539 return i;
1541 dbgprintf("TlsAlloc() => -1 (ERROR)\n");
1542 return -1;
1545 //static int WINAPI expTlsSetValue(DWORD index, void* value)
1546 static int WINAPI expTlsSetValue(int index, void* value)
1548 dbgprintf("TlsSetValue(%d,0x%x) => 1\n",index,value);
1549 // if((index<0) || (index>64))
1550 if((index>=64))
1551 return 0;
1552 *(void**)((char*)fs_seg+0x88+4*index) = value;
1553 return 1;
1556 static void* WINAPI expTlsGetValue(DWORD index)
1558 dbgprintf("TlsGetValue(%d)\n",index);
1559 // if((index<0) || (index>64))
1560 if((index>=64)) return NULL;
1561 return *(void**)((char*)fs_seg+0x88+4*index);
1564 static int WINAPI expTlsFree(int idx)
1566 int index = (int) idx;
1567 dbgprintf("TlsFree(%d)\n",index);
1568 if((index<0) || (index>64))
1569 return 0;
1570 tls_use_map[index]=0;
1571 return 1;
1574 #else
1575 struct tls_s {
1576 void* value;
1577 int used;
1578 struct tls_s* prev;
1579 struct tls_s* next;
1582 static void* WINAPI expTlsAlloc(void)
1584 if (g_tls == NULL)
1586 g_tls=my_mreq(sizeof(tls_t), 0);
1587 g_tls->next=g_tls->prev=NULL;
1589 else
1591 g_tls->next=my_mreq(sizeof(tls_t), 0);
1592 g_tls->next->prev=g_tls;
1593 g_tls->next->next=NULL;
1594 g_tls=g_tls->next;
1596 dbgprintf("TlsAlloc() => 0x%x\n", g_tls);
1597 if (g_tls)
1598 g_tls->value=0; /* XXX For Divx.dll */
1599 return g_tls;
1602 static int WINAPI expTlsSetValue(void* idx, void* value)
1604 tls_t* index = (tls_t*) idx;
1605 int result;
1606 if(index==0)
1607 result=0;
1608 else
1610 index->value=value;
1611 result=1;
1613 dbgprintf("TlsSetValue(index 0x%x, value 0x%x) => %d \n", index, value, result );
1614 return result;
1616 static void* WINAPI expTlsGetValue(void* idx)
1618 tls_t* index = (tls_t*) idx;
1619 void* result;
1620 if(index==0)
1621 result=0;
1622 else
1623 result=index->value;
1624 dbgprintf("TlsGetValue(index 0x%x) => 0x%x\n", index, result);
1625 return result;
1627 static int WINAPI expTlsFree(void* idx)
1629 tls_t* index = (tls_t*) idx;
1630 int result;
1631 if(index==0)
1632 result=0;
1633 else
1635 if(index->next)
1636 index->next->prev=index->prev;
1637 if(index->prev)
1638 index->prev->next=index->next;
1639 if (g_tls == index)
1640 g_tls = index->prev;
1641 my_release((void*)index);
1642 result=1;
1644 dbgprintf("TlsFree(index 0x%x) => %d\n", index, result);
1645 return result;
1647 #endif
1649 static void* WINAPI expLocalAlloc(int flags, int size)
1651 void* z = my_mreq(size, (flags & GMEM_ZEROINIT));
1652 if (z == 0)
1653 printf("LocalAlloc() failed\n");
1654 dbgprintf("LocalAlloc(%d, flags 0x%x) => 0x%x\n", size, flags, z);
1655 return z;
1658 static void* WINAPI expLocalReAlloc(int handle,int size, int flags)
1660 void *newpointer;
1661 int oldsize;
1663 newpointer=NULL;
1664 if (flags & LMEM_MODIFY) {
1665 dbgprintf("LocalReAlloc MODIFY\n");
1666 return (void *)handle;
1668 oldsize = my_size((void *)handle);
1669 newpointer = my_realloc((void *)handle,size);
1670 dbgprintf("LocalReAlloc(%x %d(old %d), flags 0x%x) => 0x%x\n", handle,size,oldsize, flags,newpointer);
1672 return newpointer;
1675 static void* WINAPI expLocalLock(void* z)
1677 dbgprintf("LocalLock(0x%x) => 0x%x\n", z, z);
1678 return z;
1681 static void* WINAPI expGlobalAlloc(int flags, int size)
1683 void* z;
1684 dbgprintf("GlobalAlloc(%d, flags 0x%X)\n", size, flags);
1686 z=my_mreq(size, (flags & GMEM_ZEROINIT));
1687 //z=calloc(size, 1);
1688 //z=malloc(size);
1689 if(z==0)
1690 printf("GlobalAlloc() failed\n");
1691 dbgprintf("GlobalAlloc(%d, flags 0x%x) => 0x%x\n", size, flags, z);
1692 return z;
1694 static void* WINAPI expGlobalLock(void* z)
1696 dbgprintf("GlobalLock(0x%x) => 0x%x\n", z, z);
1697 return z;
1699 // pvmjpg20 - but doesn't work anyway
1700 static int WINAPI expGlobalSize(void* amem)
1702 int size = 100000;
1703 #ifdef GARBAGE
1704 alloc_header* header = last_alloc;
1705 alloc_header* mem = (alloc_header*) amem - 1;
1706 if (amem == 0)
1707 return 0;
1708 pthread_mutex_lock(&memmut);
1709 while (header)
1711 if (header->deadbeef != 0xdeadbeef)
1713 dbgprintf("FATAL found corrupted memory! %p 0x%lx (%d)\n", header, header->deadbeef, alccnt);
1714 break;
1717 if (header == mem)
1719 size = header->size;
1720 break;
1723 header = header->prev;
1725 pthread_mutex_unlock(&memmut);
1726 #endif
1728 dbgprintf("GlobalSize(0x%x)\n", amem);
1729 return size;
1732 static int WINAPI expLoadIconA( long hinstance, char *name )
1734 dbgprintf("LoadIconA( %ld, 0x%x ) => 1\n",hinstance,name);
1735 return 1;
1738 static int WINAPI expLoadStringA(long instance, long id, void* buf, long size)
1740 int result=LoadStringA(instance, id, buf, size);
1741 // if(buf)
1742 dbgprintf("LoadStringA(instance 0x%x, id 0x%x, buffer 0x%x, size %d) => %d ( %s )\n",
1743 instance, id, buf, size, result, buf);
1744 // else
1745 // dbgprintf("LoadStringA(instance 0x%x, id 0x%x, buffer 0x%x, size %d) => %d\n",
1746 // instance, id, buf, size, result);
1747 return result;
1750 static long WINAPI expMultiByteToWideChar(long v1, long v2, char* s1, long siz1, short* s2, int siz2)
1752 #warning FIXME
1753 int i;
1754 int result;
1755 if(s2==0)
1756 result=1;
1757 else
1759 if(siz1>siz2/2)siz1=siz2/2;
1760 for(i=1; i<=siz1; i++)
1762 *s2=*s1;
1763 if(!*s1)break;
1764 s2++;
1765 s1++;
1767 result=i;
1769 if(s1)
1770 dbgprintf("MultiByteToWideChar(codepage %d, flags 0x%x, string 0x%x='%s',"
1771 "size %d, dest buffer 0x%x, dest size %d) => %d\n",
1772 v1, v2, s1, s1, siz1, s2, siz2, result);
1773 else
1774 dbgprintf("MultiByteToWideChar(codepage %d, flags 0x%x, string NULL,"
1775 "size %d, dest buffer 0x%x, dest size %d) =>\n",
1776 v1, v2, siz1, s2, siz2, result);
1777 return result;
1779 static void wch_print(const short* str)
1781 dbgprintf(" src: ");
1782 while(*str)dbgprintf("%c", *str++);
1783 dbgprintf("\n");
1785 static long WINAPI expWideCharToMultiByte(long v1, long v2, short* s1, long siz1,
1786 char* s2, int siz2, char* c3, int* siz3)
1788 int result;
1789 dbgprintf("WideCharToMultiByte(codepage %d, flags 0x%x, src 0x%x, src size %d, "
1790 "dest 0x%x, dest size %d, defch 0x%x, used_defch 0x%x)", v1, v2, s1, siz1, s2, siz2, c3, siz3);
1791 result=WideCharToMultiByte(v1, v2, s1, siz1, s2, siz2, c3, siz3);
1792 dbgprintf("=> %d\n", result);
1793 //if(s1)wch_print(s1);
1794 if(s2)dbgprintf(" dest: %s\n", s2);
1795 return result;
1798 static long WINAPI expGetVersionExA(OSVERSIONINFOA* c)
1800 dbgprintf("GetVersionExA(0x%x) => 1\n", c);
1801 c->dwOSVersionInfoSize=sizeof(*c);
1802 c->dwMajorVersion=5;
1803 c->dwMinorVersion=1;
1804 c->dwBuildNumber=0x5010a28;
1805 c->dwPlatformId=VER_PLATFORM_WIN32_NT;
1806 strcpy(c->szCSDVersion, "Service Pack 2");
1807 dbgprintf(" Major version: 5\n Minor version: 1\n Build number: 0x5010a28\n"
1808 " Platform Id: VER_PLATFORM_WIN32_NT\n Version string: 'Service Pack 2'\n");
1809 return 1;
1812 static long WINAPI expGetVersionExW(OSVERSIONINFOW* c)
1814 char CSDVersion[128];
1815 dbgprintf("GetVersionExW(0x%x) => 1\n", c);
1816 c->dwOSVersionInfoSize=sizeof(*c);
1817 c->dwMajorVersion=5;
1818 c->dwMinorVersion=1;
1819 c->dwBuildNumber=0x5010a28;
1820 c->dwPlatformId=VER_PLATFORM_WIN32_NT;
1821 strcpy(CSDVersion, "Service Pack 2");
1822 MultiByteToWideChar(65001, 0x0, CSDVersion, -1, c->szCSDVersion, 128);
1823 dbgprintf(" Major version: 5\n Minor version: 1\n Build number: 0x5010a28\n"
1824 " Platform Id: VER_PLATFORM_WIN32_NT\n Version string: 'Service Pack 2'\n");
1825 return 1;
1828 static HANDLE WINAPI expCreateSemaphoreA(char* v1, long init_count,
1829 long max_count, char* name)
1831 pthread_mutex_t *pm;
1832 pthread_cond_t *pc;
1833 HANDLE ret;
1835 mutex_list* pp;
1836 printf("CreateSemaphoreA(%p = %s)\n", name, (name ? name : "<null>"));
1837 pp=mlist;
1838 while(pp)
1840 printf("%p => ", pp);
1841 pp=pp->prev;
1843 printf("0\n");
1845 pthread_mutex_lock(&mlist_lock);
1846 if(mlist!=NULL)
1848 mutex_list* pp=mlist;
1849 if(name!=NULL)
1852 if((strcmp(pp->name, name)==0) && (pp->type==1))
1854 dbgprintf("CreateSemaphoreA(0x%x, init_count %d, max_count %d, name 0x%x='%s') => 0x%x\n",
1855 v1, init_count, max_count, name, name, mlist);
1856 ret = (HANDLE)mlist;
1857 pthread_mutex_unlock(&mlist_lock);
1858 return ret;
1860 }while((pp=pp->prev) != NULL);
1862 pm=mreq_private(sizeof(pthread_mutex_t), 0, AREATYPE_MUTEX);
1863 pthread_mutex_init(pm, NULL);
1864 pc=mreq_private(sizeof(pthread_cond_t), 0, AREATYPE_COND);
1865 pthread_cond_init(pc, NULL);
1866 if(mlist==NULL)
1868 mlist=mreq_private(sizeof(mutex_list), 00, AREATYPE_EVENT);
1869 mlist->next=mlist->prev=NULL;
1871 else
1873 mlist->next=mreq_private(sizeof(mutex_list), 00, AREATYPE_EVENT);
1874 mlist->next->prev=mlist;
1875 mlist->next->next=NULL;
1876 mlist=mlist->next;
1877 // printf("new semaphore %p\n", mlist);
1879 mlist->type=1; /* Type Semaphore */
1880 mlist->pm=pm;
1881 mlist->pc=pc;
1882 mlist->state=0;
1883 mlist->reset=0;
1884 mlist->semaphore=init_count;
1885 if(name!=NULL)
1886 strncpy(mlist->name, name, 64);
1887 else
1888 mlist->name[0]=0;
1889 if(pm==NULL)
1890 dbgprintf("ERROR::: CreateSemaphoreA failure\n");
1891 if(name)
1892 dbgprintf("CreateSemaphoreA(0x%x, init_count %d, max_count %d, name 0x%x='%s') => 0x%x\n",
1893 v1, init_count, max_count, name, name, mlist);
1894 else
1895 dbgprintf("CreateSemaphoreA(0x%x, init_count %d, max_count %d, name 0) => 0x%x\n",
1896 v1, init_count, max_count, mlist);
1897 ret = (HANDLE)mlist;
1898 pthread_mutex_unlock(&mlist_lock);
1899 return ret;
1902 static HANDLE WINAPI expCreateSemaphoreW(char* v1, long init_count,
1903 long max_count, const WCHAR* name)
1905 char ascii_name[256];
1906 char *aname = NULL;
1907 if (name) {
1908 WideCharToMultiByte(65001, 0x0, name, -1, ascii_name, 256, NULL, NULL);
1909 aname = ascii_name;
1911 return expCreateSemaphoreA(v1, init_count, max_count, aname);
1914 static long WINAPI expReleaseSemaphore(long hsem, long increment, long* prev_count)
1916 // The state of a semaphore object is signaled when its count
1917 // is greater than zero and nonsignaled when its count is equal to zero
1918 // Each time a waiting thread is released because of the semaphore's signaled
1919 // state, the count of the semaphore is decreased by one.
1920 mutex_list *ml = (mutex_list *)hsem;
1922 pthread_mutex_lock(ml->pm);
1923 if (prev_count != 0) *prev_count = ml->semaphore;
1924 if (ml->semaphore == 0) pthread_cond_signal(ml->pc);
1925 ml->semaphore += increment;
1926 pthread_mutex_unlock(ml->pm);
1927 dbgprintf("ReleaseSemaphore(semaphore 0x%x, increment %d, prev_count 0x%x) => 1\n",
1928 hsem, increment, prev_count);
1929 return 1;
1932 static HANDLE WINAPI expCreateMutexA(void *pSecAttr,
1933 char bInitialOwner, const char *name)
1935 pthread_mutex_t *pm;
1936 pthread_cond_t *pc;
1937 HANDLE ret;
1938 pthread_mutex_lock(&mlist_lock);
1939 if(mlist!=NULL)
1941 mutex_list* pp=mlist;
1942 if(name!=NULL)
1945 if((strcmp(pp->name, name)==0) && (pp->type==2))
1947 dbgprintf("CreateMutexA(0x%x, %d, '%s') => 0x%x\n", pSecAttr, bInitialOwner, name, mlist);
1948 ret = (HANDLE)mlist;
1949 pthread_mutex_unlock(&mlist_lock);
1950 return ret;
1952 }while((pp=pp->prev) != NULL);
1954 pm=mreq_private(sizeof(pthread_mutex_t), 0, AREATYPE_MUTEX);
1955 pthread_mutex_init(pm, NULL);
1956 pc=mreq_private(sizeof(pthread_cond_t), 0, AREATYPE_COND);
1957 pthread_cond_init(pc, NULL);
1958 if(mlist==NULL)
1960 mlist=mreq_private(sizeof(mutex_list), 00, AREATYPE_EVENT);
1961 mlist->next=mlist->prev=NULL;
1963 else
1965 mlist->next=mreq_private(sizeof(mutex_list), 00, AREATYPE_EVENT);
1966 mlist->next->prev=mlist;
1967 mlist->next->next=NULL;
1968 mlist=mlist->next;
1970 mlist->type=2; /* Type Mutex */
1971 mlist->pm=pm;
1972 mlist->pc=pc;
1973 mlist->state=0;
1974 mlist->reset=0;
1975 mlist->semaphore=0;
1976 if (bInitialOwner) {
1977 mlist->owner = pthread_self();
1978 mlist->lock_count = 1;
1979 } else {
1980 mlist->owner = (pthread_t)0;
1981 mlist->lock_count = 0;
1983 if(name!=NULL)
1984 strncpy(mlist->name, name, 64);
1985 else
1986 mlist->name[0]=0;
1987 if(pm==NULL)
1988 dbgprintf("ERROR::: CreateMutexA failure\n");
1989 if(name)
1990 dbgprintf("CreateMutexA(0x%x, %d, '%s') => 0x%x\n",
1991 pSecAttr, bInitialOwner, name, mlist);
1992 else
1993 dbgprintf("CreateMutexA(0x%x, %d, NULL) => 0x%x\n",
1994 pSecAttr, bInitialOwner, mlist);
1995 ret = (HANDLE)mlist;
1996 pthread_mutex_unlock(&mlist_lock);
1997 return ret;
2000 static HANDLE WINAPI expCreateMutexW(void *pSecAttr, char bInitialOwner, const WCHAR *name)
2002 char ascii_name[256];
2003 char *aname = NULL;
2004 if (name) {
2005 WideCharToMultiByte(65001, 0x0, name, -1, ascii_name, 256, NULL, NULL);
2006 aname = ascii_name;
2008 return expCreateMutexA(pSecAttr, bInitialOwner, aname);
2011 static int WINAPI expReleaseMutex(HANDLE hMutex)
2013 mutex_list *ml = (mutex_list *)hMutex;
2015 pthread_mutex_lock(ml->pm);
2016 if (--ml->lock_count == 0) pthread_cond_signal(ml->pc);
2017 pthread_mutex_unlock(ml->pm);
2018 return 1;
2021 static DWORD WINAPI expSignalObjectAndWait(HANDLE hObjectToSignal,
2022 HANDLE hObjectToWaitOn,
2023 DWORD dwMilliseconds,
2024 WIN_BOOL bAlertable) {
2025 mutex_list* mlist = (mutex_list*)hObjectToSignal;
2027 switch (mlist->type) {
2028 case 0: // Event
2029 expSetEvent(mlist);
2030 break;
2031 case 1: // Semaphore
2032 expReleaseSemaphore(mlist, 1, NULL);
2033 break;
2034 case 2: // Mutex
2035 expReleaseMutex(mlist);
2036 break;
2037 default:
2038 dbgprintf("Signalling unknown object type %d!\n", hObjectToSignal);
2040 return expWaitForSingleObject(hObjectToWaitOn, dwMilliseconds);
2043 static long WINAPI expRegOpenKeyExA(long key, const char* subkey, long reserved, long access, int* newkey)
2045 long result=RegOpenKeyExA(key, subkey, reserved, access, newkey);
2046 dbgprintf("RegOpenKeyExA(key 0x%x, subkey %s, reserved %d, access 0x%x, pnewkey 0x%x) => %d\n",
2047 key, subkey, reserved, access, newkey, result);
2048 if(newkey)dbgprintf(" New key: 0x%x\n", *newkey);
2049 return result;
2051 static long WINAPI expRegCloseKey(long key)
2053 long result=RegCloseKey(key);
2054 dbgprintf("RegCloseKey(0x%x) => %d\n", key, result);
2055 return result;
2057 static long WINAPI expRegQueryValueExA(long key, const char* value, int* reserved, int* type, int* data, int* count)
2059 long result=RegQueryValueExA(key, value, reserved, type, data, count);
2060 dbgprintf("RegQueryValueExA(key 0x%x, value %s, reserved 0x%x, data 0x%x, count 0x%x)"
2061 " => 0x%x\n", key, value, reserved, data, count, result);
2062 if(data && count)dbgprintf(" read %d bytes: '%s'\n", *count, data);
2063 return result;
2066 //from wine source dlls/advapi32/registry.c
2067 static long WINAPI expRegCreateKeyA(long hkey, const char* name, int *retkey)
2069 dbgprintf("RegCreateKeyA(key 0x%x, name 0x%x='%s',newkey=0x%x)\n",hkey,name,retkey);
2070 return RegCreateKeyExA( hkey, name, 0, NULL,REG_OPTION_NON_VOLATILE,
2071 KEY_ALL_ACCESS , NULL, retkey, NULL );
2074 static long WINAPI expRegCreateKeyExA(long key, const char* name, long reserved,
2075 void* classs, long options, long security,
2076 void* sec_attr, int* newkey, int* status)
2078 long result=RegCreateKeyExA(key, name, reserved, classs, options, security, sec_attr, newkey, status);
2079 dbgprintf("RegCreateKeyExA(key 0x%x, name 0x%x='%s', reserved=0x%x,"
2080 " 0x%x, 0x%x, 0x%x, newkey=0x%x, status=0x%x) => %d\n",
2081 key, name, name, reserved, classs, options, security, sec_attr, newkey, status, result);
2082 if(!result && newkey) dbgprintf(" New key: 0x%x\n", *newkey);
2083 if(!result && status) dbgprintf(" New key status: 0x%x\n", *status);
2084 return result;
2086 static long WINAPI expRegSetValueExA(long key, const char* name, long v1, long v2, void* data, long size)
2088 long result=RegSetValueExA(key, name, v1, v2, data, size);
2089 dbgprintf("RegSetValueExA(key 0x%x, name '%s', 0x%x, 0x%x, data 0x%x -> 0x%x '%s', size=%d) => %d",
2090 key, name, v1, v2, data, *(int*)data, data, size, result);
2091 return result;
2094 static long WINAPI expRegOpenKeyA (long hKey, LPCSTR lpSubKey, int* phkResult)
2096 long result=RegOpenKeyExA(hKey, lpSubKey, 0, 0, phkResult);
2097 dbgprintf("RegOpenKeyExA(key 0x%x, subkey '%s', 0x%x) => %d\n",
2098 hKey, lpSubKey, phkResult, result);
2099 if(!result && phkResult) dbgprintf(" New key: 0x%x\n", *phkResult);
2100 return result;
2103 static DWORD WINAPI expRegEnumValueA(HKEY hkey, DWORD index, LPSTR value, LPDWORD val_count,
2104 LPDWORD reserved, LPDWORD type, LPBYTE data, LPDWORD count)
2106 return RegEnumValueA(hkey, index, value, val_count,
2107 reserved, type, data, count);
2110 static DWORD WINAPI expRegEnumKeyExA(HKEY hKey, DWORD dwIndex, LPSTR lpName, LPDWORD lpcbName,
2111 LPDWORD lpReserved, LPSTR lpClass, LPDWORD lpcbClass,
2112 LPFILETIME lpftLastWriteTime)
2114 return RegEnumKeyExA(hKey, dwIndex, lpName, lpcbName, lpReserved, lpClass,
2115 lpcbClass, lpftLastWriteTime);
2118 static long WINAPI expQueryPerformanceCounter(long long* z)
2120 longcount(z);
2121 dbgprintf("QueryPerformanceCounter(0x%x) => 1 ( %Ld )\n", z, *z);
2122 return 1;
2126 * dummy function RegQueryInfoKeyA(), required by vss codecs
2128 static DWORD WINAPI expRegQueryInfoKeyA( HKEY hkey, LPSTR class, LPDWORD class_len, LPDWORD reserved,
2129 LPDWORD subkeys, LPDWORD max_subkey, LPDWORD max_class,
2130 LPDWORD values, LPDWORD max_value, LPDWORD max_data,
2131 LPDWORD security, FILETIME *modif )
2133 return ERROR_SUCCESS;
2137 * return CPU clock (in kHz), using linux's /proc filesystem (/proc/cpuinfo)
2139 static double linux_cpuinfo_freq(void)
2141 double freq=-1;
2142 FILE *f;
2143 char line[200];
2144 char *s,*value;
2146 f = fopen ("/proc/cpuinfo", "r");
2147 if (f != NULL) {
2148 while (fgets(line,sizeof(line),f)!=NULL) {
2149 /* NOTE: the ':' is the only character we can rely on */
2150 if (!(value = strchr(line,':')))
2151 continue;
2152 /* terminate the valuename */
2153 *value++ = '\0';
2154 /* skip any leading spaces */
2155 while (*value==' ') value++;
2156 if ((s=strchr(value,'\n')))
2157 *s='\0';
2159 if (!strncasecmp(line, "cpu MHz",strlen("cpu MHz"))
2160 && sscanf(value, "%lf", &freq) == 1) {
2161 freq*=1000;
2162 break;
2165 fclose(f);
2167 return freq;
2171 static double solaris_kstat_freq(void)
2173 #if defined(HAVE_LIBKSTAT) && defined(KSTAT_DATA_INT32)
2175 * try to extract the CPU speed from the solaris kernel's kstat data
2177 kstat_ctl_t *kc;
2178 kstat_t *ksp;
2179 kstat_named_t *kdata;
2180 int mhz = 0;
2182 kc = kstat_open();
2183 if (kc != NULL)
2185 ksp = kstat_lookup(kc, "cpu_info", 0, "cpu_info0");
2187 /* kstat found and name/value pairs? */
2188 if (ksp != NULL && ksp->ks_type == KSTAT_TYPE_NAMED)
2190 /* read the kstat data from the kernel */
2191 if (kstat_read(kc, ksp, NULL) != -1)
2194 * lookup desired "clock_MHz" entry, check the expected
2195 * data type
2197 kdata = (kstat_named_t *)kstat_data_lookup(ksp, "clock_MHz");
2198 if (kdata != NULL && kdata->data_type == KSTAT_DATA_INT32)
2199 mhz = kdata->value.i32;
2202 kstat_close(kc);
2205 if (mhz > 0)
2206 return mhz * 1000.;
2207 #endif /* HAVE_LIBKSTAT */
2208 return -1; // kstat stuff is not available, CPU freq is unknown
2212 * Measure CPU freq using the pentium's time stamp counter register (TSC)
2214 static double tsc_freq(void)
2216 static double ofreq=0.0;
2217 int i;
2218 int x,y;
2219 i=time(NULL);
2220 if (ofreq != 0.0) return ofreq;
2221 while(i==time(NULL));
2222 x=localcount();
2223 i++;
2224 while(i==time(NULL));
2225 y=localcount();
2226 ofreq = (double)(y-x)/1000.;
2227 return ofreq;
2230 static double CPU_Freq(void)
2232 double freq;
2234 if ((freq = linux_cpuinfo_freq()) > 0)
2235 return freq;
2237 if ((freq = solaris_kstat_freq()) > 0)
2238 return freq;
2240 return tsc_freq();
2243 static long WINAPI expQueryPerformanceFrequency(long long* z)
2245 *z=(long long)CPU_Freq();
2246 dbgprintf("QueryPerformanceFrequency(0x%x) => 1 ( %Ld )\n", z, *z);
2247 return 1;
2249 static long WINAPI exptimeGetTime(void)
2251 struct timeval t;
2252 long result;
2253 gettimeofday(&t, 0);
2254 result=1000*t.tv_sec+t.tv_usec/1000;
2255 dbgprintf("timeGetTime() => %d\n", result);
2256 return result;
2258 static void* WINAPI expLocalHandle(void* v)
2260 dbgprintf("LocalHandle(0x%x) => 0x%x\n", v, v);
2261 return v;
2264 static void* WINAPI expGlobalHandle(void* v)
2266 dbgprintf("GlobalHandle(0x%x) => 0x%x\n", v, v);
2267 return v;
2269 static int WINAPI expGlobalUnlock(void* v)
2271 dbgprintf("GlobalUnlock(0x%x) => 1\n", v);
2272 return 1;
2274 static void* WINAPI expGlobalFree(void* v)
2276 dbgprintf("GlobalFree(0x%x) => 0\n", v);
2277 my_release(v);
2278 //free(v);
2279 return 0;
2282 static void* WINAPI expGlobalReAlloc(void* v, int size, int flags)
2284 void* result=my_realloc(v, size);
2285 //void* result=realloc(v, size);
2286 dbgprintf("GlobalReAlloc(0x%x, size %d, flags 0x%x) => 0x%x\n", v,size,flags,result);
2287 return result;
2290 static int WINAPI expLocalUnlock(void* v)
2292 dbgprintf("LocalUnlock(0x%x) => 1\n", v);
2293 return 1;
2296 static void* WINAPI expLocalFree(void* v)
2298 dbgprintf("LocalFree(0x%x) => 0\n", v);
2299 my_release(v);
2300 return 0;
2302 static HRSRC WINAPI expFindResourceA(HMODULE module, char* name, char* type)
2304 HRSRC result;
2306 result=FindResourceA(module, name, type);
2307 dbgprintf("FindResourceA(module 0x%x, name 0x%x(%s), type 0x%x(%s)) => 0x%x\n",
2308 module, name, HIWORD(name) ? name : "UNICODE", type, HIWORD(type) ? type : "UNICODE", result);
2309 return result;
2312 static HGLOBAL WINAPI expLoadResource(HMODULE module, HRSRC res)
2314 HGLOBAL result=LoadResource(module, res);
2315 dbgprintf("LoadResource(module 0x%x, resource 0x%x) => 0x%x\n", module, res, result);
2316 return result;
2318 static void* WINAPI expLockResource(long res)
2320 void* result=LockResource(res);
2321 dbgprintf("LockResource(0x%x) => 0x%x\n", res, result);
2322 return result;
2324 static int WINAPI expFreeResource(long res)
2326 int result=FreeResource(res);
2327 dbgprintf("FreeResource(0x%x) => %d\n", res, result);
2328 return result;
2330 //bool fun(HANDLE)
2331 //!0 on success
2332 static int WINAPI expCloseHandle(long v1)
2334 dbgprintf("CloseHandle(0x%x) => 1\n", v1);
2335 /* do not close stdin,stdout and stderr */
2336 if (v1 > 2)
2337 if (!close(v1))
2338 return 0;
2339 return 1;
2342 static const char* WINAPI expGetCommandLineA(void)
2344 dbgprintf("GetCommandLineA() => \"c:\\aviplay.exe\"\n");
2345 return "c:\\aviplay.exe";
2347 static short envs[]={'p', 'a', 't', 'h', ' ', 'c', ':', '\\', 0, 0};
2348 static LPWSTR WINAPI expGetEnvironmentStringsW(void)
2350 dbgprintf("GetEnvironmentStringsW() => 0\n", envs);
2351 return 0;
2353 static void * WINAPI expRtlZeroMemory(void *p, size_t len)
2355 void* result=memset(p,0,len);
2356 dbgprintf("RtlZeroMemory(0x%x, len %d) => 0x%x\n",p,len,result);
2357 return result;
2359 static void * WINAPI expRtlMoveMemory(void *dst, void *src, size_t len)
2361 void* result=memmove(dst,src,len);
2362 dbgprintf("RtlMoveMemory (dest 0x%x, src 0x%x, len %d) => 0x%x\n",dst,src,len,result);
2363 return result;
2366 static void * WINAPI expRtlFillMemory(void *p, int ch, size_t len)
2368 void* result=memset(p,ch,len);
2369 dbgprintf("RtlFillMemory(0x%x, char 0x%x, len %d) => 0x%x\n",p,ch,len,result);
2370 return result;
2372 static int WINAPI expFreeEnvironmentStringsW(short* strings)
2374 dbgprintf("FreeEnvironmentStringsW(0x%x) => 1\n", strings);
2375 return 1;
2377 static int WINAPI expFreeEnvironmentStringsA(char* strings)
2379 dbgprintf("FreeEnvironmentStringsA(0x%x) => 1\n", strings);
2380 return 1;
2383 static const char ch_envs[]=
2384 "__MSVCRT_HEAP_SELECT=__GLOBAL_HEAP_SELECTED,1\r\n"
2385 "PATH=C:\\;C:\\windows\\;C:\\windows\\system\r\n";
2386 static LPCSTR WINAPI expGetEnvironmentStrings(void)
2388 dbgprintf("GetEnvironmentStrings() => 0x%x\n", ch_envs);
2389 return (LPCSTR)ch_envs;
2390 // dbgprintf("GetEnvironmentStrings() => 0\n");
2391 // return 0;
2394 static int WINAPI expGetStartupInfoA(STARTUPINFOA *s)
2396 dbgprintf("GetStartupInfoA(0x%x) => 1\n");
2397 memset(s, 0, sizeof(*s));
2398 s->cb=sizeof(*s);
2399 // s->lpReserved="Reserved";
2400 // s->lpDesktop="Desktop";
2401 // s->lpTitle="Title";
2402 // s->dwX=s->dwY=0;
2403 // s->dwXSize=s->dwYSize=200;
2404 s->dwFlags=s->wShowWindow=1;
2405 // s->hStdInput=s->hStdOutput=s->hStdError=0x1234;
2406 dbgprintf(" cb=%d\n", s->cb);
2407 dbgprintf(" lpReserved='%s'\n", s->lpReserved);
2408 dbgprintf(" lpDesktop='%s'\n", s->lpDesktop);
2409 dbgprintf(" lpTitle='%s'\n", s->lpTitle);
2410 dbgprintf(" dwX=%d dwY=%d dwXSize=%d dwYSize=%d\n",
2411 s->dwX, s->dwY, s->dwXSize, s->dwYSize);
2412 dbgprintf(" dwXCountChars=%d dwYCountChars=%d dwFillAttribute=%d\n",
2413 s->dwXCountChars, s->dwYCountChars, s->dwFillAttribute);
2414 dbgprintf(" dwFlags=0x%x wShowWindow=0x%x cbReserved2=0x%x\n",
2415 s->dwFlags, s->wShowWindow, s->cbReserved2);
2416 dbgprintf(" lpReserved2=0x%x hStdInput=0x%x hStdOutput=0x%x hStdError=0x%x\n",
2417 s->lpReserved2, s->hStdInput, s->hStdOutput, s->hStdError);
2418 return 1;
2421 static int WINAPI expGetStdHandle(int z)
2423 dbgprintf("GetStdHandle(0x%x) => 0x%x\n", z+0x1234);
2424 return z+0x1234;
2427 #ifdef CONFIG_QTX_CODECS
2428 #define FILE_HANDLE_quicktimeqts ((HANDLE)0x444)
2429 #define FILE_HANDLE_quicktimeqtx ((HANDLE)0x445)
2430 #endif
2432 static int WINAPI expGetFileType(int handle)
2434 dbgprintf("GetFileType(0x%x) => 0x3 = pipe\n", handle);
2435 return 0x3;
2437 #ifdef CONFIG_QTX_CODECS
2438 static int WINAPI expGetFileAttributesA(char *filename)
2440 dbgprintf("GetFileAttributesA(%s) => FILE_ATTR_NORMAL\n", filename);
2441 if (strstr(filename, "QuickTime.qts"))
2442 return FILE_ATTRIBUTE_SYSTEM;
2443 return FILE_ATTRIBUTE_NORMAL;
2445 #endif
2446 static int WINAPI expSetHandleCount(int count)
2448 dbgprintf("SetHandleCount(0x%x) => 1\n", count);
2449 return 1;
2451 static int WINAPI expGetACP(void)
2453 dbgprintf("GetACP() => 0\n");
2454 return 0;
2456 static int WINAPI expGetModuleFileNameA(int module, char* s, int len)
2458 WINE_MODREF *mr;
2459 int result;
2460 //printf("File name of module %X (%s) requested\n", module, s);
2462 if (module == 0 && len >= 12)
2464 /* return caller program name */
2465 strcpy(s, "aviplay.dll");
2466 result=1;
2468 else if(s==0)
2469 result=0;
2470 else
2471 if(len<35)
2472 result=0;
2473 else
2475 result=1;
2476 strcpy(s, "c:\\windows\\system\\");
2477 mr=MODULE32_LookupHMODULE(module);
2478 if(mr==0)//oops
2479 strcat(s, "aviplay.dll");
2480 else
2481 if(strrchr(mr->filename, '/')==NULL)
2482 strcat(s, mr->filename);
2483 else
2484 strcat(s, strrchr(mr->filename, '/')+1);
2486 if(!s)
2487 dbgprintf("GetModuleFileNameA(0x%x, 0x%x, %d) => %d\n",
2488 module, s, len, result);
2489 else
2490 dbgprintf("GetModuleFileNameA(0x%x, 0x%x, %d) => %d ( '%s' )\n",
2491 module, s, len, result, s);
2492 return result;
2495 static int WINAPI expGetModuleBaseNameA(int process, int module, char* s, int len)
2497 int result = 0;
2499 if (s && len) {
2500 av_strlcpy(s, "aviplay.dll", len);
2501 result = strlen(s);
2504 dbgprintf("GetModuleBaseNameA(0x%x, 0x%x, 0x%x, %d) => %d\n",
2505 process, module, s, len, result);
2507 return result;
2510 static int WINAPI expSetUnhandledExceptionFilter(void* filter)
2512 dbgprintf("SetUnhandledExceptionFilter(0x%x) => 1\n", filter);
2513 return 1;//unsupported and probably won't ever be supported
2516 static int WINAPI expLoadLibraryA(char* name)
2518 int result = 0;
2519 char* lastbc;
2520 if (!name)
2521 return -1;
2522 // we skip to the last backslash
2523 // this is effectively eliminating weird characters in
2524 // the text output windows
2526 lastbc = strrchr(name, '\\');
2527 if (lastbc)
2529 int i;
2530 lastbc++;
2531 for (i = 0; 1 ;i++)
2533 name[i] = *lastbc++;
2534 if (!name[i])
2535 break;
2538 if(strncmp(name, "c:\\windows\\", 11)==0) name += 11;
2539 if(strncmp(name, ".\\", 2)==0) name += 2;
2541 dbgprintf("Entering LoadLibraryA(%s)\n", name);
2543 // PIMJ and VIVO audio are loading kernel32.dll
2544 if (strcasecmp(name, "kernel32.dll") == 0 || strcasecmp(name, "kernel32") == 0)
2545 return MODULE_HANDLE_kernel32;
2546 // return ERROR_SUCCESS; /* yeah, we have also the kernel32 calls */
2547 /* exported -> do not return failed! */
2549 if (strcasecmp(name, "user32.dll") == 0 || strcasecmp(name, "user32") == 0)
2550 // return MODULE_HANDLE_kernel32;
2551 return MODULE_HANDLE_user32;
2553 #ifdef CONFIG_QTX_CODECS
2554 if (strcasecmp(name, "wininet.dll") == 0 || strcasecmp(name, "wininet") == 0)
2555 return MODULE_HANDLE_wininet;
2556 if (strcasecmp(name, "ddraw.dll") == 0 || strcasecmp(name, "ddraw") == 0)
2557 return MODULE_HANDLE_ddraw;
2558 if (strcasecmp(name, "advapi32.dll") == 0 || strcasecmp(name, "advapi32") == 0)
2559 return MODULE_HANDLE_advapi32;
2560 #endif
2562 if (strcasecmp(name, "comdlg32.dll") == 0 || strcasecmp(name, "comdlg32") == 0)
2563 return MODULE_HANDLE_comdlg32;
2564 if (strcasecmp(name, "msvcrt.dll") == 0 || strcasecmp(name, "msvcrt") == 0)
2565 return MODULE_HANDLE_msvcrt;
2566 if (strcasecmp(name, "ole32.dll") == 0 || strcasecmp(name, "ole32") == 0)
2567 return MODULE_HANDLE_ole32;
2568 if (strcasecmp(name, "winmm.dll") == 0 || strcasecmp(name, "winmm") == 0)
2569 return MODULE_HANDLE_winmm;
2570 if (strcasecmp(name, "psapi.dll") == 0 || strcasecmp(name, "psapi") == 0)
2571 return MODULE_HANDLE_psapi;
2573 result=LoadLibraryA(name);
2574 dbgprintf("Returned LoadLibraryA(0x%x='%s'), codec_path=%s => 0x%x\n",
2575 name, name, codec_path, result);
2577 return result;
2580 static int WINAPI expFreeLibrary(int module)
2582 #ifdef CONFIG_QTX_CODECS
2583 int result=0; /* FIXME:XXX: qtx svq3 frees up qt.qts */
2584 #else
2585 int result=FreeLibrary(module);
2586 #endif
2587 dbgprintf("FreeLibrary(0x%x) => %d\n", module, result);
2588 return result;
2591 static void* WINAPI expGetProcAddress(HMODULE mod, char* name)
2593 void* result;
2594 switch(mod){
2595 case MODULE_HANDLE_kernel32:
2596 result=LookupExternalByName("kernel32.dll", name); break;
2597 case MODULE_HANDLE_user32:
2598 result=LookupExternalByName("user32.dll", name); break;
2599 #ifdef CONFIG_QTX_CODECS
2600 case MODULE_HANDLE_wininet:
2601 result=LookupExternalByName("wininet.dll", name); break;
2602 case MODULE_HANDLE_ddraw:
2603 result=LookupExternalByName("ddraw.dll", name); break;
2604 case MODULE_HANDLE_advapi32:
2605 result=LookupExternalByName("advapi32.dll", name); break;
2606 #endif
2607 case MODULE_HANDLE_comdlg32:
2608 result=LookupExternalByName("comdlg32.dll", name); break;
2609 case MODULE_HANDLE_msvcrt:
2610 result=LookupExternalByName("msvcrt.dll", name); break;
2611 case MODULE_HANDLE_ole32:
2612 result=LookupExternalByName("ole32.dll", name); break;
2613 case MODULE_HANDLE_winmm:
2614 result=LookupExternalByName("winmm.dll", name); break;
2615 case MODULE_HANDLE_psapi:
2616 result=LookupExternalByName("psapi.dll", name); break;
2617 default:
2618 result=GetProcAddress(mod, name);
2620 if((unsigned int)name > 0xffff)
2621 dbgprintf("GetProcAddress(0x%x, '%s') => 0x%x\n", mod, name, result);
2622 else
2623 dbgprintf("GetProcAddress(0x%x, '%d') => 0x%x\n", mod, (int)name, result);
2624 return result;
2627 static long WINAPI expCreateFileMappingA(int hFile, void* lpAttr,
2628 long flProtect, long dwMaxHigh,
2629 long dwMaxLow, const char* name)
2631 long result=CreateFileMappingA(hFile, lpAttr, flProtect, dwMaxHigh, dwMaxLow, name);
2632 if(!name)
2633 dbgprintf("CreateFileMappingA(file 0x%x, lpAttr 0x%x,"
2634 "flProtect 0x%x, dwMaxHigh 0x%x, dwMaxLow 0x%x, name 0) => %d\n",
2635 hFile, lpAttr, flProtect, dwMaxHigh, dwMaxLow, result);
2636 else
2637 dbgprintf("CreateFileMappingA(file 0x%x, lpAttr 0x%x,"
2638 "flProtect 0x%x, dwMaxHigh 0x%x, dwMaxLow 0x%x, name 0x%x='%s') => %d\n",
2639 hFile, lpAttr, flProtect, dwMaxHigh, dwMaxLow, name, name, result);
2640 return result;
2643 static long WINAPI expOpenFileMappingA(long hFile, long hz, const char* name)
2645 long result=OpenFileMappingA(hFile, hz, name);
2646 if(!name)
2647 dbgprintf("OpenFileMappingA(0x%x, 0x%x, 0) => %d\n",
2648 hFile, hz, result);
2649 else
2650 dbgprintf("OpenFileMappingA(0x%x, 0x%x, 0x%x='%s') => %d\n",
2651 hFile, hz, name, name, result);
2652 return result;
2655 static void* WINAPI expMapViewOfFile(HANDLE file, DWORD mode, DWORD offHigh,
2656 DWORD offLow, DWORD size)
2658 dbgprintf("MapViewOfFile(0x%x, 0x%x, 0x%x, 0x%x, size %d) => 0x%x\n",
2659 file,mode,offHigh,offLow,size,(char*)file+offLow);
2660 return (char*)file+offLow;
2663 static void* WINAPI expUnmapViewOfFile(void* view)
2665 dbgprintf("UnmapViewOfFile(0x%x) => 0\n", view);
2666 return 0;
2669 static void* WINAPI expSleep(int time)
2671 #if HAVE_NANOSLEEP
2672 /* solaris doesn't have thread safe usleep */
2673 struct timespec tsp;
2674 tsp.tv_sec = time / 1000000;
2675 tsp.tv_nsec = (time % 1000000) * 1000;
2676 nanosleep(&tsp, NULL);
2677 #else
2678 usleep(time);
2679 #endif
2680 dbgprintf("Sleep(%d) => 0\n", time);
2681 return 0;
2684 // why does IV32 codec want to call this? I don't know ...
2685 static int WINAPI expCreateCompatibleDC(int hdc)
2687 int dc = 0;//0x81;
2688 //dbgprintf("CreateCompatibleDC(%d) => 0x81\n", hdc);
2689 dbgprintf("CreateCompatibleDC(%d) => %d\n", hdc, dc);
2690 return dc;
2693 static int WINAPI expGetDeviceCaps(int hdc, int unk)
2695 dbgprintf("GetDeviceCaps(0x%x, %d) => 0\n", hdc, unk);
2696 #ifdef CONFIG_QTX_CODECS
2697 #define BITSPIXEL 12
2698 #define PLANES 14
2699 if (unk == BITSPIXEL)
2700 return 24;
2701 if (unk == PLANES)
2702 return 1;
2703 #endif
2704 return 1;
2707 static WIN_BOOL WINAPI expDeleteDC(int hdc)
2709 dbgprintf("DeleteDC(0x%x) => 0\n", hdc);
2710 if (hdc == 0x81)
2711 return 1;
2712 return 0;
2715 static WIN_BOOL WINAPI expDeleteObject(int hdc)
2717 dbgprintf("DeleteObject(0x%x) => 1\n", hdc);
2718 /* FIXME - implement code here */
2719 return 1;
2722 /* btvvc32.drv wants this one */
2723 static void* WINAPI expGetWindowDC(int hdc)
2725 dbgprintf("GetWindowDC(%d) => 0x0\n", hdc);
2726 return 0;
2729 #ifdef CONFIG_QTX_CODECS
2730 static int WINAPI expGetWindowRect(HWND win, RECT *r)
2732 dbgprintf("GetWindowRect(0x%x, 0x%x) => 1\n", win, r);
2733 /* (win == 0) => desktop */
2734 r->right = PSEUDO_SCREEN_WIDTH;
2735 r->left = 0;
2736 r->bottom = PSEUDO_SCREEN_HEIGHT;
2737 r->top = 0;
2738 return 1;
2741 static int WINAPI expMonitorFromWindow(HWND win, int flags)
2743 dbgprintf("MonitorFromWindow(0x%x, 0x%x) => 0\n", win, flags);
2744 return 0;
2747 static int WINAPI expMonitorFromRect(RECT *r, int flags)
2749 dbgprintf("MonitorFromRect(0x%x, 0x%x) => 0\n", r, flags);
2750 return 0;
2753 static int WINAPI expMonitorFromPoint(void *p, int flags)
2755 dbgprintf("MonitorFromPoint(0x%x, 0x%x) => 0\n", p, flags);
2756 return 0;
2759 static int WINAPI expEnumDisplayMonitors(void *dc, RECT *r,
2760 int WINAPI (*callback_proc)(), void *callback_param)
2762 dbgprintf("EnumDisplayMonitors(0x%x, 0x%x, 0x%x, 0x%x) => ?\n",
2763 dc, r, callback_proc, callback_param);
2764 return callback_proc(0, dc, r, callback_param);
2767 #if 0
2768 typedef struct tagMONITORINFO {
2769 DWORD cbSize;
2770 RECT rcMonitor;
2771 RECT rcWork;
2772 DWORD dwFlags;
2773 } MONITORINFO, *LPMONITORINFO;
2774 #endif
2776 #define CCHDEVICENAME 8
2777 typedef struct tagMONITORINFOEX {
2778 DWORD cbSize;
2779 RECT rcMonitor;
2780 RECT rcWork;
2781 DWORD dwFlags;
2782 TCHAR szDevice[CCHDEVICENAME];
2783 } MONITORINFOEX, *LPMONITORINFOEX;
2785 static int WINAPI expGetMonitorInfoA(void *mon, LPMONITORINFO lpmi)
2787 dbgprintf("GetMonitorInfoA(0x%x, 0x%x) => 1\n", mon, lpmi);
2789 lpmi->rcMonitor.right = lpmi->rcWork.right = PSEUDO_SCREEN_WIDTH;
2790 lpmi->rcMonitor.left = lpmi->rcWork.left = 0;
2791 lpmi->rcMonitor.bottom = lpmi->rcWork.bottom = PSEUDO_SCREEN_HEIGHT;
2792 lpmi->rcMonitor.top = lpmi->rcWork.top = 0;
2794 lpmi->dwFlags = 1; /* primary monitor */
2796 if (lpmi->cbSize == sizeof(MONITORINFOEX))
2798 LPMONITORINFOEX lpmiex = (LPMONITORINFOEX)lpmi;
2799 dbgprintf("MONITORINFOEX!\n");
2800 strncpy(lpmiex->szDevice, "Monitor1", CCHDEVICENAME);
2803 return 1;
2806 static int WINAPI expEnumDisplayDevicesA(const char *device, int devnum,
2807 void *dispdev, int flags)
2809 dbgprintf("EnumDisplayDevicesA(0x%x = %s, %d, 0x%x, %x) => 1\n",
2810 device, device, devnum, dispdev, flags);
2811 return 1;
2814 static int WINAPI expIsWindowVisible(HWND win)
2816 dbgprintf("IsWindowVisible(0x%x) => 1\n", win);
2817 return 1;
2820 static HWND WINAPI expGetActiveWindow(void)
2822 dbgprintf("GetActiveWindow() => 0\n");
2823 return (HWND)0;
2826 static int WINAPI expGetClassNameA(HWND win, LPTSTR classname, int maxcount)
2828 strncat(classname, "QuickTime", maxcount);
2829 dbgprintf("GetClassNameA(0x%x, 0x%x, %d) => %d\n",
2830 win, classname, maxcount, strlen(classname));
2831 return strlen(classname);
2834 #define LPWNDCLASS void *
2835 static int WINAPI expGetClassInfoA(HINSTANCE inst, LPCSTR classname, LPWNDCLASS wndclass)
2837 dbgprintf("GetClassInfoA(0x%x, 0x%x = %s, 0x%x) => 1\n", inst,
2838 classname, classname, wndclass);
2839 return 1;
2842 static int WINAPI expGetWindowLongA(HWND win, int index)
2844 dbgprintf("GetWindowLongA(0x%x, %d) => 0\n", win, index);
2845 return 1;
2848 static int WINAPI expGetObjectA(HGDIOBJ hobj, int objsize, LPVOID obj)
2850 dbgprintf("GetObjectA(0x%x, %d, 0x%x) => %d\n", hobj, objsize, obj, objsize);
2851 return objsize;
2854 static int WINAPI expCreateRectRgn(int x, int y, int width, int height)
2856 dbgprintf("CreateRectRgn(%d, %d, %d, %d) => 0\n", x, y, width, height);
2857 return 0;
2860 static int WINAPI expEnumWindows(int (*callback_func)(), void *callback_param)
2862 int i, i2;
2863 dbgprintf("EnumWindows(0x%x, 0x%x) => 1\n", callback_func, callback_param);
2864 i = callback_func(0, callback_param);
2865 i2 = callback_func(1, callback_param);
2866 return i && i2;
2869 static int WINAPI expGetWindowThreadProcessId(HWND win, int *pid_data)
2871 int tid = pthread_self();
2872 dbgprintf("GetWindowThreadProcessId(0x%x, 0x%x) => %d\n",
2873 win, pid_data, tid);
2874 if (pid_data)
2875 *(int*)pid_data = tid;
2876 return tid;
2879 //HWND WINAPI CreateWindowExA(DWORD,LPCSTR,LPCSTR,DWORD,INT,INT,
2880 // INT,INT,HWND,HMENU,HINSTANCE,LPVOID);
2882 static HWND WINAPI expCreateWindowExA(int exstyle, const char *classname,
2883 const char *winname, int style, int x, int y, int w, int h,
2884 HWND parent, HMENU menu, HINSTANCE inst, LPVOID param)
2886 printf("CreateWindowEx() called\n");
2887 dbgprintf("CreateWindowEx(%d, 0x%x = %s, 0x%x = %s, %d, %d, %d, %d, %d, 0x%x, 0x%x, 0x%x, 0x%x) => 1\n",
2888 exstyle, classname, classname, winname, winname, style, x, y, w, h,
2889 parent, menu, inst, param);
2890 printf("CreateWindowEx() called okey\n");
2891 return 1;
2894 static int WINAPI expwaveOutGetNumDevs(void)
2896 dbgprintf("waveOutGetNumDevs() => 0\n");
2897 return 0;
2899 #endif
2902 * Returns the number of milliseconds, modulo 2^32, since the start
2903 * of the wineserver.
2905 static int WINAPI expGetTickCount(void)
2907 static int tcstart = 0;
2908 struct timeval t;
2909 int tc;
2910 gettimeofday( &t, NULL );
2911 tc = ((t.tv_sec * 1000) + (t.tv_usec / 1000)) - tcstart;
2912 if (tcstart == 0)
2914 tcstart = 0;
2915 tc = 0;
2917 dbgprintf("GetTickCount() => %d\n", tc);
2918 return tc;
2921 static int WINAPI expCreateFontA(void)
2923 dbgprintf("CreateFontA() => 0x0\n");
2924 return 1;
2927 /* tried to get pvmjpg work in a different way - no success */
2928 static int WINAPI expDrawTextA(int hDC, char* lpString, int nCount,
2929 LPRECT lpRect, unsigned int uFormat)
2931 dbgprintf("expDrawTextA(%p,...) => 8\n", hDC);
2932 return 8;
2935 static int WINAPI expGetPrivateProfileIntA(const char* appname,
2936 const char* keyname,
2937 int default_value,
2938 const char* filename)
2940 int size=255;
2941 char buffer[256];
2942 char* fullname;
2943 int result;
2945 buffer[255]=0;
2946 if(!(appname && keyname && filename) )
2948 dbgprintf("GetPrivateProfileIntA('%s', '%s', %d, '%s') => %d\n", appname, keyname, default_value, filename, default_value );
2949 return default_value;
2951 fullname=malloc(50+strlen(appname)+strlen(keyname)+strlen(filename));
2952 strcpy(fullname, "Software\\IniFileMapping\\");
2953 strcat(fullname, appname);
2954 strcat(fullname, "\\");
2955 strcat(fullname, keyname);
2956 strcat(fullname, "\\");
2957 strcat(fullname, filename);
2958 result=RegQueryValueExA(HKEY_LOCAL_MACHINE, fullname, NULL, NULL, (int*)buffer, &size);
2959 if((size>=0)&&(size<256))
2960 buffer[size]=0;
2961 // printf("GetPrivateProfileIntA(%s, %s, %s) -> %s\n", appname, keyname, filename, buffer);
2962 free(fullname);
2963 if(result)
2964 result=default_value;
2965 else
2966 result=atoi(buffer);
2967 dbgprintf("GetPrivateProfileIntA('%s', '%s', %d, '%s') => %d\n", appname, keyname, default_value, filename, result);
2968 return result;
2970 static int WINAPI expGetProfileIntA(const char* appname,
2971 const char* keyname,
2972 int default_value)
2974 dbgprintf("GetProfileIntA -> ");
2975 return expGetPrivateProfileIntA(appname, keyname, default_value, "default");
2978 static int WINAPI expGetPrivateProfileStringA(const char* appname,
2979 const char* keyname,
2980 const char* def_val,
2981 char* dest, unsigned int len,
2982 const char* filename)
2984 int result;
2985 int size;
2986 char* fullname;
2987 dbgprintf("GetPrivateProfileStringA('%s', '%s', def_val '%s', 0x%x, 0x%x, '%s')", appname, keyname, def_val, dest, len, filename );
2988 if(!(appname && keyname && filename) ) return 0;
2989 fullname=malloc(50+strlen(appname)+strlen(keyname)+strlen(filename));
2990 strcpy(fullname, "Software\\IniFileMapping\\");
2991 strcat(fullname, appname);
2992 strcat(fullname, "\\");
2993 strcat(fullname, keyname);
2994 strcat(fullname, "\\");
2995 strcat(fullname, filename);
2996 size=len;
2997 result=RegQueryValueExA(HKEY_LOCAL_MACHINE, fullname, NULL, NULL, (int*)dest, &size);
2998 free(fullname);
2999 if(result)
3001 strncpy(dest, def_val, size);
3002 if (strlen(def_val)< size) size = strlen(def_val);
3004 dbgprintf(" => %d ( '%s' )\n", size, dest);
3005 return size;
3007 static int WINAPI expWritePrivateProfileStringA(const char* appname,
3008 const char* keyname,
3009 const char* string,
3010 const char* filename)
3012 char* fullname;
3013 dbgprintf("WritePrivateProfileStringA('%s', '%s', '%s', '%s')", appname, keyname, string, filename );
3014 if(!(appname && keyname && filename) )
3016 dbgprintf(" => -1\n");
3017 return -1;
3019 fullname=malloc(50+strlen(appname)+strlen(keyname)+strlen(filename));
3020 strcpy(fullname, "Software\\IniFileMapping\\");
3021 strcat(fullname, appname);
3022 strcat(fullname, "\\");
3023 strcat(fullname, keyname);
3024 strcat(fullname, "\\");
3025 strcat(fullname, filename);
3026 RegSetValueExA(HKEY_LOCAL_MACHINE, fullname, 0, REG_SZ, (int*)string, strlen(string));
3027 // printf("RegSetValueExA(%s,%d)\n", string, strlen(string));
3028 // printf("WritePrivateProfileStringA(%s, %s, %s, %s)\n", appname, keyname, string, filename );
3029 free(fullname);
3030 dbgprintf(" => 0\n");
3031 return 0;
3034 unsigned int GetPrivateProfileIntA_(const char* appname, const char* keyname, INT default_value, const char* filename)
3036 return expGetPrivateProfileIntA(appname, keyname, default_value, filename);
3038 int GetPrivateProfileStringA_(const char* appname, const char* keyname,
3039 const char* def_val, char* dest, unsigned int len, const char* filename)
3041 return expGetPrivateProfileStringA(appname, keyname, def_val, dest, len, filename);
3043 int WritePrivateProfileStringA_(const char* appname, const char* keyname,
3044 const char* string, const char* filename)
3046 return expWritePrivateProfileStringA(appname, keyname, string, filename);
3051 static int WINAPI expDefDriverProc(int private, int id, int msg, int arg1, int arg2)
3053 dbgprintf("DefDriverProc(0x%x, 0x%x, 0x%x, 0x%x, 0x%x) => 0\n", private, id, msg, arg1, arg2);
3054 return 0;
3057 static int WINAPI expSizeofResource(int v1, int v2)
3059 int result=SizeofResource(v1, v2);
3060 dbgprintf("SizeofResource(0x%x, 0x%x) => %d\n", v1, v2, result);
3061 return result;
3064 static int WINAPI expGetLastError(void)
3066 int result=GetLastError();
3067 dbgprintf("GetLastError() => 0x%x\n", result);
3068 return result;
3071 static void WINAPI expSetLastError(int error)
3073 dbgprintf("SetLastError(0x%x)\n", error);
3074 SetLastError(error);
3077 static int WINAPI expStringFromGUID2(GUID* guid, char* str, int cbMax)
3079 int result=snprintf(str, cbMax, "%.8x-%.4x-%.4x-%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x",
3080 guid->f1, guid->f2, guid->f3,
3081 (unsigned char)guid->f4[0], (unsigned char)guid->f4[1],
3082 (unsigned char)guid->f4[2], (unsigned char)guid->f4[3],
3083 (unsigned char)guid->f4[4], (unsigned char)guid->f4[5],
3084 (unsigned char)guid->f4[6], (unsigned char)guid->f4[7]);
3085 dbgprintf("StringFromGUID2(0x%x, 0x%x='%s', %d) => %d\n", guid, str, str, cbMax, result);
3086 return result;
3090 static int WINAPI expGetFileVersionInfoSizeA(const char* name, int* lpHandle)
3092 dbgprintf("GetFileVersionInfoSizeA(0x%x='%s', 0x%X) => 0\n", name, name, lpHandle);
3093 return 0;
3096 static int WINAPI expIsBadStringPtrW(const short* string, int nchars)
3098 int result;
3099 if(string==0)result=1; else result=0;
3100 dbgprintf("IsBadStringPtrW(0x%x, %d) => %d", string, nchars, result);
3101 if(string)wch_print(string);
3102 return result;
3104 static int WINAPI expIsBadStringPtrA(const char* string, int nchars)
3106 return expIsBadStringPtrW((const short*)string, nchars);
3108 static long WINAPI expInterlockedExchangeAdd( long* dest, long incr )
3110 long ret;
3111 __asm__ volatile
3113 "lock; xaddl %0,(%1)"
3114 : "=r" (ret)
3115 : "r" (dest), "0" (incr)
3116 : "memory"
3118 return ret;
3121 static long WINAPI expInterlockedCompareExchange( unsigned long* dest, unsigned long exchange, unsigned long comperand)
3123 unsigned long retval = *dest;
3124 if(*dest == comperand)
3125 *dest = exchange;
3126 return retval;
3129 static long WINAPI expInterlockedIncrement( long* dest )
3131 long result=expInterlockedExchangeAdd( dest, 1 ) + 1;
3132 dbgprintf("InterlockedIncrement(0x%x => %d) => %d\n", dest, *dest, result);
3133 return result;
3135 static long WINAPI expInterlockedDecrement( long* dest )
3137 long result=expInterlockedExchangeAdd( dest, -1 ) - 1;
3138 dbgprintf("InterlockedDecrement(0x%x => %d) => %d\n", dest, *dest, result);
3139 return result;
3142 static void WINAPI expOutputDebugStringA( const char* string )
3144 dbgprintf("OutputDebugStringA(0x%x='%s')\n", string);
3145 fprintf(stderr, "DEBUG: %s\n", string);
3148 static int WINAPI expGetDC(int hwnd)
3150 dbgprintf("GetDC(0x%x) => 1\n", hwnd);
3151 return 1;
3154 static int WINAPI expReleaseDC(int hwnd, int hdc)
3156 dbgprintf("ReleaseDC(0x%x, 0x%x) => 1\n", hwnd, hdc);
3157 return 1;
3160 static int WINAPI expGetDesktopWindow(void)
3162 dbgprintf("GetDesktopWindow() => 0\n");
3163 return 0;
3166 static int cursor[100];
3168 static int WINAPI expLoadCursorA(int handle,LPCSTR name)
3170 dbgprintf("LoadCursorA(%d, 0x%x='%s') => 0x%x\n", handle, name, (int)&cursor[0]);
3171 return (int)&cursor[0];
3173 static int WINAPI expSetCursor(void *cursor)
3175 dbgprintf("SetCursor(0x%x) => 0x%x\n", cursor, cursor);
3176 return (int)cursor;
3178 static int WINAPI expGetCursorPos(void *cursor)
3180 dbgprintf("GetCursorPos(0x%x) => 0x%x\n", cursor, cursor);
3181 return 1;
3183 #ifdef CONFIG_QTX_CODECS
3184 static int show_cursor = 0;
3185 static int WINAPI expShowCursor(int show)
3187 dbgprintf("ShowCursor(%d) => %d\n", show, show);
3188 if (show)
3189 show_cursor++;
3190 else
3191 show_cursor--;
3192 return show_cursor;
3194 #endif
3195 static int WINAPI expRegisterWindowMessageA(char *message)
3197 dbgprintf("RegisterWindowMessageA(%s)\n", message);
3198 return 1;
3200 static int WINAPI expGetProcessVersion(int pid)
3202 dbgprintf("GetProcessVersion(%d)\n", pid);
3203 return 1;
3205 static int WINAPI expGetCurrentThread(void)
3207 #warning FIXME!
3208 dbgprintf("GetCurrentThread() => %x\n", 0xcfcf9898);
3209 return 0xcfcf9898;
3211 static int WINAPI expGetOEMCP(void)
3213 dbgprintf("GetOEMCP()\n");
3214 return 1;
3216 static int WINAPI expGetCPInfo(int cp,void *info)
3218 dbgprintf("GetCPInfo()\n");
3219 return 0;
3221 #ifdef CONFIG_QTX_CODECS
3222 #define SM_CXSCREEN 0
3223 #define SM_CYSCREEN 1
3224 #define SM_XVIRTUALSCREEN 76
3225 #define SM_YVIRTUALSCREEN 77
3226 #define SM_CXVIRTUALSCREEN 78
3227 #define SM_CYVIRTUALSCREEN 79
3228 #define SM_CMONITORS 80
3229 #endif
3230 static int WINAPI expGetSystemMetrics(int index)
3232 dbgprintf("GetSystemMetrics(%d)\n", index);
3233 #ifdef CONFIG_QTX_CODECS
3234 switch(index)
3236 case SM_XVIRTUALSCREEN:
3237 case SM_YVIRTUALSCREEN:
3238 return 0;
3239 case SM_CXSCREEN:
3240 case SM_CXVIRTUALSCREEN:
3241 return PSEUDO_SCREEN_WIDTH;
3242 case SM_CYSCREEN:
3243 case SM_CYVIRTUALSCREEN:
3244 return PSEUDO_SCREEN_HEIGHT;
3245 case SM_CMONITORS:
3246 return 1;
3248 #endif
3249 return 1;
3251 static int WINAPI expGetSysColor(int index)
3253 dbgprintf("GetSysColor(%d) => 1\n", index);
3254 return 1;
3256 static int WINAPI expGetSysColorBrush(int index)
3258 dbgprintf("GetSysColorBrush(%d)\n", index);
3259 return 1;
3264 static int WINAPI expGetSystemPaletteEntries(int hdc, int iStartIndex, int nEntries, void* lppe)
3266 dbgprintf("GetSystemPaletteEntries(0x%x, 0x%x, 0x%x, 0x%x) => 0\n",
3267 hdc, iStartIndex, nEntries, lppe);
3268 return 0;
3272 typedef struct TIME_ZONE_INFORMATION {
3273 long Bias;
3274 char StandardName[32];
3275 SYSTEMTIME StandardDate;
3276 long StandardBias;
3277 char DaylightName[32];
3278 SYSTEMTIME DaylightDate;
3279 long DaylightBias;
3280 } TIME_ZONE_INFORMATION, *LPTIME_ZONE_INFORMATION;
3283 static int WINAPI expGetTimeZoneInformation(LPTIME_ZONE_INFORMATION lpTimeZoneInformation)
3285 const short name[]={'C', 'e', 'n', 't', 'r', 'a', 'l', ' ', 'S', 't', 'a',
3286 'n', 'd', 'a', 'r', 'd', ' ', 'T', 'i', 'm', 'e', 0};
3287 const short pname[]={'C', 'e', 'n', 't', 'r', 'a', 'l', ' ', 'D', 'a', 'y',
3288 'l', 'i', 'g', 'h', 't', ' ', 'T', 'i', 'm', 'e', 0};
3289 dbgprintf("GetTimeZoneInformation(0x%x) => TIME_ZONE_ID_STANDARD\n");
3290 memset(lpTimeZoneInformation, 0, sizeof(TIME_ZONE_INFORMATION));
3291 lpTimeZoneInformation->Bias=360;//GMT-6
3292 memcpy(lpTimeZoneInformation->StandardName, name, sizeof(name));
3293 lpTimeZoneInformation->StandardDate.wMonth=10;
3294 lpTimeZoneInformation->StandardDate.wDay=5;
3295 lpTimeZoneInformation->StandardDate.wHour=2;
3296 lpTimeZoneInformation->StandardBias=0;
3297 memcpy(lpTimeZoneInformation->DaylightName, pname, sizeof(pname));
3298 lpTimeZoneInformation->DaylightDate.wMonth=4;
3299 lpTimeZoneInformation->DaylightDate.wDay=1;
3300 lpTimeZoneInformation->DaylightDate.wHour=2;
3301 lpTimeZoneInformation->DaylightBias=-60;
3302 return TIME_ZONE_ID_STANDARD;
3305 static void WINAPI expGetLocalTime(SYSTEMTIME* systime)
3307 time_t local_time;
3308 struct tm *local_tm;
3309 struct timeval tv;
3311 dbgprintf("GetLocalTime(0x%x)\n");
3312 gettimeofday(&tv, NULL);
3313 local_time=tv.tv_sec;
3314 local_tm=localtime(&local_time);
3316 systime->wYear = local_tm->tm_year + 1900;
3317 systime->wMonth = local_tm->tm_mon + 1;
3318 systime->wDayOfWeek = local_tm->tm_wday;
3319 systime->wDay = local_tm->tm_mday;
3320 systime->wHour = local_tm->tm_hour;
3321 systime->wMinute = local_tm->tm_min;
3322 systime->wSecond = local_tm->tm_sec;
3323 systime->wMilliseconds = (tv.tv_usec / 1000) % 1000;
3324 dbgprintf(" Year: %d\n Month: %d\n Day of week: %d\n"
3325 " Day: %d\n Hour: %d\n Minute: %d\n Second: %d\n"
3326 " Milliseconds: %d\n",
3327 systime->wYear, systime->wMonth, systime->wDayOfWeek, systime->wDay,
3328 systime->wHour, systime->wMinute, systime->wSecond, systime->wMilliseconds);
3331 static int WINAPI expGetSystemTime(SYSTEMTIME* systime)
3333 time_t local_time;
3334 struct tm *local_tm;
3335 struct timeval tv;
3337 dbgprintf("GetSystemTime(0x%x)\n", systime);
3338 gettimeofday(&tv, NULL);
3339 local_time=tv.tv_sec;
3340 local_tm=gmtime(&local_time);
3342 systime->wYear = local_tm->tm_year + 1900;
3343 systime->wMonth = local_tm->tm_mon + 1;
3344 systime->wDayOfWeek = local_tm->tm_wday;
3345 systime->wDay = local_tm->tm_mday;
3346 systime->wHour = local_tm->tm_hour;
3347 systime->wMinute = local_tm->tm_min;
3348 systime->wSecond = local_tm->tm_sec;
3349 systime->wMilliseconds = (tv.tv_usec / 1000) % 1000;
3350 dbgprintf(" Year: %d\n Month: %d\n Day of week: %d\n"
3351 " Day: %d\n Hour: %d\n Minute: %d\n Second: %d\n"
3352 " Milliseconds: %d\n",
3353 systime->wYear, systime->wMonth, systime->wDayOfWeek, systime->wDay,
3354 systime->wHour, systime->wMinute, systime->wSecond, systime->wMilliseconds);
3355 return 0;
3358 #define SECS_1601_TO_1970 ((369 * 365 + 89) * 86400ULL)
3359 static void WINAPI expGetSystemTimeAsFileTime(FILETIME* systime)
3361 struct timeval tv;
3362 unsigned long long secs;
3364 dbgprintf("GetSystemTime(0x%x)\n", systime);
3365 gettimeofday(&tv, NULL);
3366 secs = (tv.tv_sec + SECS_1601_TO_1970) * 10000000;
3367 secs += tv.tv_usec * 10;
3368 systime->dwLowDateTime = secs & 0xffffffff;
3369 systime->dwHighDateTime = (secs >> 32);
3372 static int WINAPI expGetEnvironmentVariableA(const char* name, char* field, int size)
3374 //char *p;
3375 // printf("%s %x %x\n", name, field, size);
3376 if(field)field[0]=0;
3378 p = getenv(name);
3379 if (p) strncpy(field,p,size);
3381 if (strcmp(name,"__MSVCRT_HEAP_SELECT")==0)
3382 strcpy(field,"__GLOBAL_HEAP_SELECTED,1");
3383 dbgprintf("GetEnvironmentVariableA(0x%x='%s', 0x%x, %d) => %d\n", name, name, field, size, strlen(field));
3384 return strlen(field);
3387 static int WINAPI expSetEnvironmentVariableA(const char *name, const char *value)
3389 dbgprintf("SetEnvironmentVariableA(%s, %s)\n", name, value);
3390 return 0;
3393 static void* WINAPI expCoTaskMemAlloc(ULONG cb)
3395 return my_mreq(cb, 0);
3397 static void WINAPI expCoTaskMemFree(void* cb)
3399 my_release(cb);
3405 void* CoTaskMemAlloc(unsigned long cb)
3407 return expCoTaskMemAlloc(cb);
3409 void CoTaskMemFree(void* cb)
3411 expCoTaskMemFree(cb);
3414 struct COM_OBJECT_INFO
3416 GUID clsid;
3417 long (*GetClassObject) (GUID* clsid, const GUID* iid, void** ppv);
3420 static struct COM_OBJECT_INFO* com_object_table=0;
3421 static int com_object_size=0;
3422 int RegisterComClass(const GUID* clsid, GETCLASSOBJECT gcs)
3424 if(!clsid || !gcs)
3425 return -1;
3426 com_object_table=realloc(com_object_table, sizeof(struct COM_OBJECT_INFO)*(++com_object_size));
3427 com_object_table[com_object_size-1].clsid=*clsid;
3428 com_object_table[com_object_size-1].GetClassObject=gcs;
3429 return 0;
3432 int UnregisterComClass(const GUID* clsid, GETCLASSOBJECT gcs)
3434 int found = 0;
3435 int i = 0;
3436 if(!clsid || !gcs)
3437 return -1;
3439 if (com_object_table == 0)
3440 printf("Warning: UnregisterComClass() called without any registered class\n");
3441 while (i < com_object_size)
3443 if (found && i > 0)
3445 memcpy(&com_object_table[i - 1].clsid,
3446 &com_object_table[i].clsid, sizeof(GUID));
3447 com_object_table[i - 1].GetClassObject =
3448 com_object_table[i].GetClassObject;
3450 else if (memcmp(&com_object_table[i].clsid, clsid, sizeof(GUID)) == 0
3451 && com_object_table[i].GetClassObject == gcs)
3453 found++;
3455 i++;
3457 if (found)
3459 if (--com_object_size == 0)
3461 free(com_object_table);
3462 com_object_table = 0;
3465 return 0;
3469 const GUID IID_IUnknown =
3471 0x00000000, 0x0000, 0x0000,
3472 {0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}
3474 const GUID IID_IClassFactory =
3476 0x00000001, 0x0000, 0x0000,
3477 {0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}
3480 static long WINAPI expCoCreateInstance(GUID* rclsid, struct IUnknown* pUnkOuter,
3481 long dwClsContext, const GUID* riid, void** ppv)
3483 int i;
3484 struct COM_OBJECT_INFO* ci=0;
3485 for(i=0; i<com_object_size; i++)
3486 if(!memcmp(rclsid, &com_object_table[i].clsid, sizeof(GUID)))
3487 ci=&com_object_table[i];
3488 if(!ci)return REGDB_E_CLASSNOTREG;
3489 // in 'real' world we should mess with IClassFactory here
3490 i=ci->GetClassObject(rclsid, riid, ppv);
3491 return i;
3494 long CoCreateInstance(GUID* rclsid, struct IUnknown* pUnkOuter,
3495 long dwClsContext, const GUID* riid, void** ppv)
3497 return expCoCreateInstance(rclsid, pUnkOuter, dwClsContext, riid, ppv);
3500 static int WINAPI expIsRectEmpty(CONST RECT *lprc)
3502 int r = 0;
3503 int w,h;
3504 //trapbug();
3505 if (lprc)
3507 w = lprc->right - lprc->left;
3508 h = lprc->bottom - lprc->top;
3509 if (w <= 0 || h <= 0)
3510 r = 1;
3512 else
3513 r = 1;
3515 dbgprintf("IsRectEmpty(%p) => %s\n", lprc, (r) ? "TRUE" : "FALSE");
3516 //printf("Rect: left: %d, top: %d, right: %d, bottom: %d\n", lprc->left, lprc->top, lprc->right, lprc->bottom);
3517 // return 0; // wmv9?
3518 return r; // TM20
3521 static int _adjust_fdiv=0; //what's this? - used to adjust division
3522 static int _winver = 0x510; // windows version
3527 static unsigned int WINAPI expGetTempPathA(unsigned int len, char* path)
3529 dbgprintf("GetTempPathA(%d, 0x%x)", len, path);
3530 if(len<5)
3532 dbgprintf(" => 0\n");
3533 return 0;
3535 strcpy(path, "/tmp");
3536 dbgprintf(" => 5 ( '/tmp' )\n");
3537 return 5;
3540 FYI:
3541 typedef struct
3543 DWORD dwFileAttributes;
3544 FILETIME ftCreationTime;
3545 FILETIME ftLastAccessTime;
3546 FILETIME ftLastWriteTime;
3547 DWORD nFileSizeHigh;
3548 DWORD nFileSizeLow;
3549 DWORD dwReserved0;
3550 DWORD dwReserved1;
3551 CHAR cFileName[260];
3552 CHAR cAlternateFileName[14];
3553 } WIN32_FIND_DATAA, *LPWIN32_FIND_DATAA;
3556 static DIR* qtx_dir=NULL;
3558 static WIN_BOOL WINAPI expFindNextFileA(HANDLE h,LPWIN32_FIND_DATAA lpfd)
3560 #ifdef CONFIG_QTX_CODECS
3561 dbgprintf("FindNextFileA(0x%x, 0x%x) => 0\n", h, lpfd);
3562 if(h==FILE_HANDLE_quicktimeqtx){
3563 struct dirent* d;
3564 if(!qtx_dir) return 0;
3565 while((d=readdir(qtx_dir))){
3566 char* x=strrchr(d->d_name,'.');
3567 if(!x) continue;
3568 if(strcmp(x,".qtx")) continue;
3569 strcpy(lpfd->cFileName,d->d_name);
3570 // sprintf(lpfd->cAlternateFileName,"%-8s.qtx",d->d_name);
3571 strcpy(lpfd->cAlternateFileName,"foobar.qtx");
3572 dbgprintf("### FindNext: %s\n",lpfd->cFileName);
3573 return 1;
3575 closedir(qtx_dir); qtx_dir=NULL;
3576 return 0;
3578 #endif
3579 return 0;
3582 static HANDLE WINAPI expFindFirstFileA(LPCSTR s, LPWIN32_FIND_DATAA lpfd)
3584 dbgprintf("FindFirstFileA(0x%x='%s', 0x%x) => 0\n", s, s, lpfd);
3585 // printf("\n### FindFirstFileA('%s')...\n",s);
3586 #ifdef CONFIG_QTX_CODECS
3587 if(strstr(s, "quicktime\\*.QTX")){
3588 dbgprintf("FindFirstFileA(0x%x='%s', 0x%x) => QTX\n", s, s, lpfd);
3589 dbgprintf("\n### Searching for QuickTime plugins (*.qtx) at %s...\n",
3590 codec_path);
3591 qtx_dir = opendir(codec_path);
3592 if(!qtx_dir) return (HANDLE)-1;
3593 memset(lpfd,0,sizeof(*lpfd));
3594 if(expFindNextFileA(FILE_HANDLE_quicktimeqtx,lpfd))
3595 return FILE_HANDLE_quicktimeqtx;
3596 printf("loader: Couldn't find the QuickTime plugins (.qtx files) at %s\n",
3597 codec_path);
3598 return (HANDLE)-1;
3600 #if 0
3601 if(strstr(s, "QuickTime.qts")){
3602 dbgprintf("FindFirstFileA(0x%x='%s', 0x%x) => QTS\n", s, s, lpfd);
3603 // if(!strcmp(s,"C:\\windows\\QuickTime.qts\\QuickTime.qts\\*.QTX"))
3604 // return (HANDLE)-1;
3605 strcpy(lpfd->cFileName, "QuickTime.qts");
3606 strcpy(lpfd->cAlternateFileName, "QuickT~1.qts");
3607 return FILE_HANDLE_quicktimeqts;
3609 #endif
3610 #endif
3611 if(strstr(s, "*.vwp")){
3612 // hack for VoxWare codec plugins:
3613 strcpy(lpfd->cFileName, "msms001.vwp");
3614 strcpy(lpfd->cAlternateFileName, "msms001.vwp");
3615 return (HANDLE)0;
3617 // return 'file not found'
3618 return (HANDLE)-1;
3621 static WIN_BOOL WINAPI expFindClose(HANDLE h)
3623 dbgprintf("FindClose(0x%x) => 0\n", h);
3624 #ifdef CONFIG_QTX_CODECS
3625 // if(h==FILE_HANDLE_quicktimeqtx && qtx_dir){
3626 // closedir(qtx_dir);
3627 // qtx_dir=NULL;
3628 // }
3629 #endif
3630 return 0;
3632 static UINT WINAPI expSetErrorMode(UINT i)
3634 dbgprintf("SetErrorMode(%d) => 0\n", i);
3635 return 0;
3637 static UINT WINAPI expGetWindowsDirectoryA(LPSTR s,UINT c)
3639 char windir[]="c:\\windows";
3640 int result;
3641 strncpy(s, windir, c);
3642 result=1+((c<strlen(windir))?c:strlen(windir));
3643 dbgprintf("GetWindowsDirectoryA(0x%x, %d) => %d\n", s, c, result);
3644 return result;
3646 #ifdef CONFIG_QTX_CODECS
3647 static UINT WINAPI expGetCurrentDirectoryA(UINT c, LPSTR s)
3649 char curdir[]="c:\\";
3650 int result;
3651 strncpy(s, curdir, c);
3652 result=1+((c<strlen(curdir))?c:strlen(curdir));
3653 dbgprintf("GetCurrentDirectoryA(0x%x, %d) => %d\n", s, c, result);
3654 return result;
3657 static int WINAPI expSetCurrentDirectoryA(const char *pathname)
3659 dbgprintf("SetCurrentDirectoryA(0x%x = %s) => 1\n", pathname, pathname);
3660 #if 0
3661 if (strrchr(pathname, '\\'))
3662 chdir(strcat(strrchr(pathname, '\\')+1, '/'));
3663 else
3664 chdir(pathname);
3665 #endif
3666 return 1;
3669 static int WINAPI expCreateDirectoryA(const char *pathname, void *sa)
3671 dbgprintf("CreateDirectory(0x%x = %s, 0x%x) => 1\n",
3672 pathname, pathname, sa);
3673 #if 0
3674 p = strrchr(pathname, '\\')+1;
3675 strcpy(&buf[0], p); /* should be strncpy */
3676 if (!strlen(p))
3678 buf[0] = '.';
3679 buf[1] = 0;
3681 #if 0
3682 if (strrchr(pathname, '\\'))
3683 mkdir(strcat(strrchr(pathname, '\\')+1, '/'), 666);
3684 else
3685 mkdir(pathname, 666);
3686 #endif
3687 mkdir(&buf);
3688 #endif
3689 return 1;
3691 #endif
3692 static WIN_BOOL WINAPI expDeleteFileA(LPCSTR s)
3694 dbgprintf("DeleteFileA(0x%x='%s') => 0\n", s, s);
3695 return 0;
3697 static WIN_BOOL WINAPI expFileTimeToLocalFileTime(const FILETIME* cpf, LPFILETIME pf)
3699 dbgprintf("FileTimeToLocalFileTime(0x%x, 0x%x) => 0\n", cpf, pf);
3700 return 0;
3703 static UINT WINAPI expGetTempFileNameA(LPCSTR cs1,LPCSTR cs2,UINT i,LPSTR ps)
3705 char mask[16]="/tmp/AP_XXXXXX";
3706 int result;
3707 dbgprintf("GetTempFileNameA(0x%x='%s', 0x%x='%s', %d, 0x%x)", cs1, cs1, cs2, cs2, i, ps);
3708 if(i && i<10)
3710 dbgprintf(" => -1\n");
3711 return -1;
3713 result=mkstemp(mask);
3714 sprintf(ps, "AP%d", result);
3715 dbgprintf(" => %d\n", strlen(ps));
3716 return strlen(ps);
3719 // This func might need proper implementation if we want AngelPotion codec.
3720 // They try to open APmpeg4v1.apl with it.
3721 // DLL will close opened file with CloseHandle().
3723 static HANDLE WINAPI expCreateFileA(LPCSTR cs1,DWORD i1,DWORD i2,
3724 LPSECURITY_ATTRIBUTES p1, DWORD i3,DWORD i4,HANDLE i5)
3726 dbgprintf("CreateFileA(0x%x='%s', %d, %d, 0x%x, %d, %d, 0x%x)\n", cs1, cs1, i1,
3727 i2, p1, i3, i4, i5);
3728 if((!cs1) || (strlen(cs1)<2))return -1;
3730 #ifdef CONFIG_QTX_CODECS
3731 if(strstr(cs1, "QuickTime.qts"))
3733 int result;
3734 char* tmp = malloc(strlen(codec_path) + 50);
3735 strcpy(tmp, codec_path);
3736 strcat(tmp, "/");
3737 strcat(tmp, "QuickTime.qts");
3738 result=open(tmp, O_RDONLY);
3739 free(tmp);
3740 return result;
3742 if(strstr(cs1, ".qtx"))
3744 int result;
3745 char* tmp = malloc(strlen(codec_path) + 250);
3746 char* x=strrchr(cs1,'\\');
3747 sprintf(tmp, "%s/%s", codec_path, x ? (x + 1) : cs1);
3748 // printf("### Open: %s -> %s\n",cs1,tmp);
3749 result=open(tmp, O_RDONLY);
3750 free(tmp);
3751 return result;
3753 #endif
3755 if(strncmp(cs1, "AP", 2) == 0)
3757 int result;
3758 char* tmp = malloc(strlen(codec_path) + 50);
3759 strcpy(tmp, codec_path);
3760 strcat(tmp, "/");
3761 strcat(tmp, "APmpg4v1.apl");
3762 result=open(tmp, O_RDONLY);
3763 free(tmp);
3764 return result;
3766 if (strstr(cs1, "vp3") || strstr(cs1, ".fpf") || strstr(cs1, ".col"))
3768 int r;
3769 int flg = 0;
3770 char* tmp=malloc(20 + strlen(cs1));
3771 strcpy(tmp, "/tmp/");
3772 strcat(tmp, cs1);
3773 r = 4;
3774 while (tmp[r])
3776 if (tmp[r] == ':' || tmp[r] == '\\')
3777 tmp[r] = '_';
3778 r++;
3780 if (GENERIC_READ & i1)
3781 flg |= O_RDONLY;
3782 else if (GENERIC_WRITE & i1)
3784 flg |= O_WRONLY | O_CREAT;
3785 printf("Warning: openning filename %s %d (flags; 0x%x) for write\n", tmp, r, flg);
3787 r=open(tmp, flg, S_IRWXU);
3788 free(tmp);
3789 return r;
3792 // Needed by wnvplay1.dll
3793 if (strstr(cs1, "WINNOV.bmp"))
3795 int r;
3796 r=open("/dev/null", O_RDONLY);
3797 return r;
3800 #if 0
3801 /* we need this for some virtualdub filters */
3803 int r;
3804 int flg = 0;
3805 if (GENERIC_READ & i1)
3806 flg |= O_RDONLY;
3807 else if (GENERIC_WRITE & i1)
3809 flg |= O_WRONLY;
3810 printf("Warning: openning filename %s %d (flags; 0x%x) for write\n", cs1, r, flg);
3812 r=open(cs1, flg);
3813 return r;
3815 #endif
3817 return atoi(cs1+2);
3819 static UINT WINAPI expGetSystemDirectoryA(
3820 char* lpBuffer, // address of buffer for system directory
3821 UINT uSize // size of directory buffer
3823 dbgprintf("GetSystemDirectoryA(%p,%d)\n", lpBuffer,uSize);
3824 if(!lpBuffer) strcpy(lpBuffer,".");
3825 return 1;
3828 static char sysdir[]=".";
3829 static LPCSTR WINAPI expGetSystemDirectoryA(void)
3831 dbgprintf("GetSystemDirectoryA() => 0x%x='%s'\n", sysdir, sysdir);
3832 return sysdir;
3835 static DWORD WINAPI expGetFullPathNameA
3837 LPCTSTR lpFileName,
3838 DWORD nBufferLength,
3839 LPTSTR lpBuffer,
3840 LPTSTR lpFilePart
3842 if(!lpFileName) return 0;
3843 dbgprintf("GetFullPathNameA('%s',%d,%p,%p)\n",lpFileName,nBufferLength,
3844 lpBuffer, lpFilePart);
3845 #if 0
3846 #ifdef CONFIG_QTX_CODECS
3847 strcpy(lpFilePart, "Quick123.qts");
3848 #else
3849 strcpy(lpFilePart, lpFileName);
3850 #endif
3851 #else
3852 if (strrchr(lpFileName, '\\'))
3853 lpFilePart = strrchr(lpFileName, '\\');
3854 else
3855 lpFilePart = (LPTSTR)lpFileName;
3856 #endif
3857 strcpy(lpBuffer, lpFileName);
3858 // strncpy(lpBuffer, lpFileName, rindex(lpFileName, '\\')-lpFileName);
3859 return strlen(lpBuffer);
3862 static DWORD WINAPI expGetShortPathNameA
3864 LPCSTR longpath,
3865 LPSTR shortpath,
3866 DWORD shortlen
3868 if(!longpath) return 0;
3869 dbgprintf("GetShortPathNameA('%s',%p,%d)\n",longpath,shortpath,shortlen);
3870 strcpy(shortpath,longpath);
3871 return strlen(shortpath);
3874 static WIN_BOOL WINAPI expReadFile(HANDLE h,LPVOID pv,DWORD size,LPDWORD rd,LPOVERLAPPED unused)
3876 int result;
3877 dbgprintf("ReadFile(%d, 0x%x, %d -> 0x%x)\n", h, pv, size, rd);
3878 result=read(h, pv, size);
3879 if(rd)*rd=result;
3880 if(!result)return 0;
3881 return 1;
3884 static WIN_BOOL WINAPI expWriteFile(HANDLE h,LPCVOID pv,DWORD size,LPDWORD wr,LPOVERLAPPED unused)
3886 int result;
3887 dbgprintf("WriteFile(%d, 0x%x, %d -> 0x%x)\n", h, pv, size, wr);
3888 if(h==1234)h=1;
3889 result=write(h, pv, size);
3890 if(wr)*wr=result;
3891 if(!result)return 0;
3892 return 1;
3894 static DWORD WINAPI expSetFilePointer(HANDLE h, LONG val, LPLONG ext, DWORD whence)
3896 int wh;
3897 dbgprintf("SetFilePointer(%d, 0x%x, 0x%x = %d, %d)\n", h, val, ext, ext ? *ext : NULL, whence);
3898 //why would DLL want temporary file with >2Gb size?
3899 switch(whence)
3901 case FILE_BEGIN:
3902 wh=SEEK_SET;break;
3903 case FILE_END:
3904 wh=SEEK_END;break;
3905 case FILE_CURRENT:
3906 wh=SEEK_CUR;break;
3907 default:
3908 return -1;
3910 #ifdef CONFIG_QTX_CODECS
3911 if (val == 0 && ext != 0)
3912 val = val&(*ext);
3913 #endif
3914 return lseek(h, val, wh);
3917 static HDRVR WINAPI expOpenDriverA(LPCSTR szDriverName, LPCSTR szSectionName,
3918 LPARAM lParam2)
3920 dbgprintf("OpenDriverA(0x%x='%s', 0x%x='%s', 0x%x) => -1\n", szDriverName, szDriverName, szSectionName, szSectionName, lParam2);
3921 return -1;
3923 static HDRVR WINAPI expOpenDriver(LPCSTR szDriverName, LPCSTR szSectionName,
3924 LPARAM lParam2)
3926 dbgprintf("OpenDriver(0x%x='%s', 0x%x='%s', 0x%x) => -1\n", szDriverName, szDriverName, szSectionName, szSectionName, lParam2);
3927 return -1;
3931 static WIN_BOOL WINAPI expGetProcessAffinityMask(HANDLE hProcess,
3932 LPDWORD lpProcessAffinityMask,
3933 LPDWORD lpSystemAffinityMask)
3935 dbgprintf("GetProcessAffinityMask(0x%x, 0x%x, 0x%x) => 1\n",
3936 hProcess, lpProcessAffinityMask, lpSystemAffinityMask);
3937 if(lpProcessAffinityMask)*lpProcessAffinityMask=1;
3938 if(lpSystemAffinityMask)*lpSystemAffinityMask=1;
3939 return 1;
3942 // Fake implementation: does nothing, but does it right :)
3943 static WIN_BOOL WINAPI expSetProcessAffinityMask(HANDLE hProcess,
3944 LPDWORD dwProcessAffinityMask)
3946 dbgprintf("SetProcessAffinityMask(0x%x, 0x%x) => 1\n",
3947 hProcess, dwProcessAffinityMask);
3949 return 1;
3952 static int WINAPI expMulDiv(int nNumber, int nNumerator, int nDenominator)
3954 static const long long max_int=0x7FFFFFFFLL;
3955 static const long long min_int=-0x80000000LL;
3956 long long tmp=(long long)nNumber*(long long)nNumerator;
3957 dbgprintf("expMulDiv %d * %d / %d\n", nNumber, nNumerator, nDenominator);
3958 if(!nDenominator)return 1;
3959 tmp/=nDenominator;
3960 if(tmp<min_int) return 1;
3961 if(tmp>max_int) return 1;
3962 return (int)tmp;
3965 static LONG WINAPI explstrcmpiA(const char* str1, const char* str2)
3967 LONG result=strcasecmp(str1, str2);
3968 dbgprintf("strcmpi(0x%x='%s', 0x%x='%s') => %d\n", str1, str1, str2, str2, result);
3969 return result;
3972 static LONG WINAPI explstrlenA(const char* str1)
3974 LONG result=strlen(str1);
3975 dbgprintf("strlen(0x%x='%.50s') => %d\n", str1, str1, result);
3976 return result;
3979 static LONG WINAPI explstrcpyA(char* str1, const char* str2)
3981 int result= (int) strcpy(str1, str2);
3982 dbgprintf("strcpy(0x%.50x, 0x%.50x='%.50s') => %d\n", str1, str2, str2, result);
3983 return result;
3985 static LONG WINAPI explstrcpynA(char* str1, const char* str2,int len)
3987 int result;
3988 if (strlen(str2)>len)
3989 result = (int) strncpy(str1, str2,len);
3990 else
3991 result = (int) strcpy(str1,str2);
3992 dbgprintf("strncpy(0x%x, 0x%x='%s' len %d strlen %d) => %x\n", str1, str2, str2,len, strlen(str2),result);
3993 return result;
3995 static LONG WINAPI explstrcatA(char* str1, const char* str2)
3997 int result= (int) strcat(str1, str2);
3998 dbgprintf("strcat(0x%x, 0x%x='%s') => %d\n", str1, str2, str2, result);
3999 return result;
4003 static LONG WINAPI expInterlockedExchange(long *dest, long l)
4005 long retval = *dest;
4006 *dest = l;
4007 return retval;
4010 static void WINAPI expInitCommonControls(void)
4012 dbgprintf("InitCommonControls called!\n");
4013 return;
4016 #ifdef CONFIG_QTX_CODECS
4017 /* needed by QuickTime.qts */
4018 static HWND WINAPI expCreateUpDownControl (DWORD style, INT x, INT y, INT cx, INT cy,
4019 HWND parent, INT id, HINSTANCE inst,
4020 HWND buddy, INT maxVal, INT minVal, INT curVal)
4022 dbgprintf("CreateUpDownControl(...)\n");
4023 return 0;
4025 #endif
4027 /* alex: implement this call! needed for 3ivx */
4028 static HRESULT WINAPI expCoCreateFreeThreadedMarshaler(void *pUnkOuter, void **ppUnkInner)
4030 dbgprintf("CoCreateFreeThreadedMarshaler(%p, %p) called!\n",
4031 pUnkOuter, ppUnkInner);
4032 // return 0;
4033 return ERROR_CALL_NOT_IMPLEMENTED;
4037 static int WINAPI expDuplicateHandle(HANDLE hSourceProcessHandle, // handle to source process
4038 HANDLE hSourceHandle, // handle to duplicate
4039 HANDLE hTargetProcessHandle, // handle to target process
4040 HANDLE* lpTargetHandle, // duplicate handle
4041 DWORD dwDesiredAccess, // requested access
4042 int bInheritHandle, // handle inheritance option
4043 DWORD dwOptions // optional actions
4046 dbgprintf("DuplicateHandle(%p, %p, %p, %p, 0x%x, %d, %d) called\n",
4047 hSourceProcessHandle, hSourceHandle, hTargetProcessHandle,
4048 lpTargetHandle, dwDesiredAccess, bInheritHandle, dwOptions);
4049 *lpTargetHandle = hSourceHandle;
4050 return 1;
4053 static HRESULT WINAPI expCoInitializeEx(LPVOID lpReserved, DWORD dwCoInit)
4055 dbgprintf("CoInitializeEx(%p, %d) called\n", lpReserved, dwCoInit);
4056 return S_OK;
4059 // required by PIM1 codec (used by win98 PCTV Studio capture sw)
4060 static HRESULT WINAPI expCoInitialize(
4061 LPVOID lpReserved /* [in] pointer to win32 malloc interface
4062 (obsolete, should be NULL) */
4066 * Just delegate to the newer method.
4068 return expCoInitializeEx(lpReserved, COINIT_APARTMENTTHREADED);
4071 static void WINAPI expCoUninitialize(void)
4073 dbgprintf("CoUninitialize() called\n");
4076 /* allow static linking */
4077 HRESULT WINAPI CoInitializeEx(LPVOID lpReserved, DWORD dwCoInit)
4079 return expCoInitializeEx(lpReserved, dwCoInit);
4081 HRESULT WINAPI CoInitialize(LPVOID lpReserved)
4083 return expCoInitialize(lpReserved);
4085 void WINAPI CoUninitialize(void)
4087 expCoUninitialize();
4090 static DWORD WINAPI expSetThreadAffinityMask
4092 HANDLE hThread,
4093 DWORD dwThreadAffinityMask
4095 return 0;
4099 * no WINAPI functions - CDECL
4101 static void* expmalloc(int size)
4103 //printf("malloc");
4104 // return malloc(size);
4105 void* result=my_mreq(size,0);
4106 dbgprintf("malloc(0x%x) => 0x%x\n", size,result);
4107 if(result==0)
4108 printf("WARNING: malloc() failed\n");
4109 return result;
4111 static void expfree(void* mem)
4113 // return free(mem);
4114 dbgprintf("free(%p)\n", mem);
4115 my_release(mem);
4117 /* needed by atrac3.acm */
4118 static void *expcalloc(int num, int size)
4120 void* result=my_mreq(num*size,1);
4121 dbgprintf("calloc(%d,%d) => %p\n", num,size,result);
4122 if(result==0)
4123 printf("WARNING: calloc() failed\n");
4124 return result;
4126 static void* expnew(int size)
4128 // printf("NEW:: Call from address %08x\n STACK DUMP:\n", *(-1+(int*)&size));
4129 // printf("%08x %08x %08x %08x\n",
4130 // size, *(1+(int*)&size),
4131 // *(2+(int*)&size),*(3+(int*)&size));
4132 void* result;
4133 assert(size >= 0);
4135 result=my_mreq(size,0);
4136 dbgprintf("new(%d) => %p\n", size, result);
4137 if (result==0)
4138 printf("WARNING: new() failed\n");
4139 return result;
4142 static int expdelete(void* memory)
4144 dbgprintf("delete(%p)\n", memory);
4145 my_release(memory);
4146 return 0;
4150 * local definition - we need only the last two members at this point
4151 * otherwice we would have to introduce here GUIDs and some more types..
4153 typedef struct __attribute__((__packed__))
4155 char hay[0x40];
4156 unsigned long cbFormat; //0x40
4157 char* pbFormat; //0x44
4158 } MY_MEDIA_TYPE;
4159 static HRESULT WINAPI expMoCopyMediaType(MY_MEDIA_TYPE* dest, const MY_MEDIA_TYPE* src)
4161 if (!dest || !src)
4162 return E_POINTER;
4163 memcpy(dest, src, sizeof(MY_MEDIA_TYPE));
4164 if (dest->cbFormat)
4166 dest->pbFormat = (char*) my_mreq(dest->cbFormat, 0);
4167 if (!dest->pbFormat)
4168 return E_OUTOFMEMORY;
4169 memcpy(dest->pbFormat, src->pbFormat, dest->cbFormat);
4171 return S_OK;
4173 static HRESULT WINAPI expMoInitMediaType(MY_MEDIA_TYPE* dest, DWORD cbFormat)
4175 if (!dest)
4176 return E_POINTER;
4177 memset(dest, 0, sizeof(MY_MEDIA_TYPE));
4178 if (cbFormat)
4180 dest->pbFormat = (char*) my_mreq(cbFormat, 0);
4181 if (!dest->pbFormat)
4182 return E_OUTOFMEMORY;
4184 return S_OK;
4186 static HRESULT WINAPI expMoCreateMediaType(MY_MEDIA_TYPE** dest, DWORD cbFormat)
4188 if (!dest)
4189 return E_POINTER;
4190 *dest = my_mreq(sizeof(MY_MEDIA_TYPE), 0);
4191 return expMoInitMediaType(*dest, cbFormat);
4193 static HRESULT WINAPI expMoDuplicateMediaType(MY_MEDIA_TYPE** dest, const void* src)
4195 if (!dest)
4196 return E_POINTER;
4197 *dest = my_mreq(sizeof(MY_MEDIA_TYPE), 0);
4198 return expMoCopyMediaType(*dest, src);
4200 static HRESULT WINAPI expMoFreeMediaType(MY_MEDIA_TYPE* dest)
4202 if (!dest)
4203 return E_POINTER;
4204 if (dest->pbFormat)
4206 my_release(dest->pbFormat);
4207 dest->pbFormat = 0;
4208 dest->cbFormat = 0;
4210 return S_OK;
4212 static HRESULT WINAPI expMoDeleteMediaType(MY_MEDIA_TYPE* dest)
4214 if (!dest)
4215 return E_POINTER;
4216 expMoFreeMediaType(dest);
4217 my_release(dest);
4218 return S_OK;
4221 static int exp_snprintf( char *str, int size, const char *format, ... )
4223 int x;
4224 va_list va;
4225 va_start(va, format);
4226 x=snprintf(str,size,format,va);
4227 dbgprintf("_snprintf( 0x%x, %d, %s, ... ) => %d\n",str,size,format,x);
4228 va_end(va);
4229 return x;
4232 #if 0
4233 static int exp_initterm(int v1, int v2)
4235 dbgprintf("_initterm(0x%x, 0x%x) => 0\n", v1, v2);
4236 return 0;
4238 #else
4239 /* merged from wine - 2002.04.21 */
4240 typedef void (*INITTERMFUNC)();
4241 static int exp_initterm(INITTERMFUNC *start, INITTERMFUNC *end)
4243 dbgprintf("_initterm(0x%x, 0x%x) %p\n", start, end, *start);
4244 while (start < end)
4246 if (*start)
4248 //printf("call _initfunc: from: %p %d\n", *start);
4249 // ok this trick with push/pop is necessary as otherwice
4250 // edi/esi registers are being trashed
4251 void* p = *start;
4252 __asm__ volatile
4254 "pushl %%ebx \n\t"
4255 "pushl %%ecx \n\t"
4256 "pushl %%edx \n\t"
4257 "pushl %%edi \n\t"
4258 "pushl %%esi \n\t"
4259 "call *%%eax \n\t"
4260 "popl %%esi \n\t"
4261 "popl %%edi \n\t"
4262 "popl %%edx \n\t"
4263 "popl %%ecx \n\t"
4264 "popl %%ebx \n\t"
4266 : "a"(p)
4267 : "memory"
4269 //printf("done %p %d:%d\n", end);
4271 start++;
4273 return 0;
4275 #endif
4277 /* Fake _initterm_e from msvcr80.dll, needed by sirenacm.dll
4278 * NOTE: If I make this an alias for _initterm, then sirenacm.dll tries to call
4279 other uninmplemented functions; keep this in mind if some future codec needs
4280 a real implementation of this function */
4281 static int exp_initterm_e(INITTERMFUNC *start, INITTERMFUNC *end)
4283 dbgprintf("_initterm_e(0x%x, 0x%x)\n", start, end);
4284 return 0;
4287 static void* exp__dllonexit(void)
4289 // FIXME extract from WINE
4290 return NULL;
4293 static int expwsprintfA(char* string, const char* format, ...)
4295 va_list va;
4296 int result;
4297 va_start(va, format);
4298 result = vsprintf(string, format, va);
4299 dbgprintf("wsprintfA(0x%x, '%s', ...) => %d\n", string, format, result);
4300 va_end(va);
4301 return result;
4304 static int expsprintf(char* str, const char* format, ...)
4306 va_list args;
4307 int r;
4308 dbgprintf("sprintf(0x%x, %s)\n", str, format);
4309 va_start(args, format);
4310 r = vsprintf(str, format, args);
4311 va_end(args);
4312 return r;
4314 static int expsscanf(const char* str, const char* format, ...)
4316 va_list args;
4317 int r;
4318 dbgprintf("sscanf(%s, %s)\n", str, format);
4319 va_start(args, format);
4320 r = vsscanf(str, format, args);
4321 va_end(args);
4322 return r;
4324 static void* expfopen(const char* path, const char* mode)
4326 printf("fopen: \"%s\" mode:%s\n", path, mode);
4327 //return fopen(path, mode);
4328 return fdopen(0, mode); // everything on screen
4330 static int expfprintf(void* stream, const char* format, ...)
4332 va_list args;
4333 int r = 0;
4334 dbgprintf("fprintf(%p, %s, ...)\n", stream, format);
4335 va_start(args, format);
4336 r = vfprintf((FILE*) stream, format, args);
4337 va_end(args);
4338 return r;
4341 static int expprintf(const char* format, ...)
4343 va_list args;
4344 int r;
4345 dbgprintf("printf(%s, ...)\n", format);
4346 va_start(args, format);
4347 r = vprintf(format, args);
4348 va_end(args);
4349 return r;
4352 static char* expgetenv(const char* varname)
4354 char* v = getenv(varname);
4355 dbgprintf("getenv(%s) => %s\n", varname, v);
4356 return v;
4359 static void* expwcscpy(WCHAR* dst, const WCHAR* src)
4361 WCHAR* p = dst;
4362 while ((*p++ = *src++))
4364 return dst;
4367 static char* expstrrchr(char* string, int value)
4369 char* result=strrchr(string, value);
4370 if(result)
4371 dbgprintf("strrchr(0x%x='%s', %d) => 0x%x='%s'", string, string, value, result, result);
4372 else
4373 dbgprintf("strrchr(0x%x='%s', %d) => 0", string, string, value);
4374 return result;
4377 static char* expstrchr(char* string, int value)
4379 char* result=strchr(string, value);
4380 if(result)
4381 dbgprintf("strchr(0x%x='%s', %d) => 0x%x='%s'", string, string, value, result, result);
4382 else
4383 dbgprintf("strchr(0x%x='%s', %d) => 0", string, string, value);
4384 return result;
4386 static int expstrlen(char* str)
4388 int result=strlen(str);
4389 dbgprintf("strlen(0x%x='%s') => %d\n", str, str, result);
4390 return result;
4392 static char* expstrcpy(char* str1, const char* str2)
4394 char* result= strcpy(str1, str2);
4395 dbgprintf("strcpy(0x%x, 0x%x='%s') => %p\n", str1, str2, str2, result);
4396 return result;
4398 static char* expstrncpy(char* str1, const char* str2, size_t count)
4400 char* result= strncpy(str1, str2, count);
4401 dbgprintf("strncpy(0x%x, 0x%x='%s', %d) => %p\n", str1, str2, str2, count, result);
4402 return result;
4404 static int expstrcmp(const char* str1, const char* str2)
4406 int result=strcmp(str1, str2);
4407 dbgprintf("strcmp(0x%x='%s', 0x%x='%s') => %d\n", str1, str1, str2, str2, result);
4408 return result;
4410 static int expstrncmp(const char* str1, const char* str2,int x)
4412 int result=strncmp(str1, str2,x);
4413 dbgprintf("strcmp(0x%x='%s', 0x%x='%s') => %d\n", str1, str1, str2, str2, result);
4414 return result;
4416 static char* expstrcat(char* str1, const char* str2)
4418 char* result = strcat(str1, str2);
4419 dbgprintf("strcat(0x%x='%s', 0x%x='%s') => %p\n", str1, str1, str2, str2, result);
4420 return result;
4422 static char* exp_strdup(const char* str1)
4424 int l = strlen(str1);
4425 char* result = (char*) my_mreq(l + 1,0);
4426 if (result)
4427 strcpy(result, str1);
4428 dbgprintf("_strdup(0x%x='%s') => %p\n", str1, str1, result);
4429 return result;
4431 static int expisalnum(int c)
4433 int result= (int) isalnum(c);
4434 dbgprintf("isalnum(0x%x='%c' => %d\n", c, c, result);
4435 return result;
4437 static int expisspace(int c)
4439 int result= (int) isspace(c);
4440 dbgprintf("isspace(0x%x='%c' => %d\n", c, c, result);
4441 return result;
4443 static int expisalpha(int c)
4445 int result= (int) isalpha(c);
4446 dbgprintf("isalpha(0x%x='%c' => %d\n", c, c, result);
4447 return result;
4449 static int expisdigit(int c)
4451 int result= (int) isdigit(c);
4452 dbgprintf("isdigit(0x%x='%c' => %d\n", c, c, result);
4453 return result;
4455 static void* expmemmove(void* dest, void* src, int n)
4457 void* result = memmove(dest, src, n);
4458 dbgprintf("memmove(0x%x, 0x%x, %d) => %p\n", dest, src, n, result);
4459 return result;
4461 static int expmemcmp(void* dest, void* src, int n)
4463 int result = memcmp(dest, src, n);
4464 dbgprintf("memcmp(0x%x, 0x%x, %d) => %d\n", dest, src, n, result);
4465 return result;
4467 static void* expmemcpy(void* dest, void* src, int n)
4469 void *result = memcpy(dest, src, n);
4470 dbgprintf("memcpy(0x%x, 0x%x, %d) => %p\n", dest, src, n, result);
4471 return result;
4473 static void* expmemset(void* dest, int c, size_t n)
4475 void *result = memset(dest, c, n);
4476 dbgprintf("memset(0x%x, %d, %d) => %p\n", dest, c, n, result);
4477 return result;
4479 static time_t exptime(time_t* t)
4481 time_t result = time(t);
4482 dbgprintf("time(0x%x) => %d\n", t, result);
4483 return result;
4486 static int exprand(void)
4488 return rand();
4491 static void expsrand(int seed)
4493 srand(seed);
4496 #if 1
4498 // preferred compilation with -O2 -ffast-math !
4500 static double explog10(double x)
4502 /*printf("Log10 %f => %f 0x%Lx\n", x, log10(x), *((int64_t*)&x));*/
4503 return log10(x);
4506 static double expcos(double x)
4508 /*printf("Cos %f => %f 0x%Lx\n", x, cos(x), *((int64_t*)&x));*/
4509 return cos(x);
4512 #else
4514 static void explog10(void)
4516 __asm__ volatile
4518 "fldl 8(%esp) \n\t"
4519 "fldln2 \n\t"
4520 "fxch %st(1) \n\t"
4521 "fyl2x \n\t"
4525 static void expcos(void)
4527 __asm__ volatile
4529 "fldl 8(%esp) \n\t"
4530 "fcos \n\t"
4534 #endif
4536 // this seem to be the only how to make this function working properly
4537 // ok - I've spent tremendous amount of time (many many many hours
4538 // of debuging fixing & testing - it's almost unimaginable - kabi
4540 // _ftol - operated on the float value which is already on the FPU stack
4542 static void exp_ftol(void)
4544 __asm__ volatile
4546 "sub $12, %esp \n\t"
4547 "fstcw -2(%ebp) \n\t"
4548 "wait \n\t"
4549 "movw -2(%ebp), %ax \n\t"
4550 "orb $0x0C, %ah \n\t"
4551 "movw %ax, -4(%ebp) \n\t"
4552 "fldcw -4(%ebp) \n\t"
4553 "fistpl -12(%ebp) \n\t"
4554 "fldcw -2(%ebp) \n\t"
4555 "movl -12(%ebp), %eax \n\t"
4556 //Note: gcc 3.03 does not do the following op if it
4557 // knows that ebp=esp
4558 "movl %ebp, %esp \n\t"
4562 #define FPU_DOUBLES(var1,var2) double var1,var2; \
4563 __asm__ volatile( "fstpl %0;fwait" : "=m" (var2) : ); \
4564 __asm__ volatile( "fstpl %0;fwait" : "=m" (var1) : )
4566 static double exp_CIpow(void)
4568 FPU_DOUBLES(x,y);
4570 dbgprintf("_CIpow(%lf, %lf)\n", x, y);
4571 return pow(x, y);
4574 static double exppow(double x, double y)
4576 /*printf("Pow %f %f 0x%Lx 0x%Lx => %f\n", x, y, *((int64_t*)&x), *((int64_t*)&y), pow(x, y));*/
4577 return pow(x, y);
4580 static double expldexp(double x, int expo)
4582 /*printf("Cos %f => %f 0x%Lx\n", x, cos(x), *((int64_t*)&x));*/
4583 return ldexp(x, expo);
4586 static double expfrexp(double x, int* expo)
4588 /*printf("Cos %f => %f 0x%Lx\n", x, cos(x), *((int64_t*)&x));*/
4589 return frexp(x, expo);
4594 static int exp_stricmp(const char* s1, const char* s2)
4596 return strcasecmp(s1, s2);
4599 /* from declaration taken from Wine sources - this fountion seems to be
4600 * undocumented in any M$ doc */
4601 static int exp_setjmp3(void* jmpbuf, int x)
4603 //dbgprintf("!!!!UNIMPLEMENTED: setjmp3(%p, %d) => 0\n", jmpbuf, x);
4604 //return 0;
4605 __asm__ volatile
4607 //"mov 4(%%esp), %%edx \n\t"
4608 "mov (%%esp), %%eax \n\t"
4609 "mov %%eax, (%%edx) \n\t" // store ebp
4611 //"mov %%ebp, (%%edx) \n\t"
4612 "mov %%ebx, 4(%%edx) \n\t"
4613 "mov %%edi, 8(%%edx) \n\t"
4614 "mov %%esi, 12(%%edx) \n\t"
4615 "mov %%esp, 16(%%edx) \n\t"
4617 "mov 4(%%esp), %%eax \n\t"
4618 "mov %%eax, 20(%%edx) \n\t"
4620 "movl $0x56433230, 32(%%edx) \n\t" // VC20 ??
4621 "movl $0, 36(%%edx) \n\t"
4622 : // output
4623 : "d"(jmpbuf) // input
4624 : "eax"
4626 __asm__ volatile
4628 "mov %%fs:0, %%eax \n\t" // unsure
4629 "mov %%eax, 24(%%edx) \n\t"
4630 "cmp $0xffffffff, %%eax \n\t"
4631 "jnz l1 \n\t"
4632 "mov %%eax, 28(%%edx) \n\t"
4633 "l1: \n\t"
4636 : "eax"
4639 return 0;
4642 static DWORD WINAPI expGetCurrentProcessId(void)
4644 dbgprintf("GetCurrentProcessId(void) => %d\n", getpid());
4645 return getpid(); //(DWORD)NtCurrentTeb()->pid;
4649 typedef struct {
4650 UINT wPeriodMin;
4651 UINT wPeriodMax;
4652 } TIMECAPS, *LPTIMECAPS;
4654 static MMRESULT WINAPI exptimeGetDevCaps(LPTIMECAPS lpCaps, UINT wSize)
4656 dbgprintf("timeGetDevCaps(%p, %u) !\n", lpCaps, wSize);
4658 lpCaps->wPeriodMin = 1;
4659 lpCaps->wPeriodMax = 65535;
4660 return 0;
4663 static MMRESULT WINAPI exptimeBeginPeriod(UINT wPeriod)
4665 dbgprintf("timeBeginPeriod(%u) !\n", wPeriod);
4667 if (wPeriod < 1 || wPeriod > 65535) return 96+1; //TIMERR_NOCANDO;
4668 return 0;
4671 #ifdef CONFIG_QTX_CODECS
4672 static MMRESULT WINAPI exptimeEndPeriod(UINT wPeriod)
4674 dbgprintf("timeEndPeriod(%u) !\n", wPeriod);
4676 if (wPeriod < 1 || wPeriod > 65535) return 96+1; //TIMERR_NOCANDO;
4677 return 0;
4679 #endif
4681 static void WINAPI expGlobalMemoryStatus(
4682 LPMEMORYSTATUS lpmem
4684 static MEMORYSTATUS cached_memstatus;
4685 static int cache_lastchecked = 0;
4686 SYSTEM_INFO si;
4687 FILE *f;
4689 if (time(NULL)==cache_lastchecked) {
4690 memcpy(lpmem,&cached_memstatus,sizeof(MEMORYSTATUS));
4691 return;
4694 f = fopen( "/proc/meminfo", "r" );
4695 if (f)
4697 char buffer[256];
4698 int total, used, free, shared, buffers, cached;
4700 lpmem->dwLength = sizeof(MEMORYSTATUS);
4701 lpmem->dwTotalPhys = lpmem->dwAvailPhys = 0;
4702 lpmem->dwTotalPageFile = lpmem->dwAvailPageFile = 0;
4703 while (fgets( buffer, sizeof(buffer), f ))
4705 /* old style /proc/meminfo ... */
4706 if (sscanf( buffer, "Mem: %d %d %d %d %d %d", &total, &used, &free, &shared, &buffers, &cached ))
4708 lpmem->dwTotalPhys += total;
4709 lpmem->dwAvailPhys += free + buffers + cached;
4711 if (sscanf( buffer, "Swap: %d %d %d", &total, &used, &free ))
4713 lpmem->dwTotalPageFile += total;
4714 lpmem->dwAvailPageFile += free;
4717 /* new style /proc/meminfo ... */
4718 if (sscanf(buffer, "MemTotal: %d", &total))
4719 lpmem->dwTotalPhys = total*1024;
4720 if (sscanf(buffer, "MemFree: %d", &free))
4721 lpmem->dwAvailPhys = free*1024;
4722 if (sscanf(buffer, "SwapTotal: %d", &total))
4723 lpmem->dwTotalPageFile = total*1024;
4724 if (sscanf(buffer, "SwapFree: %d", &free))
4725 lpmem->dwAvailPageFile = free*1024;
4726 if (sscanf(buffer, "Buffers: %d", &buffers))
4727 lpmem->dwAvailPhys += buffers*1024;
4728 if (sscanf(buffer, "Cached: %d", &cached))
4729 lpmem->dwAvailPhys += cached*1024;
4731 fclose( f );
4733 if (lpmem->dwTotalPhys)
4735 DWORD TotalPhysical = lpmem->dwTotalPhys+lpmem->dwTotalPageFile;
4736 DWORD AvailPhysical = lpmem->dwAvailPhys+lpmem->dwAvailPageFile;
4737 lpmem->dwMemoryLoad = (TotalPhysical-AvailPhysical)
4738 / (TotalPhysical / 100);
4740 } else
4742 /* FIXME: should do something for other systems */
4743 lpmem->dwMemoryLoad = 0;
4744 lpmem->dwTotalPhys = 16*1024*1024;
4745 lpmem->dwAvailPhys = 16*1024*1024;
4746 lpmem->dwTotalPageFile = 16*1024*1024;
4747 lpmem->dwAvailPageFile = 16*1024*1024;
4749 expGetSystemInfo(&si);
4750 lpmem->dwTotalVirtual = si.lpMaximumApplicationAddress-si.lpMinimumApplicationAddress;
4751 /* FIXME: we should track down all the already allocated VM pages and substract them, for now arbitrarily remove 64KB so that it matches NT */
4752 lpmem->dwAvailVirtual = lpmem->dwTotalVirtual-64*1024;
4753 memcpy(&cached_memstatus,lpmem,sizeof(MEMORYSTATUS));
4754 cache_lastchecked = time(NULL);
4756 /* it appears some memory display programs want to divide by these values */
4757 if(lpmem->dwTotalPageFile==0)
4758 lpmem->dwTotalPageFile++;
4760 if(lpmem->dwAvailPageFile==0)
4761 lpmem->dwAvailPageFile++;
4764 static INT WINAPI expGetThreadPriority(HANDLE hthread)
4766 dbgprintf("GetThreadPriority(%p)\n",hthread);
4767 return 0;
4770 /**********************************************************************
4771 * SetThreadPriority [KERNEL32.@] Sets priority for thread.
4773 * RETURNS
4774 * Success: TRUE
4775 * Failure: FALSE
4777 static WIN_BOOL WINAPI expSetThreadPriority(
4778 HANDLE hthread, /* [in] Handle to thread */
4779 INT priority) /* [in] Thread priority level */
4781 dbgprintf("SetThreadPriority(%p,%d)\n",hthread,priority);
4782 return TRUE;
4785 static void WINAPI expTerminateProcess( DWORD process, DWORD status )
4787 printf("EXIT - process %ld code %ld\n", process, status);
4788 exit(status);
4791 static void WINAPI expExitProcess( DWORD status )
4793 printf("EXIT - code %ld\n",status);
4794 exit(status);
4797 static INT WINAPI expMessageBoxA(HWND hWnd, LPCSTR text, LPCSTR title, UINT type){
4798 printf("MSGBOX '%s' '%s' (%d)\n",text,title,type);
4799 #ifdef CONFIG_QTX_CODECS
4800 if (type == MB_ICONHAND && !strlen(text) && !strlen(title))
4801 return IDIGNORE;
4802 #endif
4803 return IDOK;
4806 /* these are needed for mss1 */
4809 * \brief this symbol is defined within exp_EH_prolog_dummy
4810 * \param dest jump target
4812 void exp_EH_prolog(void *dest);
4813 void exp_EH_prolog_dummy(void);
4814 //! just a dummy function that acts a container for the asm section
4815 void exp_EH_prolog_dummy(void) {
4816 __asm__ volatile (
4817 // take care, this "function" may not change flags or
4818 // registers besides eax (which is also why we can't use
4819 // exp_EH_prolog_dummy directly)
4820 MANGLE(exp_EH_prolog)": \n\t"
4821 "pop %eax \n\t"
4822 "push %ebp \n\t"
4823 "mov %esp, %ebp \n\t"
4824 "lea -12(%esp), %esp \n\t"
4825 "jmp *%eax \n\t"
4829 #include <netinet/in.h>
4830 static WINAPI inline unsigned long int exphtonl(unsigned long int hostlong)
4832 // dbgprintf("htonl(%x) => %x\n", hostlong, htonl(hostlong));
4833 return htonl(hostlong);
4836 static WINAPI inline unsigned long int expntohl(unsigned long int netlong)
4838 // dbgprintf("ntohl(%x) => %x\n", netlong, ntohl(netlong));
4839 return ntohl(netlong);
4842 static char* WINAPI expSysAllocStringLen(char *pch, unsigned cch)
4844 char *str;
4845 dbgprintf("SysAllocStringLen('%s', %d)\n", pch, cch);
4846 str = malloc(cch * 2 + sizeof(unsigned) + 2);
4847 *(unsigned *)str = cch;
4848 str += sizeof(unsigned);
4849 if (pch)
4850 memcpy(str, pch, cch * 2);
4851 str[cch * 2] = 0;
4852 str[cch * 2 + 1] = 0;
4853 return str;
4856 static void WINAPI expSysFreeString(char *str)
4858 if (str) {
4859 free(str - sizeof(unsigned));
4863 static void WINAPI expVariantInit(void* p)
4865 printf("InitCommonControls called!\n");
4866 return;
4869 static int WINAPI expRegisterClassA(const void/*WNDCLASSA*/ *wc)
4871 dbgprintf("RegisterClassA(%p) => random id\n", wc);
4872 return time(NULL); /* be precise ! */
4875 static int WINAPI expUnregisterClassA(const char *className, HINSTANCE hInstance)
4877 dbgprintf("UnregisterClassA(%s, %p) => 0\n", className, hInstance);
4878 return 0;
4881 #ifdef CONFIG_QTX_CODECS
4882 /* should be fixed bcs it's not fully strlen equivalent */
4883 static int expSysStringByteLen(void *str)
4885 dbgprintf("SysStringByteLen(%p) => %d\n", str, strlen(str));
4886 return strlen(str);
4889 static int expDirectDrawCreate(void)
4891 dbgprintf("DirectDrawCreate(...) => NULL\n");
4892 return 0;
4895 #if 1
4896 typedef struct tagPALETTEENTRY {
4897 BYTE peRed;
4898 BYTE peGreen;
4899 BYTE peBlue;
4900 BYTE peFlags;
4901 } PALETTEENTRY;
4903 typedef struct tagLOGPALETTE {
4904 WORD palVersion;
4905 WORD palNumEntries;
4906 PALETTEENTRY palPalEntry[1];
4907 } LOGPALETTE;
4909 static HPALETTE WINAPI expCreatePalette(CONST LOGPALETTE *lpgpl)
4911 HPALETTE test;
4912 int i;
4914 dbgprintf("CreatePalette(%x) => NULL\n", lpgpl);
4916 i = sizeof(LOGPALETTE)+((lpgpl->palNumEntries-1)*sizeof(PALETTEENTRY));
4917 test = malloc(i);
4918 memcpy((void *)test, lpgpl, i);
4920 return test;
4922 #else
4923 static int expCreatePalette(void)
4925 dbgprintf("CreatePalette(...) => NULL\n");
4926 return NULL;
4928 #endif
4930 static int WINAPI expGetClientRect(HWND win, RECT *r)
4932 dbgprintf("GetClientRect(0x%x, 0x%x) => 1\n", win, r);
4933 r->right = PSEUDO_SCREEN_WIDTH;
4934 r->left = 0;
4935 r->bottom = PSEUDO_SCREEN_HEIGHT;
4936 r->top = 0;
4937 return 1;
4940 #if 0
4941 typedef struct tagPOINT {
4942 LONG x;
4943 LONG y;
4944 } POINT, *PPOINT;
4945 #endif
4947 static int WINAPI expClientToScreen(HWND win, POINT *p)
4949 dbgprintf("ClientToScreen(0x%x, 0x%x = %d,%d) => 1\n", win, p, p->x, p->y);
4950 p->x = 0;
4951 p->y = 0;
4952 return 1;
4954 #endif
4956 /* for m3jpeg */
4957 static int WINAPI expSetThreadIdealProcessor(HANDLE thread, int proc)
4959 dbgprintf("SetThreadIdealProcessor(0x%x, %x) => 0\n", thread, proc);
4960 return 0;
4963 static int WINAPI expMessageBeep(int type)
4965 dbgprintf("MessageBeep(%d) => 1\n", type);
4966 return 1;
4969 static int WINAPI expDialogBoxParamA(void *inst, const char *name,
4970 HWND parent, void *dialog_func, void *init_param)
4972 dbgprintf("DialogBoxParamA(0x%x, 0x%x = %s, 0x%x, 0x%x, 0x%x) => 0x42424242\n",
4973 inst, name, name, parent, dialog_func, init_param);
4974 return 0x42424242;
4977 static void WINAPI expRegisterClipboardFormatA(const char *name) {
4978 dbgprintf("RegisterClipboardFormatA(0x%x = %s)\n", name, name);
4981 /* needed by imagepower mjpeg2k */
4982 static void *exprealloc(void *ptr, size_t size)
4984 dbgprintf("realloc(0x%x, %x)\n", ptr, size);
4985 if (!ptr)
4986 return my_mreq(size,0);
4987 else
4988 return my_realloc(ptr, size);
4991 /* Fake GetOpenFileNameA from comdlg32.dll for ViVD codec */
4992 static WIN_BOOL WINAPI expGetOpenFileNameA(/*LPOPENFILENAMEA*/ void* lpfn)
4994 return 1;
4997 static char * WINAPI expPathFindExtensionA(const char *path) {
4998 char *ext;
4999 if (!path)
5000 ext = NULL;
5001 else {
5002 ext = strrchr(path, '.');
5003 if (!ext)
5004 ext = &path[strlen(path)];
5006 dbgprintf("PathFindExtensionA(0x%x = %s) => 0x%x, %s\n", path, path, ext, ext);
5007 return ext;
5010 static char * WINAPI expPathFindFileNameA(const char *path) {
5011 char *name;
5012 if (!path || strlen(path) < 2)
5013 name = path;
5014 else {
5015 name = strrchr(path - 1, '\\');
5016 if (!name)
5017 name = path;
5019 dbgprintf("PathFindFileNameA(0x%x = %s) => 0x%x, %s\n", path, path, name, name);
5020 return name;
5023 static double expfloor(double x)
5025 dbgprintf("floor(%lf)\n", x);
5026 return floor(x);
5029 #define FPU_DOUBLE(var) double var; \
5030 __asm__ volatile( "fstpl %0;fwait" : "=m" (var) : )
5032 static double exp_CIcos(void)
5034 FPU_DOUBLE(x);
5036 dbgprintf("_CIcos(%lf)\n", x);
5037 return cos(x);
5040 static double exp_CIsin(void)
5042 FPU_DOUBLE(x);
5044 dbgprintf("_CIsin(%lf)\n", x);
5045 return sin(x);
5048 static double exp_CIsqrt(void)
5050 FPU_DOUBLE(x);
5052 dbgprintf("_CIsqrt(%lf)\n", x);
5053 return sqrt(x);
5056 /* Needed by rp8 sipr decoder */
5057 static LPSTR WINAPI expCharNextA(LPCSTR ptr)
5059 if (!*ptr) return (LPSTR)ptr;
5060 // dbgprintf("CharNextA(0x%08x), %s\n", ptr, ptr);
5061 return (LPSTR)(ptr + 1);
5064 // Fake implementation, needed by wvc1dmod.dll
5065 static int WINAPI expPropVariantClear(void *pvar)
5067 // dbgprintf("PropVariantclear (0x%08x), %s\n", ptr, ptr);
5068 return 1;
5071 // This define is fake, the real thing is a struct
5072 #define LPDEVMODEA void*
5073 // Dummy implementation, always return 1
5074 // Required for frapsvid.dll 2.8.1, return value does not matter
5075 static WIN_BOOL WINAPI expEnumDisplaySettingsA(LPCSTR name ,DWORD n,
5076 LPDEVMODEA devmode)
5078 dbgprintf("EnumDisplaySettingsA (dummy) => 1\n");
5079 return 1;
5082 // Fake implementation of _decode_pointer from msvcr80.dll, needed by sirenacm.dll
5083 // NOTE: undocumented function, probably the declaration is not right
5084 static int exp_decode_pointer(void *ptr)
5086 dbgprintf("_decode_pointer (0x%08x)\n", ptr);
5087 return 0;
5090 /* Fake implementation of sdt::_Lockit::_Lockit(void) from msvcp60.dll
5091 Needed by SCLS.DLL */
5092 static int exp_0Lockit_dummy(void)
5094 dbgprintf("0Lockit_dummy (??0_Lockit@std@@QAE@XZ)\n");
5095 return 0;
5098 /* Fake implementation of sdt::_Lockit::~_Lockit(void) from msvcp60.dll
5099 Needed by SCLS.DLL */
5100 static int exp_1Lockit_dummy(void)
5102 dbgprintf("1Lockit_dummy (??1_Lockit@std@@QAE@XZ)\n");
5103 return 0;
5106 static void * WINAPI expEncodePointer(void *p)
5108 return p;
5111 static void * WINAPI expDecodePointer(void *p)
5113 return p;
5116 static DWORD WINAPI expGetThreadLocale(void)
5118 return 0;
5122 * Very incomplete implementation, return an error for almost all cases.
5124 static DWORD WINAPI expGetLocaleInfoA(DWORD locale, DWORD lctype, char* lpLCData, int cchData)
5126 if (lctype == 0x1004) { // LOCALE_IDEFAULTANSICODEPAGE
5127 if (cchData < 4)
5128 return cchData == 0 ? 4 : 0;
5129 strcpy(lpLCData, "437");
5130 return 4;
5132 return 0;
5135 struct exports
5137 char name[64];
5138 int id;
5139 void* func;
5141 struct libs
5143 char name[64];
5144 int length;
5145 struct exports* exps;
5148 #define FF(X,Y) \
5149 {#X, Y, (void*)exp##X},
5151 #define UNDEFF(X, Y) \
5152 {#X, Y, (void*)-1},
5154 struct exports exp_kernel32[]=
5156 FF(GetVolumeInformationA,-1)
5157 FF(GetDriveTypeA,-1)
5158 FF(GetLogicalDriveStringsA,-1)
5159 FF(IsBadWritePtr, 357)
5160 FF(IsBadReadPtr, 354)
5161 FF(IsBadStringPtrW, -1)
5162 FF(IsBadStringPtrA, -1)
5163 FF(DisableThreadLibraryCalls, -1)
5164 FF(CreateThread, -1)
5165 FF(ResumeThread, -1)
5166 FF(CreateEventA, -1)
5167 FF(CreateEventW, -1)
5168 FF(SetEvent, -1)
5169 FF(ResetEvent, -1)
5170 FF(WaitForSingleObject, -1)
5171 #ifdef CONFIG_QTX_CODECS
5172 FF(WaitForMultipleObjects, -1)
5173 FF(ExitThread, -1)
5174 #endif
5175 FF(GetSystemInfo, -1)
5176 FF(GetVersion, 332)
5177 FF(HeapCreate, 461)
5178 FF(HeapAlloc, -1)
5179 FF(HeapDestroy, -1)
5180 FF(HeapFree, -1)
5181 FF(HeapSize, -1)
5182 FF(HeapReAlloc,-1)
5183 FF(GetProcessHeap, -1)
5184 FF(VirtualAlloc, -1)
5185 FF(VirtualFree, -1)
5186 FF(InitializeCriticalSection, -1)
5187 FF(InitializeCriticalSectionAndSpinCount, -1)
5188 FF(EnterCriticalSection, -1)
5189 FF(LeaveCriticalSection, -1)
5190 FF(DeleteCriticalSection, -1)
5191 FF(TlsAlloc, -1)
5192 FF(TlsFree, -1)
5193 FF(TlsGetValue, -1)
5194 FF(TlsSetValue, -1)
5195 FF(GetCurrentThreadId, -1)
5196 FF(GetCurrentProcess, -1)
5197 FF(LocalAlloc, -1)
5198 FF(LocalReAlloc,-1)
5199 FF(LocalLock, -1)
5200 FF(GlobalAlloc, -1)
5201 FF(GlobalReAlloc, -1)
5202 FF(GlobalLock, -1)
5203 FF(GlobalSize, -1)
5204 FF(MultiByteToWideChar, 427)
5205 FF(WideCharToMultiByte, -1)
5206 FF(GetVersionExA, -1)
5207 FF(GetVersionExW, -1)
5208 FF(CreateSemaphoreA, -1)
5209 FF(CreateSemaphoreW, -1)
5210 FF(QueryPerformanceCounter, -1)
5211 FF(QueryPerformanceFrequency, -1)
5212 FF(LocalHandle, -1)
5213 FF(LocalUnlock, -1)
5214 FF(LocalFree, -1)
5215 FF(GlobalHandle, -1)
5216 FF(GlobalUnlock, -1)
5217 FF(GlobalFree, -1)
5218 FF(LoadResource, -1)
5219 FF(ReleaseSemaphore, -1)
5220 FF(CreateMutexA, -1)
5221 FF(CreateMutexW, -1)
5222 FF(ReleaseMutex, -1)
5223 FF(SignalObjectAndWait, -1)
5224 FF(FindResourceA, -1)
5225 FF(LockResource, -1)
5226 FF(FreeResource, -1)
5227 FF(SizeofResource, -1)
5228 FF(CloseHandle, -1)
5229 FF(GetCommandLineA, -1)
5230 FF(GetEnvironmentStringsW, -1)
5231 FF(FreeEnvironmentStringsW, -1)
5232 FF(FreeEnvironmentStringsA, -1)
5233 FF(GetEnvironmentStrings, -1)
5234 FF(GetStartupInfoA, -1)
5235 FF(GetStdHandle, -1)
5236 FF(GetFileType, -1)
5237 #ifdef CONFIG_QTX_CODECS
5238 FF(GetFileAttributesA, -1)
5239 #endif
5240 FF(SetHandleCount, -1)
5241 FF(GetACP, -1)
5242 FF(GetModuleFileNameA, -1)
5243 FF(SetUnhandledExceptionFilter, -1)
5244 FF(LoadLibraryA, -1)
5245 FF(GetProcAddress, -1)
5246 FF(FreeLibrary, -1)
5247 FF(CreateFileMappingA, -1)
5248 FF(OpenFileMappingA, -1)
5249 FF(MapViewOfFile, -1)
5250 FF(UnmapViewOfFile, -1)
5251 FF(Sleep, -1)
5252 FF(GetModuleHandleA, -1)
5253 FF(GetModuleHandleW, -1)
5254 FF(GetProfileIntA, -1)
5255 FF(GetPrivateProfileIntA, -1)
5256 FF(GetPrivateProfileStringA, -1)
5257 FF(WritePrivateProfileStringA, -1)
5258 FF(GetLastError, -1)
5259 FF(SetLastError, -1)
5260 FF(InterlockedIncrement, -1)
5261 FF(InterlockedDecrement, -1)
5262 FF(GetTimeZoneInformation, -1)
5263 FF(OutputDebugStringA, -1)
5264 FF(GetLocalTime, -1)
5265 FF(GetSystemTime, -1)
5266 FF(GetSystemTimeAsFileTime, -1)
5267 FF(GetEnvironmentVariableA, -1)
5268 FF(SetEnvironmentVariableA, -1)
5269 FF(RtlZeroMemory,-1)
5270 FF(RtlMoveMemory,-1)
5271 FF(RtlFillMemory,-1)
5272 FF(GetTempPathA,-1)
5273 FF(FindFirstFileA,-1)
5274 FF(FindNextFileA,-1)
5275 FF(FindClose,-1)
5276 FF(FileTimeToLocalFileTime,-1)
5277 FF(DeleteFileA,-1)
5278 FF(ReadFile,-1)
5279 FF(WriteFile,-1)
5280 FF(SetFilePointer,-1)
5281 FF(GetTempFileNameA,-1)
5282 FF(CreateFileA,-1)
5283 FF(GetSystemDirectoryA,-1)
5284 FF(GetWindowsDirectoryA,-1)
5285 #ifdef CONFIG_QTX_CODECS
5286 FF(GetCurrentDirectoryA,-1)
5287 FF(SetCurrentDirectoryA,-1)
5288 FF(CreateDirectoryA,-1)
5289 #endif
5290 FF(GetShortPathNameA,-1)
5291 FF(GetFullPathNameA,-1)
5292 FF(SetErrorMode, -1)
5293 FF(IsProcessorFeaturePresent, -1)
5294 FF(IsDebuggerPresent, -1)
5295 FF(GetProcessAffinityMask, -1)
5296 FF(InterlockedExchange, -1)
5297 FF(InterlockedCompareExchange, -1)
5298 FF(MulDiv, -1)
5299 FF(lstrcmpiA, -1)
5300 FF(lstrlenA, -1)
5301 FF(lstrcpyA, -1)
5302 FF(lstrcatA, -1)
5303 FF(lstrcpynA,-1)
5304 FF(GetProcessVersion,-1)
5305 FF(GetCurrentThread,-1)
5306 FF(GetOEMCP,-1)
5307 FF(GetCPInfo,-1)
5308 FF(DuplicateHandle,-1)
5309 FF(GetTickCount, -1)
5310 FF(SetThreadAffinityMask,-1)
5311 FF(GetCurrentProcessId,-1)
5312 FF(GlobalMemoryStatus,-1)
5313 FF(GetThreadPriority,-1)
5314 FF(SetThreadPriority,-1)
5315 FF(TerminateProcess,-1)
5316 FF(ExitProcess,-1)
5317 {"LoadLibraryExA", -1, (void*)&LoadLibraryExA},
5318 FF(SetThreadIdealProcessor,-1)
5319 FF(SetProcessAffinityMask, -1)
5320 FF(EncodePointer, -1)
5321 FF(DecodePointer, -1)
5322 FF(GetThreadLocale, -1)
5323 FF(GetLocaleInfoA, -1)
5324 UNDEFF(FlsAlloc, -1)
5325 UNDEFF(FlsGetValue, -1)
5326 UNDEFF(FlsSetValue, -1)
5327 UNDEFF(FlsFree, -1)
5330 struct exports exp_msvcrt[]={
5331 FF(malloc, -1)
5332 FF(_initterm, -1)
5333 FF(__dllonexit, -1)
5334 FF(_snprintf,-1)
5335 FF(free, -1)
5336 {"??3@YAXPAX@Z", -1, expdelete},
5337 {"??2@YAPAXI@Z", -1, expnew},
5338 {"_adjust_fdiv", -1, (void*)&_adjust_fdiv},
5339 {"_winver",-1,(void*)&_winver},
5340 FF(strrchr, -1)
5341 FF(strchr, -1)
5342 FF(strlen, -1)
5343 FF(strcpy, -1)
5344 FF(strncpy, -1)
5345 FF(wcscpy, -1)
5346 FF(strcmp, -1)
5347 FF(strncmp, -1)
5348 FF(strcat, -1)
5349 FF(_stricmp,-1)
5350 FF(_strdup,-1)
5351 FF(_setjmp3,-1)
5352 FF(isalnum, -1)
5353 FF(isspace, -1)
5354 FF(isalpha, -1)
5355 FF(isdigit, -1)
5356 FF(memmove, -1)
5357 FF(memcmp, -1)
5358 FF(memset, -1)
5359 FF(memcpy, -1)
5360 FF(time, -1)
5361 FF(rand, -1)
5362 FF(srand, -1)
5363 FF(log10, -1)
5364 FF(pow, -1)
5365 FF(cos, -1)
5366 FF(_ftol,-1)
5367 FF(_CIpow,-1)
5368 FF(_CIcos,-1)
5369 FF(_CIsin,-1)
5370 FF(_CIsqrt,-1)
5371 FF(ldexp,-1)
5372 FF(frexp,-1)
5373 FF(sprintf,-1)
5374 FF(sscanf,-1)
5375 FF(fopen,-1)
5376 FF(fprintf,-1)
5377 FF(printf,-1)
5378 FF(getenv,-1)
5379 FF(floor,-1)
5380 /* needed by frapsvid.dll */
5381 {"strstr",-1,(char *)&strstr},
5382 {"qsort",-1,(void *)&qsort},
5383 FF(_EH_prolog,-1)
5384 FF(calloc,-1)
5385 {"ceil",-1,(void*)&ceil},
5386 /* needed by imagepower mjpeg2k */
5387 {"clock",-1,(void*)&clock},
5388 {"memchr",-1,(void*)&memchr},
5389 {"vfprintf",-1,(void*)&vfprintf},
5390 // {"realloc",-1,(void*)&realloc},
5391 FF(realloc,-1)
5392 {"puts",-1,(void*)&puts}
5394 struct exports exp_winmm[]={
5395 FF(GetDriverModuleHandle, -1)
5396 FF(timeGetTime, -1)
5397 FF(DefDriverProc, -1)
5398 FF(OpenDriverA, -1)
5399 FF(OpenDriver, -1)
5400 FF(timeGetDevCaps, -1)
5401 FF(timeBeginPeriod, -1)
5402 #ifdef CONFIG_QTX_CODECS
5403 FF(timeEndPeriod, -1)
5404 FF(waveOutGetNumDevs, -1)
5405 #endif
5407 struct exports exp_psapi[]={
5408 FF(GetModuleBaseNameA, -1)
5410 struct exports exp_user32[]={
5411 FF(LoadIconA,-1)
5412 FF(LoadStringA, -1)
5413 FF(wsprintfA, -1)
5414 FF(GetDC, -1)
5415 FF(GetDesktopWindow, -1)
5416 FF(ReleaseDC, -1)
5417 FF(IsRectEmpty, -1)
5418 FF(LoadCursorA,-1)
5419 FF(SetCursor,-1)
5420 FF(GetCursorPos,-1)
5421 #ifdef CONFIG_QTX_CODECS
5422 FF(ShowCursor,-1)
5423 #endif
5424 FF(RegisterWindowMessageA,-1)
5425 FF(GetSystemMetrics,-1)
5426 FF(GetSysColor,-1)
5427 FF(GetSysColorBrush,-1)
5428 FF(GetWindowDC, -1)
5429 FF(DrawTextA, -1)
5430 FF(MessageBoxA, -1)
5431 FF(RegisterClassA, -1)
5432 FF(UnregisterClassA, -1)
5433 #ifdef CONFIG_QTX_CODECS
5434 FF(GetWindowRect, -1)
5435 FF(MonitorFromWindow, -1)
5436 FF(MonitorFromRect, -1)
5437 FF(MonitorFromPoint, -1)
5438 FF(EnumDisplayMonitors, -1)
5439 FF(GetMonitorInfoA, -1)
5440 FF(EnumDisplayDevicesA, -1)
5441 FF(GetClientRect, -1)
5442 FF(ClientToScreen, -1)
5443 FF(IsWindowVisible, -1)
5444 FF(GetActiveWindow, -1)
5445 FF(GetClassNameA, -1)
5446 FF(GetClassInfoA, -1)
5447 FF(GetWindowLongA, -1)
5448 FF(EnumWindows, -1)
5449 FF(GetWindowThreadProcessId, -1)
5450 FF(CreateWindowExA, -1)
5451 #endif
5452 FF(MessageBeep, -1)
5453 FF(DialogBoxParamA, -1)
5454 FF(RegisterClipboardFormatA, -1)
5455 FF(CharNextA, -1)
5456 FF(EnumDisplaySettingsA, -1)
5458 struct exports exp_advapi32[]={
5459 FF(RegCloseKey, -1)
5460 FF(RegCreateKeyA, -1)
5461 FF(RegCreateKeyExA, -1)
5462 FF(RegEnumKeyExA, -1)
5463 FF(RegEnumValueA, -1)
5464 FF(RegOpenKeyA, -1)
5465 FF(RegOpenKeyExA, -1)
5466 FF(RegQueryValueExA, -1)
5467 FF(RegSetValueExA, -1)
5468 FF(RegQueryInfoKeyA, -1)
5470 struct exports exp_gdi32[]={
5471 FF(CreateCompatibleDC, -1)
5472 FF(CreateFontA, -1)
5473 FF(DeleteDC, -1)
5474 FF(DeleteObject, -1)
5475 FF(GetDeviceCaps, -1)
5476 FF(GetSystemPaletteEntries, -1)
5477 #ifdef CONFIG_QTX_CODECS
5478 FF(CreatePalette, -1)
5479 FF(GetObjectA, -1)
5480 FF(CreateRectRgn, -1)
5481 #endif
5483 struct exports exp_version[]={
5484 FF(GetFileVersionInfoSizeA, -1)
5486 struct exports exp_ole32[]={
5487 FF(CoCreateFreeThreadedMarshaler,-1)
5488 FF(CoCreateInstance, -1)
5489 FF(CoInitialize, -1)
5490 FF(CoInitializeEx, -1)
5491 FF(CoUninitialize, -1)
5492 FF(CoTaskMemAlloc, -1)
5493 FF(CoTaskMemFree, -1)
5494 FF(StringFromGUID2, -1)
5495 FF(PropVariantClear, -1)
5497 // do we really need crtdll ???
5498 // msvcrt is the correct place probably...
5499 struct exports exp_crtdll[]={
5500 FF(memcpy, -1)
5501 FF(wcscpy, -1)
5503 struct exports exp_comctl32[]={
5504 FF(StringFromGUID2, -1)
5505 FF(InitCommonControls, 17)
5506 #ifdef CONFIG_QTX_CODECS
5507 FF(CreateUpDownControl, 16)
5508 #endif
5510 struct exports exp_wsock32[]={
5511 FF(htonl,8)
5512 FF(ntohl,14)
5514 struct exports exp_msdmo[]={
5515 FF(memcpy, -1) // just test
5516 FF(MoCopyMediaType, -1)
5517 FF(MoCreateMediaType, -1)
5518 FF(MoDeleteMediaType, -1)
5519 FF(MoDuplicateMediaType, -1)
5520 FF(MoFreeMediaType, -1)
5521 FF(MoInitMediaType, -1)
5523 struct exports exp_oleaut32[]={
5524 FF(SysAllocStringLen, 4)
5525 FF(SysFreeString, 6)
5526 FF(VariantInit, 8)
5527 #ifdef CONFIG_QTX_CODECS
5528 FF(SysStringByteLen, 149)
5529 #endif
5532 /* realplayer8:
5533 DLL Name: PNCRT.dll
5534 vma: Hint/Ord Member-Name
5535 22ff4 615 free
5536 2302e 250 _ftol
5537 22fea 666 malloc
5538 2303e 609 fprintf
5539 2305e 167 _adjust_fdiv
5540 23052 280 _initterm
5542 22ffc 176 _beginthreadex
5543 23036 284 _iob
5544 2300e 85 __CxxFrameHandler
5545 23022 411 _purecall
5547 #ifdef REALPLAYER
5548 struct exports exp_pncrt[]={
5549 FF(malloc, -1) // just test
5550 FF(free, -1) // just test
5551 FF(fprintf, -1) // just test
5552 {"_adjust_fdiv", -1, (void*)&_adjust_fdiv},
5553 FF(_ftol,-1)
5554 FF(_initterm, -1)
5555 {"??3@YAXPAX@Z", -1, expdelete},
5556 {"??2@YAPAXI@Z", -1, expnew},
5557 FF(__dllonexit, -1)
5558 FF(strncpy, -1)
5559 FF(_CIpow,-1)
5560 FF(calloc,-1)
5561 FF(memmove, -1)
5562 FF(ldexp, -1)
5563 FF(frexp, -1)
5565 #endif
5567 #ifdef CONFIG_QTX_CODECS
5568 struct exports exp_ddraw[]={
5569 FF(DirectDrawCreate, -1)
5571 #endif
5573 struct exports exp_comdlg32[]={
5574 FF(GetOpenFileNameA, -1)
5577 struct exports exp_shlwapi[]={
5578 FF(PathFindExtensionA, -1)
5579 FF(PathFindFileNameA, -1)
5582 struct exports exp_msvcr80[]={
5583 FF(_CIpow,-1)
5584 FF(_CIsin,-1)
5585 FF(_CIcos,-1)
5586 FF(_CIsqrt,-1)
5587 FF(memset,-1)
5588 FF(_initterm_e, -1)
5589 FF(_initterm, -1)
5590 FF(_decode_pointer, -1)
5591 /* needed by KGV1-VFW.dll */
5592 {"??2@YAPAXI@Z", -1, expnew},
5593 {"??3@YAXPAX@Z", -1, expdelete}
5596 struct exports exp_msvcp60[]={
5597 {"??0_Lockit@std@@QAE@XZ", -1, exp_0Lockit_dummy},
5598 {"??1_Lockit@std@@QAE@XZ", -1, exp_1Lockit_dummy}
5601 #define LL(X) \
5602 {#X".dll", sizeof(exp_##X)/sizeof(struct exports), exp_##X},
5604 struct libs libraries[]={
5605 LL(kernel32)
5606 LL(msvcrt)
5607 LL(winmm)
5608 LL(psapi)
5609 LL(user32)
5610 LL(advapi32)
5611 LL(gdi32)
5612 LL(version)
5613 LL(ole32)
5614 LL(oleaut32)
5615 LL(crtdll)
5616 LL(comctl32)
5617 LL(wsock32)
5618 LL(msdmo)
5619 #ifdef REALPLAYER
5620 LL(pncrt)
5621 #endif
5622 #ifdef CONFIG_QTX_CODECS
5623 LL(ddraw)
5624 #endif
5625 LL(comdlg32)
5626 LL(shlwapi)
5627 LL(msvcr80)
5628 LL(msvcp60)
5631 static WIN_BOOL WINAPI ext_stubs(void)
5633 // NOTE! these magic values will be replaced at runtime, make sure
5634 // add_stub can still find them if you change them.
5635 volatile int idx = 0x0deadabc;
5636 // make sure gcc does not do eip-relative call or something like that
5637 void (* volatile my_printf)(char *, char *) = (void *)0xdeadfbcd;
5638 my_printf("Called unk_%s\n", export_names[idx]);
5639 return 0;
5642 #define MAX_STUB_SIZE 0x60
5643 #define MAX_NUM_STUBS 200
5644 static int pos=0;
5645 static char *extcode = NULL;
5647 static void* add_stub(void)
5649 int i;
5650 int found = 0;
5651 // generated code in runtime!
5652 char* answ;
5653 if (!extcode)
5654 extcode = mmap_anon(NULL, MAX_NUM_STUBS * MAX_STUB_SIZE,
5655 PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE, 0);
5656 answ = extcode + pos * MAX_STUB_SIZE;
5657 if (pos >= MAX_NUM_STUBS) {
5658 printf("too many stubs, expect crash\n");
5659 return NULL;
5661 memcpy(answ, ext_stubs, MAX_STUB_SIZE);
5662 for (i = 0; i < MAX_STUB_SIZE - 3; i++) {
5663 int *magic = (int *)(answ + i);
5664 if (*magic == 0x0deadabc) {
5665 *magic = pos;
5666 found |= 1;
5668 if (*magic == 0xdeadfbcd) {
5669 *magic = (intptr_t)printf;
5670 found |= 2;
5673 if (found != 3) {
5674 printf("magic code not found in ext_subs, expect crash\n");
5675 return NULL;
5677 pos++;
5678 return (void*)answ;
5681 void* LookupExternal(const char* library, int ordinal)
5683 int i,j;
5684 if(library==0)
5686 printf("ERROR: library=0\n");
5687 return (void*)ext_unknown;
5689 // printf("%x %x\n", &unk_exp1, &unk_exp2);
5691 dbgprintf("External func %s:%d\n", library, ordinal);
5693 for(i=0; i<sizeof(libraries)/sizeof(struct libs); i++)
5695 if(strcasecmp(library, libraries[i].name))
5696 continue;
5697 for(j=0; j<libraries[i].length; j++)
5699 if(ordinal!=libraries[i].exps[j].id)
5700 continue;
5701 //printf("Hit: 0x%p\n", libraries[i].exps[j].func);
5702 return libraries[i].exps[j].func;
5706 #ifndef LOADLIB_TRY_NATIVE
5707 /* hack for truespeech and vssh264*/
5708 if (!strcmp(library, "tsd32.dll") || !strcmp(library,"vssh264dec.dll") || !strcmp(library,"LCMW2.dll") || !strcmp(library,"VDODEC32.dll"))
5709 #endif
5710 /* ok, this is a hack, and a big memory leak. should be fixed. - alex */
5712 int hand;
5713 WINE_MODREF *wm;
5714 void *func;
5716 hand = LoadLibraryA(library);
5717 if (!hand)
5718 goto no_dll;
5719 wm = MODULE32_LookupHMODULE(hand);
5720 if (!wm)
5722 FreeLibrary(hand);
5723 goto no_dll;
5725 func = PE_FindExportedFunction(wm, (LPCSTR) ordinal, 0);
5726 if (!func)
5728 printf("No such ordinal in external dll\n");
5729 FreeLibrary((int)hand);
5730 goto no_dll;
5733 printf("External dll loaded (offset: 0x%x, func: %p)\n",
5734 hand, func);
5735 return func;
5738 no_dll:
5739 if(pos>150)return 0;
5740 snprintf(export_names[pos], sizeof(export_names[pos]), "%s:%d", library, ordinal);
5741 return add_stub();
5744 void* LookupExternalByName(const char* library, const char* name)
5746 int i,j;
5747 // return (void*)ext_unknown;
5748 if(library==0)
5750 printf("ERROR: library=0\n");
5751 return (void*)ext_unknown;
5753 if((unsigned long)name<=0xffff)
5755 return LookupExternal(library, (int)name);
5757 dbgprintf("External func %s:%s\n", library, name);
5758 for(i=0; i<sizeof(libraries)/sizeof(struct libs); i++)
5760 if(strcasecmp(library, libraries[i].name))
5761 continue;
5762 for(j=0; j<libraries[i].length; j++)
5764 if(strcmp(name, libraries[i].exps[j].name))
5765 continue;
5766 if((unsigned int)(libraries[i].exps[j].func) == -1)
5767 return NULL; //undefined func
5768 // printf("Hit: 0x%08X\n", libraries[i].exps[j].func);
5769 return libraries[i].exps[j].func;
5773 #ifndef LOADLIB_TRY_NATIVE
5774 /* hack for vss h264 */
5775 if (!strcmp(library,"vssh264core.dll") || !strcmp(library,"3ivx.dll"))
5776 #endif
5777 /* ok, this is a hack, and a big memory leak. should be fixed. - alex */
5779 int hand;
5780 WINE_MODREF *wm;
5781 void *func;
5783 hand = LoadLibraryA(library);
5784 if (!hand)
5785 goto no_dll_byname;
5786 wm = MODULE32_LookupHMODULE(hand);
5787 if (!wm)
5789 FreeLibrary(hand);
5790 goto no_dll_byname;
5792 func = PE_FindExportedFunction(wm, name, 0);
5793 if (!func)
5795 printf("No such name in external dll\n");
5796 FreeLibrary((int)hand);
5797 goto no_dll_byname;
5800 printf("External dll loaded (offset: 0x%x, func: %p)\n",
5801 hand, func);
5802 return func;
5805 no_dll_byname:
5806 if(pos>150)return 0;// to many symbols
5807 snprintf(export_names[pos], sizeof(export_names[pos]), "%s", name);
5808 return add_stub();
5811 void my_garbagecollection(void)
5813 #ifdef GARBAGE
5814 int unfree = 0, unfreecnt = 0;
5816 int max_fatal = 8;
5817 free_registry();
5818 while (last_alloc)
5820 alloc_header* mem = last_alloc + 1;
5821 unfree += my_size(mem);
5822 unfreecnt++;
5823 if (my_release(mem) != 0)
5824 // avoid endless loop when memory is trashed
5825 if (--max_fatal < 0)
5826 break;
5828 dbgprintf("Total Unfree %d bytes cnt %d [%p,%d]\n",unfree, unfreecnt, last_alloc, alccnt);
5829 #endif
5830 g_tls = NULL;
5831 pthread_mutex_lock(&list_lock);
5832 list = NULL;
5833 pthread_mutex_unlock(&list_lock);