input: fix possible crash in printing key combo names
[mplayer.git] / loader / win32.c
blobfb7f48b09e4577b7473c7b3442fcb9d10837b521
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 "ldt_keeper.h"
53 #include "path.h"
55 #include <stdlib.h>
56 #include <assert.h>
57 #include <stdarg.h>
58 #include <ctype.h>
59 #include <pthread.h>
60 #include <errno.h>
61 #include <time.h>
62 #include <math.h>
63 #include <unistd.h>
64 #include <fcntl.h>
65 #include <sys/types.h>
66 #include <dirent.h>
67 #include <sys/time.h>
68 #include <sys/stat.h>
69 #ifdef HAVE_KSTAT
70 #include <kstat.h>
71 #endif
73 #ifdef HAVE_SYS_MMAN_H
74 #include <sys/mman.h>
75 #else
76 #include "osdep/mmap.h"
77 #endif
78 #include "osdep/mmap_anon.h"
79 #include "libavutil/avstring.h"
80 #include "cpudetect.h"
82 static unsigned int c_localcount_tsc(void)
84 int a;
85 __asm__ volatile
87 "rdtsc\n\t"
88 :"=a"(a)
90 :"edx"
92 return a;
94 static void c_longcount_tsc(long long* z)
96 __asm__ volatile
98 "pushl %%ebx\n\t"
99 "movl %%eax, %%ebx\n\t"
100 "rdtsc\n\t"
101 "movl %%eax, 0(%%ebx)\n\t"
102 "movl %%edx, 4(%%ebx)\n\t"
103 "popl %%ebx\n\t"
104 ::"a"(z)
105 :"edx"
108 static unsigned int c_localcount_notsc(void)
110 struct timeval tv;
111 unsigned limit=~0;
112 limit/=1000000;
113 gettimeofday(&tv, 0);
114 return limit*tv.tv_usec;
116 static void c_longcount_notsc(long long* z)
118 struct timeval tv;
119 unsigned long long result;
120 unsigned limit=~0;
121 if(!z)return;
122 limit/=1000000;
123 gettimeofday(&tv, 0);
124 result=tv.tv_sec;
125 result<<=32;
126 result+=limit*tv.tv_usec;
127 *z=result;
129 static unsigned int localcount_stub(void);
130 static void longcount_stub(long long*);
131 static unsigned int (*localcount)(void)=localcount_stub;
132 static void (*longcount)(long long*)=longcount_stub;
134 static pthread_mutex_t memmut = PTHREAD_MUTEX_INITIALIZER;
136 static unsigned int localcount_stub(void)
138 unsigned int regs[4];
139 do_cpuid(1, regs);
140 if ((regs[3] & 0x00000010) != 0)
142 localcount=c_localcount_tsc;
143 longcount=c_longcount_tsc;
145 else
147 localcount=c_localcount_notsc;
148 longcount=c_longcount_notsc;
150 return localcount();
152 static void longcount_stub(long long* z)
154 unsigned int regs[4];
155 do_cpuid(1, regs);
156 if ((regs[3] & 0x00000010) != 0)
158 localcount=c_localcount_tsc;
159 longcount=c_longcount_tsc;
161 else
163 localcount=c_localcount_notsc;
164 longcount=c_longcount_notsc;
166 longcount(z);
169 #include "mp_msg.h"
170 int LOADER_DEBUG=1; // active only if compiled with -DDETAILED_OUT
171 //#define DETAILED_OUT
172 static inline void dbgprintf(char* fmt, ...)
174 #ifdef DETAILED_OUT
175 if(LOADER_DEBUG)
177 FILE* f;
178 va_list va;
179 va_start(va, fmt);
180 f=fopen("./log", "a");
181 vprintf(fmt, va);
182 fflush(stdout);
183 if(f)
185 vfprintf(f, fmt, va);
186 fsync(fileno(f));
187 fclose(f);
189 va_end(va);
191 #endif
192 if ( mp_msg_test(MSGT_WIN32,MSGL_DBG3) )
194 va_list va;
196 va_start(va, fmt);
197 vprintf(fmt, va);
198 // mp_dbg(MSGT_WIN32, MSGL_DBG3, fmt, va);
199 va_end(va);
200 fflush(stdout);
205 char export_names[300][32]={
206 "name1",
207 //"name2",
208 //"name3"
210 //#define min(x,y) ((x)<(y)?(x):(y))
212 void destroy_event(void* event);
214 struct th_list_t;
215 typedef struct th_list_t{
216 int id;
217 void* thread;
218 struct th_list_t* next;
219 struct th_list_t* prev;
220 } th_list;
223 // have to be cleared by GARBAGE COLLECTOR
224 //static unsigned char* heap=NULL;
225 //static int heap_counter=0;
226 static tls_t* g_tls=NULL;
227 static th_list* list=NULL;
228 static pthread_mutex_t list_lock = PTHREAD_MUTEX_INITIALIZER;
230 #if 0
231 static void test_heap(void)
233 int offset=0;
234 if(heap==0)
235 return;
236 while(offset<heap_counter)
238 if(*(int*)(heap+offset)!=0x433476)
240 printf("Heap corruption at address %d\n", offset);
241 return;
243 offset+=8+*(int*)(heap+offset+4);
245 for(;offset<min(offset+1000, 20000000); offset++)
246 if(heap[offset]!=0xCC)
248 printf("Free heap corruption at address %d\n", offset);
251 #endif
252 #undef MEMORY_DEBUG
254 #ifdef MEMORY_DEBUG
256 static void* my_mreq(int size, int to_zero)
258 static int test=0;
259 test++;
260 if(test%10==0)printf("Memory: %d bytes allocated\n", heap_counter);
261 // test_heap();
262 if(heap==NULL)
264 heap=malloc(20000000);
265 memset(heap, 0xCC,20000000);
267 if(heap==0)
269 printf("No enough memory\n");
270 return 0;
272 if(heap_counter+size>20000000)
274 printf("No enough memory\n");
275 return 0;
277 *(int*)(heap+heap_counter)=0x433476;
278 heap_counter+=4;
279 *(int*)(heap+heap_counter)=size;
280 heap_counter+=4;
281 printf("Allocated %d bytes of memory: sys %d, user %d-%d\n", size, heap_counter-8, heap_counter, heap_counter+size);
282 if(to_zero)
283 memset(heap+heap_counter, 0, size);
284 else
285 memset(heap+heap_counter, 0xcc, size); // make crash reproducable
286 heap_counter+=size;
287 return heap+heap_counter-size;
289 static int my_release(char* memory)
291 // test_heap();
292 if(memory==NULL)
294 printf("ERROR: free(0)\n");
295 return 0;
297 if(*(int*)(memory-8)!=0x433476)
299 printf("MEMORY CORRUPTION !!!!!!!!!!!!!!!!!!!\n");
300 return 0;
302 printf("Freed %d bytes of memory\n", *(int*)(memory-4));
303 // memset(memory-8, *(int*)(memory-4), 0xCC);
304 return 0;
307 #else
308 #define GARBAGE
309 typedef struct alloc_header_t alloc_header;
310 struct alloc_header_t
312 // let's keep allocated data 16 byte aligned
313 alloc_header* prev;
314 alloc_header* next;
315 long deadbeef;
316 long size;
317 long type;
318 long reserved1;
319 long reserved2;
320 long reserved3;
323 #ifdef GARBAGE
324 static alloc_header* last_alloc = NULL;
325 static int alccnt = 0;
326 #endif
328 #define AREATYPE_CLIENT 0
329 #define AREATYPE_EVENT 1
330 #define AREATYPE_MUTEX 2
331 #define AREATYPE_COND 3
332 #define AREATYPE_CRITSECT 4
334 /* -- critical sections -- */
335 struct CRITSECT
337 pthread_t id;
338 pthread_mutex_t mutex;
339 pthread_cond_t unlocked;
340 int lock_count;
341 long deadbeef;
344 void* mreq_private(int size, int to_zero, int type);
345 void* mreq_private(int size, int to_zero, int type)
347 int nsize = size + sizeof(alloc_header);
348 alloc_header* header = malloc(nsize);
349 if (!header)
350 return 0;
351 if (to_zero)
352 memset(header, 0, nsize);
353 #ifdef GARBAGE
354 pthread_mutex_lock(&memmut);
355 if (last_alloc)
357 last_alloc->next = header; /* set next */
360 header->prev = last_alloc;
361 header->next = 0;
362 last_alloc = header;
363 alccnt++;
364 pthread_mutex_unlock(&memmut);
365 #endif
366 header->deadbeef = 0xdeadbeef;
367 header->size = size;
368 header->type = type;
370 //if (alccnt < 40000) printf("MY_REQ: %p\t%d t:%d (cnt:%d)\n", header, size, type, alccnt);
371 return header + 1;
374 static int my_release(void* memory)
376 alloc_header* header = (alloc_header*) memory - 1;
377 #ifdef GARBAGE
378 alloc_header* prevmem;
379 alloc_header* nextmem;
381 if (memory == 0)
382 return 0;
384 if (header->deadbeef != (long) 0xdeadbeef)
386 dbgprintf("FATAL releasing corrupted memory! %p 0x%lx (%d)\n", header, header->deadbeef, alccnt);
387 return 0;
390 pthread_mutex_lock(&memmut);
392 switch(header->type)
394 case AREATYPE_EVENT:
395 destroy_event(memory);
396 break;
397 case AREATYPE_COND:
398 pthread_cond_destroy((pthread_cond_t*)memory);
399 break;
400 case AREATYPE_MUTEX:
401 pthread_mutex_destroy((pthread_mutex_t*)memory);
402 break;
403 case AREATYPE_CRITSECT:
404 pthread_mutex_destroy(&((struct CRITSECT*)memory)->mutex);
405 break;
406 default:
407 //memset(memory, 0xcc, header->size);
411 header->deadbeef = 0;
412 prevmem = header->prev;
413 nextmem = header->next;
415 if (prevmem)
416 prevmem->next = nextmem;
417 if (nextmem)
418 nextmem->prev = prevmem;
420 if (header == last_alloc)
421 last_alloc = prevmem;
423 alccnt--;
425 pthread_mutex_unlock(&memmut);
427 //if (alccnt < 40000) printf("MY_RELEASE: %p\t%ld (%d)\n", header, header->size, alccnt);
428 #else
429 if (memory == 0)
430 return 0;
431 #endif
432 //memset(header + 1, 0xcc, header->size);
433 free(header);
434 return 0;
436 #endif
438 static inline void* my_mreq(int size, int to_zero)
440 return mreq_private(size, to_zero, AREATYPE_CLIENT);
443 static int my_size(void* memory)
445 if(!memory) return 0;
446 return ((alloc_header*)memory)[-1].size;
449 static void* my_realloc(void* memory, int size)
451 void *ans = memory;
452 int osize;
453 if (memory == NULL)
454 return my_mreq(size, 0);
455 osize = my_size(memory);
456 if (osize < size)
458 ans = my_mreq(size, 0);
459 memcpy(ans, memory, osize);
460 my_release(memory);
462 return ans;
467 * WINE API - native implementation for several win32 libraries
471 static int WINAPI ext_unknown(void)
473 printf("Unknown func called\n");
474 return 0;
477 static int WINAPI expGetVolumeInformationA( const char *root, char *label,
478 unsigned int label_len, unsigned int *serial,
479 unsigned int *filename_len,unsigned int *flags,
480 char *fsname, unsigned int fsname_len )
482 dbgprintf("GetVolumeInformationA( %s, 0x%x, %ld, 0x%x, 0x%x, 0x%x, 0x%x, %ld) => 1\n",
483 root,label,label_len,serial,filename_len,flags,fsname,fsname_len);
484 //hack Do not return any real data - do nothing
485 return 1;
488 static unsigned int WINAPI expGetDriveTypeA( const char *root )
490 dbgprintf("GetDriveTypeA( %s ) => %d\n",root,DRIVE_FIXED);
491 // hack return as Fixed Drive Type
492 return DRIVE_FIXED;
495 static unsigned int WINAPI expGetLogicalDriveStringsA( unsigned int len, char *buffer )
497 dbgprintf("GetLogicalDriveStringsA(%d, 0x%x) => 4\n",len,buffer);
498 // hack only have one drive c:\ in this hack
499 *buffer++='c';
500 *buffer++=':';
501 *buffer++='\\';
502 *buffer++='\0';
503 *buffer= '\0';
504 return 4; // 1 drive * 4 bytes (includes null)
508 static int WINAPI expIsBadWritePtr(void* ptr, unsigned int count)
510 int result = (count == 0 || ptr != 0) ? 0 : 1;
511 dbgprintf("IsBadWritePtr(0x%x, 0x%x) => %d\n", ptr, count, result);
512 return result;
514 static int WINAPI expIsBadReadPtr(void* ptr, unsigned int count)
516 int result = (count == 0 || ptr != 0) ? 0 : 1;
517 dbgprintf("IsBadReadPtr(0x%x, 0x%x) => %d\n", ptr, count, result);
518 return result;
520 static int WINAPI expDisableThreadLibraryCalls(int module)
522 dbgprintf("DisableThreadLibraryCalls(0x%x) => 0\n", module);
523 return 0;
526 static HMODULE WINAPI expGetDriverModuleHandle(DRVR* pdrv)
528 HMODULE result;
529 if (pdrv==NULL)
530 result=0;
531 else
532 result=pdrv->hDriverModule;
533 dbgprintf("GetDriverModuleHandle(%p) => %p\n", pdrv, result);
534 return result;
537 #define MODULE_HANDLE_kernel32 ((HMODULE)0x120)
538 #define MODULE_HANDLE_user32 ((HMODULE)0x121)
539 #ifdef CONFIG_QTX_CODECS
540 #define MODULE_HANDLE_wininet ((HMODULE)0x122)
541 #define MODULE_HANDLE_ddraw ((HMODULE)0x123)
542 #define MODULE_HANDLE_advapi32 ((HMODULE)0x124)
543 #endif
544 #define MODULE_HANDLE_comdlg32 ((HMODULE)0x125)
545 #define MODULE_HANDLE_msvcrt ((HMODULE)0x126)
546 #define MODULE_HANDLE_ole32 ((HMODULE)0x127)
547 #define MODULE_HANDLE_winmm ((HMODULE)0x128)
548 #define MODULE_HANDLE_psapi ((HMODULE)0x129)
550 // Fake PE header, since some software (and the Microsoft CRT v8 and newer)
551 // assume GetModuleHandle(NULL) returns a pointer to a PE header.
552 // We simulate a very simple header with only one section.
554 // NOTE: If you have a section called .mixcrt, the Microsoft CRT will assume
555 // it's running in a POSIX binary, and stop using EncodePointer/DecodePointer.
556 static const struct {
557 IMAGE_DOS_HEADER doshdr;
558 IMAGE_NT_HEADERS nthdr;
559 IMAGE_SECTION_HEADER opthdr;
560 } __attribute__((__packed__)) mp_exe = {
561 .doshdr.e_lfanew = sizeof(IMAGE_DOS_HEADER),
562 .nthdr.FileHeader.NumberOfSections = 1,
563 .nthdr.FileHeader.SizeOfOptionalHeader =
564 sizeof(IMAGE_NT_HEADERS) - FIELD_OFFSET(IMAGE_NT_HEADERS, OptionalHeader), /* 0xe0 */
565 .opthdr.Name = ".text"
568 static HMODULE WINAPI expGetModuleHandleA(const char* name)
570 WINE_MODREF* wm;
571 HMODULE result;
572 if(!name)
573 result=(HMODULE)&mp_exe.doshdr;
574 else
576 wm=MODULE_FindModule(name);
577 if(wm==0)result=0;
578 else
579 result=(HMODULE)(wm->module);
581 if(!result)
583 if(name && (strcasecmp(name, "kernel32")==0 || !strcasecmp(name, "kernel32.dll")))
584 result=MODULE_HANDLE_kernel32;
585 #ifdef CONFIG_QTX_CODECS
586 if(name && strcasecmp(name, "user32")==0)
587 result=MODULE_HANDLE_user32;
588 #endif
590 dbgprintf("GetModuleHandleA('%s') => 0x%x\n", name, result);
591 return result;
594 static HMODULE WINAPI expGetModuleHandleW(const uint16_t* name)
596 char aname[256];
597 int pos = 0;
598 while (*name) {
599 if (*name > 256 || pos >= sizeof(aname) - 1)
600 return 0;
601 aname[pos++] = *name++;
603 aname[pos] = 0;
604 return expGetModuleHandleA(aname);
607 static void* WINAPI expCreateThread(void* pSecAttr, long dwStackSize,
608 void* lpStartAddress, void* lpParameter,
609 long dwFlags, long* dwThreadId)
611 pthread_t *pth;
612 // printf("CreateThread:");
613 pth = (pthread_t*) my_mreq(sizeof(pthread_t), 0);
614 pthread_create(pth, NULL, (void*(*)(void*))lpStartAddress, lpParameter);
615 if(dwFlags)
616 printf( "WARNING: CreateThread flags not supported\n");
617 if(dwThreadId)
618 *dwThreadId=(long)pth;
619 pthread_mutex_lock(&list_lock);
620 if(list==NULL)
622 list=my_mreq(sizeof(th_list), 1);
623 list->next=list->prev=NULL;
625 else
627 list->next=my_mreq(sizeof(th_list), 0);
628 list->next->prev=list;
629 list->next->next=NULL;
630 list=list->next;
632 list->thread=pth;
633 pthread_mutex_unlock(&list_lock);
634 dbgprintf("CreateThread(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x) => 0x%x\n",
635 pSecAttr, dwStackSize, lpStartAddress, lpParameter, dwFlags, dwThreadId, pth);
636 return pth;
639 static DWORD WINAPI expResumeThread(HANDLE hThread)
641 int ret = 1;
642 dbgprintf("ResumeThread(0x%x) => 0x%x\n", hThread, ret);
643 return ret;
646 struct mutex_list_t;
648 struct mutex_list_t
650 char type;
651 pthread_mutex_t *pm;
652 pthread_cond_t *pc;
653 char state;
654 char reset;
655 char name[128];
656 int semaphore;
657 int lock_count;
658 pthread_t owner;
659 struct mutex_list_t* next;
660 struct mutex_list_t* prev;
662 typedef struct mutex_list_t mutex_list;
663 static mutex_list* mlist=NULL;
664 static pthread_mutex_t mlist_lock = PTHREAD_MUTEX_INITIALIZER;
666 void destroy_event(void* event)
668 mutex_list *pp;
669 pthread_mutex_lock(&mlist_lock);
670 pp=mlist;
671 // printf("garbage collector: destroy_event(%x)\n", event);
672 while(pp)
674 if(pp==(mutex_list*)event)
676 if(pp->next)
677 pp->next->prev=pp->prev;
678 if(pp->prev)
679 pp->prev->next=pp->next;
680 if(mlist==(mutex_list*)event)
681 mlist=mlist->prev;
683 pp=mlist;
684 while(pp)
686 printf("%x => ", pp);
687 pp=pp->prev;
689 printf("0\n");
691 pthread_mutex_unlock(&mlist_lock);
692 return;
694 pp=pp->prev;
696 pthread_mutex_unlock(&mlist_lock);
699 static void* WINAPI expCreateEventA(void* pSecAttr, char bManualReset,
700 char bInitialState, const char* name)
702 pthread_mutex_t *pm;
703 pthread_cond_t *pc;
704 void *ret;
706 mutex_list* pp;
707 pp=mlist;
708 while(pp)
710 printf("%x => ", pp);
711 pp=pp->prev;
713 printf("0\n");
715 pthread_mutex_lock(&mlist_lock);
716 if(mlist!=NULL)
718 mutex_list* pp=mlist;
719 if(name!=NULL)
722 if((strcmp(pp->name, name)==0) && (pp->type==0))
724 dbgprintf("CreateEventA(0x%x, 0x%x, 0x%x, 0x%x='%s') => 0x%x\n",
725 pSecAttr, bManualReset, bInitialState, name, name, pp->pm);
726 pthread_mutex_unlock(&mlist_lock);
727 return pp->pm;
729 }while((pp=pp->prev) != NULL);
731 pm=mreq_private(sizeof(pthread_mutex_t), 0, AREATYPE_MUTEX);
732 pthread_mutex_init(pm, NULL);
733 pc=mreq_private(sizeof(pthread_cond_t), 0, AREATYPE_COND);
734 pthread_cond_init(pc, NULL);
735 if(mlist==NULL)
737 mlist=mreq_private(sizeof(mutex_list), 00, AREATYPE_EVENT);
738 mlist->next=mlist->prev=NULL;
740 else
742 mlist->next=mreq_private(sizeof(mutex_list), 00, AREATYPE_EVENT);
743 mlist->next->prev=mlist;
744 mlist->next->next=NULL;
745 mlist=mlist->next;
747 mlist->type=0; /* Type Event */
748 mlist->pm=pm;
749 mlist->pc=pc;
750 mlist->state=bInitialState;
751 mlist->reset=!bManualReset;
752 if(name)
753 strncpy(mlist->name, name, 127);
754 else
755 mlist->name[0]=0;
756 if(pm==NULL)
757 dbgprintf("ERROR::: CreateEventA failure\n");
759 if(bInitialState)
760 pthread_mutex_lock(pm);
762 if(name)
763 dbgprintf("CreateEventA(0x%x, 0x%x, 0x%x, 0x%x='%s') => 0x%x\n",
764 pSecAttr, bManualReset, bInitialState, name, name, mlist);
765 else
766 dbgprintf("CreateEventA(0x%x, 0x%x, 0x%x, NULL) => 0x%x\n",
767 pSecAttr, bManualReset, bInitialState, mlist);
768 ret = mlist;
769 pthread_mutex_unlock(&mlist_lock);
770 return ret;
773 static void* WINAPI expCreateEventW(void* pSecAttr, char bManualReset,
774 char bInitialState, const WCHAR* name)
776 char ascii_name[256];
777 char *aname = NULL;
778 if (name) {
779 WideCharToMultiByte(65001, 0x0, name, -1, ascii_name, 256, NULL, NULL);
780 aname = ascii_name;
782 return expCreateEventA(pSecAttr, bManualReset, bInitialState, aname);
785 static void* WINAPI expSetEvent(void* event)
787 mutex_list *ml = (mutex_list *)event;
788 dbgprintf("SetEvent(%x) => 0x1\n", event);
789 pthread_mutex_lock(ml->pm);
790 if (ml->state == 0) {
791 ml->state = 1;
792 pthread_cond_signal(ml->pc);
794 pthread_mutex_unlock(ml->pm);
796 return (void *)1;
798 static void* WINAPI expResetEvent(void* event)
800 mutex_list *ml = (mutex_list *)event;
801 dbgprintf("ResetEvent(0x%x) => 0x1\n", event);
802 pthread_mutex_lock(ml->pm);
803 ml->state = 0;
804 pthread_mutex_unlock(ml->pm);
806 return (void *)1;
809 static void* WINAPI expWaitForSingleObject(void* object, int duration)
811 mutex_list *ml = (mutex_list *)object;
812 // FIXME FIXME FIXME - this value is sometime unititialize !!!
813 int ret = WAIT_FAILED;
814 mutex_list* pp;
815 th_list* tp;
816 if(object == (void*)0xcfcf9898)
819 From GetCurrentThread() documentation:
820 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.
822 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.
824 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.
826 dbgprintf("WaitForSingleObject(thread_handle) called\n");
827 return (void*)WAIT_FAILED;
829 dbgprintf("WaitForSingleObject(0x%x, duration %d) =>\n",object, duration);
831 // See if this is a thread.
832 pthread_mutex_lock(&list_lock);
833 tp=list;
834 while (tp && (tp->thread != object))
835 tp = tp->prev;
836 pthread_mutex_unlock(&list_lock);
837 if (tp) {
838 if (pthread_join(*(pthread_t*)object, NULL) == 0) {
839 return (void*)WAIT_OBJECT_0;
840 } else {
841 return (void*)WAIT_FAILED;
845 // loop below was slightly fixed - its used just for checking if
846 // this object really exists in our list
847 if (!ml)
848 return (void*) ret;
849 pthread_mutex_lock(&mlist_lock);
850 pp=mlist;
851 while (pp && (pp->pm != ml->pm))
852 pp = pp->prev;
853 pthread_mutex_unlock(&mlist_lock);
854 if (!pp) {
855 dbgprintf("WaitForSingleObject: NotFound\n");
856 return (void*)ret;
859 pthread_mutex_lock(ml->pm);
861 switch(ml->type) {
862 case 0: /* Event */
863 if (duration == 0) { /* Check Only */
864 if (ml->state == 1) ret = WAIT_OBJECT_0;
865 else ret = WAIT_FAILED;
867 if (duration == -1) { /* INFINITE */
868 if (ml->state == 0)
869 pthread_cond_wait(ml->pc,ml->pm);
870 if (ml->reset)
871 ml->state = 0;
872 ret = WAIT_OBJECT_0;
874 if (duration > 0) { /* Timed Wait */
875 struct timespec abstime;
876 struct timeval now;
877 gettimeofday(&now, 0);
878 abstime.tv_sec = now.tv_sec + (now.tv_usec+duration)/1000000;
879 abstime.tv_nsec = ((now.tv_usec+duration)%1000000)*1000;
880 if (ml->state == 0)
881 ret=pthread_cond_timedwait(ml->pc,ml->pm,&abstime);
882 if (ret == ETIMEDOUT) ret = WAIT_TIMEOUT;
883 else ret = WAIT_OBJECT_0;
884 if (ml->reset)
885 ml->state = 0;
887 break;
888 case 1: /* Semaphore */
889 if (duration == 0) {
890 if(ml->semaphore==0) ret = WAIT_FAILED;
891 else {
892 ml->semaphore--;
893 ret = WAIT_OBJECT_0;
896 if (duration == -1) {
897 if (ml->semaphore==0)
898 pthread_cond_wait(ml->pc,ml->pm);
899 ml->semaphore--;
900 ret = WAIT_OBJECT_0;
902 break;
903 case 2: /* Mutex */
904 if (duration == 0) {
905 if(ml->lock_count > 0 && ml->owner != pthread_self()) ret = WAIT_FAILED;
906 else {
907 ml->lock_count++;
908 ml->owner = pthread_self();
909 ret = WAIT_OBJECT_0;
912 if (duration == -1) {
913 if (ml->lock_count > 0 && ml->owner != pthread_self()) {
914 pthread_cond_wait(ml->pc,ml->pm);
916 ml->lock_count++;
917 ml->owner = pthread_self();
918 ret = WAIT_OBJECT_0;
920 break;
922 pthread_mutex_unlock(ml->pm);
924 dbgprintf("WaitForSingleObject(0x%x, %d): 0x%x => 0x%x \n",object,duration,ml,ret);
925 return (void *)ret;
928 #ifdef CONFIG_QTX_CODECS
929 static void* WINAPI expWaitForMultipleObjects(int count, const void** objects,
930 int WaitAll, int duration)
932 int i;
933 void *object;
934 void *ret;
936 dbgprintf("WaitForMultipleObjects(%d, 0x%x, %d, duration %d) =>\n",
937 count, objects, WaitAll, duration);
939 for (i = 0; i < count; i++)
941 object = (void *)objects[i];
942 ret = expWaitForSingleObject(object, duration);
943 if (WaitAll)
944 dbgprintf("WaitAll flag not yet supported...\n");
945 else
946 return ret;
948 return NULL;
951 static void WINAPI expExitThread(int retcode)
953 dbgprintf("ExitThread(%d)\n", retcode);
954 pthread_exit(&retcode);
956 #endif
958 static int pf_set = 0;
959 static BYTE PF[64] = {0,};
961 static void DumpSystemInfo(const SYSTEM_INFO* si)
963 dbgprintf(" Processor architecture %d\n", si->u.s.wProcessorArchitecture);
964 dbgprintf(" Page size: %d\n", si->dwPageSize);
965 dbgprintf(" Minimum app address: %d\n", si->lpMinimumApplicationAddress);
966 dbgprintf(" Maximum app address: %d\n", si->lpMaximumApplicationAddress);
967 dbgprintf(" Active processor mask: 0x%x\n", si->dwActiveProcessorMask);
968 dbgprintf(" Number of processors: %d\n", si->dwNumberOfProcessors);
969 dbgprintf(" Processor type: 0x%x\n", si->dwProcessorType);
970 dbgprintf(" Allocation granularity: 0x%x\n", si->dwAllocationGranularity);
971 dbgprintf(" Processor level: 0x%x\n", si->wProcessorLevel);
972 dbgprintf(" Processor revision: 0x%x\n", si->wProcessorRevision);
975 static void WINAPI expGetSystemInfo(SYSTEM_INFO* si)
977 /* FIXME: better values for the two entries below... */
978 static int cache = 0;
979 static SYSTEM_INFO cachedsi;
980 dbgprintf("GetSystemInfo(%p) =>\n", si);
982 if (cache) {
983 goto exit;
985 memset(PF,0,sizeof(PF));
986 pf_set = 1;
988 cachedsi.u.s.wProcessorArchitecture = PROCESSOR_ARCHITECTURE_INTEL;
989 cachedsi.dwPageSize = getpagesize();
991 /* FIXME: better values for the two entries below... */
992 cachedsi.lpMinimumApplicationAddress = (void *)0x00000000;
993 cachedsi.lpMaximumApplicationAddress = (void *)0x7FFFFFFF;
994 cachedsi.dwActiveProcessorMask = 1;
995 cachedsi.dwNumberOfProcessors = 1;
996 cachedsi.dwProcessorType = PROCESSOR_INTEL_386;
997 cachedsi.dwAllocationGranularity = 0x10000;
998 cachedsi.wProcessorLevel = 5; /* pentium */
999 cachedsi.wProcessorRevision = 0x0101;
1001 /* mplayer's way to detect PF's */
1003 #include "cpudetect.h"
1005 if (gCpuCaps.hasMMX)
1006 PF[PF_MMX_INSTRUCTIONS_AVAILABLE] = TRUE;
1007 if (gCpuCaps.hasSSE)
1008 PF[PF_XMMI_INSTRUCTIONS_AVAILABLE] = TRUE;
1009 if (gCpuCaps.hasSSE2)
1010 PF[PF_XMMI64_INSTRUCTIONS_AVAILABLE] = TRUE;
1011 if (gCpuCaps.has3DNow)
1012 PF[PF_AMD3D_INSTRUCTIONS_AVAILABLE] = TRUE;
1014 if (gCpuCaps.cpuType == 4)
1016 cachedsi.dwProcessorType = PROCESSOR_INTEL_486;
1017 cachedsi.wProcessorLevel = 4;
1019 else if (gCpuCaps.cpuType >= 5)
1021 cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
1022 cachedsi.wProcessorLevel = 5;
1024 else
1026 cachedsi.dwProcessorType = PROCESSOR_INTEL_386;
1027 cachedsi.wProcessorLevel = 3;
1029 cachedsi.wProcessorRevision = gCpuCaps.cpuStepping;
1030 cachedsi.dwNumberOfProcessors = 1; /* hardcoded */
1033 /* MPlayer: linux detection enabled (based on proc/cpuinfo) for checking
1034 fdiv_bug and fpu emulation flags -- alex/MPlayer */
1035 #ifdef __linux__
1037 char buf[20];
1038 char line[200];
1039 FILE *f = fopen ("/proc/cpuinfo", "r");
1041 if (!f)
1043 mp_msg(MSGT_WIN32, MSGL_WARN, "expGetSystemInfo: "
1044 "/proc/cpuinfo not readable! "
1045 "Expect bad performance and/or weird behaviour\n");
1046 goto exit;
1048 while (fgets(line,200,f)!=NULL) {
1049 char *s,*value;
1051 /* NOTE: the ':' is the only character we can rely on */
1052 if (!(value = strchr(line,':')))
1053 continue;
1054 /* terminate the valuename */
1055 *value++ = '\0';
1056 /* skip any leading spaces */
1057 while (*value==' ') value++;
1058 if ((s=strchr(value,'\n')))
1059 *s='\0';
1061 /* 2.1 method */
1062 if (!lstrncmpiA(line, "cpu family",strlen("cpu family"))) {
1063 if (isdigit (value[0])) {
1064 switch (value[0] - '0') {
1065 case 3: cachedsi.dwProcessorType = PROCESSOR_INTEL_386;
1066 cachedsi.wProcessorLevel= 3;
1067 break;
1068 case 4: cachedsi.dwProcessorType = PROCESSOR_INTEL_486;
1069 cachedsi.wProcessorLevel= 4;
1070 break;
1071 case 5: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
1072 cachedsi.wProcessorLevel= 5;
1073 break;
1074 case 6: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
1075 cachedsi.wProcessorLevel= 5;
1076 break;
1077 default:cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
1078 cachedsi.wProcessorLevel= 5;
1079 break;
1082 /* set the CPU type of the current processor */
1083 sprintf(buf,"CPU %ld",cachedsi.dwProcessorType);
1084 continue;
1086 /* old 2.0 method */
1087 if (!lstrncmpiA(line, "cpu",strlen("cpu"))) {
1088 if ( isdigit (value[0]) && value[1] == '8' &&
1089 value[2] == '6' && value[3] == 0
1091 switch (value[0] - '0') {
1092 case 3: cachedsi.dwProcessorType = PROCESSOR_INTEL_386;
1093 cachedsi.wProcessorLevel= 3;
1094 break;
1095 case 4: cachedsi.dwProcessorType = PROCESSOR_INTEL_486;
1096 cachedsi.wProcessorLevel= 4;
1097 break;
1098 case 5: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
1099 cachedsi.wProcessorLevel= 5;
1100 break;
1101 case 6: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
1102 cachedsi.wProcessorLevel= 5;
1103 break;
1104 default:cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
1105 cachedsi.wProcessorLevel= 5;
1106 break;
1109 /* set the CPU type of the current processor */
1110 sprintf(buf,"CPU %ld",cachedsi.dwProcessorType);
1111 continue;
1113 if (!lstrncmpiA(line,"fdiv_bug",strlen("fdiv_bug"))) {
1114 if (!lstrncmpiA(value,"yes",3))
1115 PF[PF_FLOATING_POINT_PRECISION_ERRATA] = TRUE;
1117 continue;
1119 if (!lstrncmpiA(line,"fpu",strlen("fpu"))) {
1120 if (!lstrncmpiA(value,"no",2))
1121 PF[PF_FLOATING_POINT_EMULATED] = TRUE;
1123 continue;
1125 if (!lstrncmpiA(line,"processor",strlen("processor"))) {
1126 /* processor number counts up...*/
1127 unsigned int x;
1129 if (sscanf(value,"%d",&x))
1130 if (x+1>cachedsi.dwNumberOfProcessors)
1131 cachedsi.dwNumberOfProcessors=x+1;
1133 /* Create a new processor subkey on a multiprocessor
1134 * system
1136 sprintf(buf,"%d",x);
1138 if (!lstrncmpiA(line,"stepping",strlen("stepping"))) {
1139 int x;
1141 if (sscanf(value,"%d",&x))
1142 cachedsi.wProcessorRevision = x;
1145 ( (!lstrncmpiA(line,"flags",strlen("flags")))
1146 || (!lstrncmpiA(line,"features",strlen("features"))) )
1148 if (strstr(value,"cx8"))
1149 PF[PF_COMPARE_EXCHANGE_DOUBLE] = TRUE;
1150 if (strstr(value,"mmx"))
1151 PF[PF_MMX_INSTRUCTIONS_AVAILABLE] = TRUE;
1152 if (strstr(value,"tsc"))
1153 PF[PF_RDTSC_INSTRUCTION_AVAILABLE] = TRUE;
1154 if (strstr(value,"xmm") || strstr(value,"sse"))
1155 PF[PF_XMMI_INSTRUCTIONS_AVAILABLE] = TRUE;
1156 if (strstr(value,"sse2"))
1157 PF[PF_XMMI64_INSTRUCTIONS_AVAILABLE] = TRUE;
1158 if (strstr(value,"3dnow"))
1159 PF[PF_AMD3D_INSTRUCTIONS_AVAILABLE] = TRUE;
1162 fclose (f);
1164 #endif /* __linux__ */
1165 cache = 1;
1166 exit:
1167 memcpy(si,&cachedsi,sizeof(*si));
1168 DumpSystemInfo(si);
1171 // avoid undefined expGetSystemInfo
1172 static WIN_BOOL WINAPI expIsProcessorFeaturePresent(DWORD v)
1174 WIN_BOOL result = 0;
1175 if (!pf_set)
1177 SYSTEM_INFO si;
1178 expGetSystemInfo(&si);
1180 if(v<64) result=PF[v];
1181 dbgprintf("IsProcessorFeaturePresent(0x%x) => 0x%x\n", v, result);
1182 return result;
1185 static WIN_BOOL WINAPI expIsDebuggerPresent(void)
1187 return 0;
1190 static long WINAPI expGetVersion(void)
1192 dbgprintf("GetVersion() => 0xC0000004\n");
1193 return 0xC0000004;//Windows 95
1196 static HANDLE WINAPI expHeapCreate(long flags, long init_size, long max_size)
1198 // printf("HeapCreate:");
1199 HANDLE result;
1200 if(init_size==0)
1201 result=(HANDLE)my_mreq(0x110000, 0);
1202 else
1203 result=(HANDLE)my_mreq((init_size + 0xfff) & 0x7ffff000 , 0);
1204 dbgprintf("HeapCreate(flags 0x%x, initial size %d, maximum size %d) => 0x%x\n", flags, init_size, max_size, result);
1205 return result;
1208 // this is another dirty hack
1209 // VP31 is releasing one allocated Heap chunk twice
1210 // we will silently ignore this second call...
1211 static void* heapfreehack = 0;
1212 static int heapfreehackshown = 0;
1213 //void trapbug(void);
1214 static void* WINAPI expHeapAlloc(HANDLE heap, int flags, int size)
1216 void* z;
1218 Morgan's m3jpeg32.dll v. 2.0 encoder expects that request for
1219 HeapAlloc returns area larger than size argument :-/
1221 actually according to M$ Doc HeapCreate size should be rounded
1222 to page boundaries thus we should simulate this
1224 //if (size == 22276) trapbug();
1225 z=my_mreq((size + 0xfff) & 0x7ffff000, (flags & HEAP_ZERO_MEMORY));
1226 if(z==0)
1227 printf("HeapAlloc failure\n");
1228 dbgprintf("HeapAlloc(heap 0x%x, flags 0x%x, size %d) => 0x%x\n", heap, flags, size, z);
1229 heapfreehack = 0; // reset
1230 return z;
1232 static long WINAPI expHeapDestroy(void* heap)
1234 dbgprintf("HeapDestroy(heap 0x%x) => 1\n", heap);
1235 my_release(heap);
1236 return 1;
1239 static long WINAPI expHeapFree(HANDLE heap, DWORD dwFlags, LPVOID lpMem)
1241 dbgprintf("HeapFree(0x%x, 0x%x, pointer 0x%x) => 1\n", heap, dwFlags, lpMem);
1242 if (heapfreehack != lpMem && lpMem != (void*)0xffffffff
1243 && lpMem != (void*)0xbdbdbdbd)
1244 // 0xbdbdbdbd is for i263_drv.drv && libefence
1245 // it seems to be reading from relased memory
1246 // EF_PROTECT_FREE doens't show any probleme
1247 my_release(lpMem);
1248 else
1250 if (!heapfreehackshown++)
1251 printf("Info: HeapFree deallocating same memory twice! (%p)\n", lpMem);
1253 heapfreehack = lpMem;
1254 return 1;
1256 static long WINAPI expHeapSize(int heap, int flags, void* pointer)
1258 long result=my_size(pointer);
1259 dbgprintf("HeapSize(heap 0x%x, flags 0x%x, pointer 0x%x) => %d\n", heap, flags, pointer, result);
1260 return result;
1262 static void* WINAPI expHeapReAlloc(HANDLE heap,int flags,void *lpMem,int size)
1264 long orgsize = my_size(lpMem);
1265 dbgprintf("HeapReAlloc() Size %ld org %d\n",orgsize,size);
1266 return my_realloc(lpMem, size);
1268 static long WINAPI expGetProcessHeap(void)
1270 dbgprintf("GetProcessHeap() => 1\n");
1271 return 1;
1273 static void* WINAPI expVirtualAlloc(void* v1, long v2, long v3, long v4)
1275 void* z = VirtualAlloc(v1, v2, v3, v4);
1276 if(z==0)
1277 printf("VirtualAlloc failure\n");
1278 dbgprintf("VirtualAlloc(0x%x, %d, %d, %d) => 0x%x \n",v1,v2,v3,v4, z);
1279 return z;
1281 static int WINAPI expVirtualFree(void* v1, int v2, int v3)
1283 int result = VirtualFree(v1,v2,v3);
1284 dbgprintf("VirtualFree(0x%x, %d, %d) => %d\n",v1,v2,v3, result);
1285 return result;
1288 /* we're building a table of critical sections. cs_win pointer uses the DLL
1289 cs_unix is the real structure, we're using cs_win only to identifying cs_unix */
1290 struct critsecs_list_t
1292 CRITICAL_SECTION *cs_win;
1293 struct CRITSECT *cs_unix;
1296 /* 'NEWTYPE' is working with VIVO, 3ivX and QTX dll (no more segfaults) -- alex */
1297 #undef CRITSECS_NEWTYPE
1298 //#define CRITSECS_NEWTYPE 1
1300 #ifdef CRITSECS_NEWTYPE
1301 /* increased due to ucod needs more than 32 entries */
1302 /* and 64 should be enough for everything */
1303 #define CRITSECS_LIST_MAX 64
1304 static struct critsecs_list_t critsecs_list[CRITSECS_LIST_MAX];
1306 static int critsecs_get_pos(CRITICAL_SECTION *cs_win)
1308 int i;
1310 for (i=0; i < CRITSECS_LIST_MAX; i++)
1311 if (critsecs_list[i].cs_win == cs_win)
1312 return i;
1313 return -1;
1316 static int critsecs_get_unused(void)
1318 int i;
1320 for (i=0; i < CRITSECS_LIST_MAX; i++)
1321 if (critsecs_list[i].cs_win == NULL)
1322 return i;
1323 return -1;
1326 struct CRITSECT *critsecs_get_unix(CRITICAL_SECTION *cs_win)
1328 int i;
1330 for (i=0; i < CRITSECS_LIST_MAX; i++)
1331 if (critsecs_list[i].cs_win == cs_win && critsecs_list[i].cs_unix)
1332 return critsecs_list[i].cs_unix;
1333 return NULL;
1335 #endif
1337 static void WINAPI expInitializeCriticalSection(CRITICAL_SECTION* c)
1339 dbgprintf("InitializeCriticalSection(0x%x)\n", c);
1340 /* if(sizeof(pthread_mutex_t)>sizeof(CRITICAL_SECTION))
1342 printf(" ERROR:::: sizeof(pthread_mutex_t) is %d, expected <=%d!\n",
1343 sizeof(pthread_mutex_t), sizeof(CRITICAL_SECTION));
1344 return;
1346 /* pthread_mutex_init((pthread_mutex_t*)c, NULL); */
1347 #ifdef CRITSECS_NEWTYPE
1349 struct CRITSECT *cs;
1350 int i = critsecs_get_unused();
1352 if (i < 0)
1354 printf("InitializeCriticalSection(%p) - no more space in list\n", c);
1355 return;
1357 dbgprintf("got unused space at %d\n", i);
1358 cs = malloc(sizeof(struct CRITSECT));
1359 if (!cs)
1361 printf("InitializeCriticalSection(%p) - out of memory\n", c);
1362 return;
1364 pthread_mutex_init(&cs->mutex, NULL);
1365 pthread_cond_init(&cs->unlocked, NULL);
1366 cs->lock_count = 0;
1367 critsecs_list[i].cs_win = c;
1368 critsecs_list[i].cs_unix = cs;
1369 dbgprintf("InitializeCriticalSection -> itemno=%d, cs_win=%p, cs_unix=%p\n",
1370 i, c, cs);
1372 #else
1374 struct CRITSECT* cs = mreq_private(sizeof(struct CRITSECT) + sizeof(CRITICAL_SECTION),
1375 0, AREATYPE_CRITSECT);
1376 pthread_mutex_init(&cs->mutex, NULL);
1377 pthread_cond_init(&cs->unlocked, NULL);
1378 cs->lock_count = 0;
1379 cs->deadbeef = 0xdeadbeef;
1380 *(void**)c = cs;
1382 #endif
1383 return;
1386 static WIN_BOOL WINAPI expInitializeCriticalSectionAndSpinCount(CRITICAL_SECTION* c, DWORD spin)
1388 expInitializeCriticalSection(c);
1389 return 1;
1392 static void WINAPI expEnterCriticalSection(CRITICAL_SECTION* c)
1394 #ifdef CRITSECS_NEWTYPE
1395 struct CRITSECT* cs = critsecs_get_unix(c);
1396 #else
1397 struct CRITSECT* cs = (*(struct CRITSECT**)c);
1398 #endif
1399 dbgprintf("EnterCriticalSection(0x%x) %p\n",c, cs);
1400 if (!cs)
1402 dbgprintf("entered uninitialized critisec!\n");
1403 expInitializeCriticalSection(c);
1404 #ifdef CRITSECS_NEWTYPE
1405 cs=critsecs_get_unix(c);
1406 #else
1407 cs = (*(struct CRITSECT**)c);
1408 #endif
1409 dbgprintf("Win32 Warning: Accessed uninitialized Critical Section (%p)!\n", c);
1411 pthread_mutex_lock(&(cs->mutex));
1412 if (cs->lock_count > 0 && cs->id == pthread_self()) {
1413 cs->lock_count++;
1414 } else {
1415 while (cs->lock_count != 0) {
1416 pthread_cond_wait(&(cs->unlocked), &(cs->mutex));
1418 cs->lock_count = 1;
1419 cs->id = pthread_self();
1421 pthread_mutex_unlock(&(cs->mutex));
1422 return;
1424 static void WINAPI expLeaveCriticalSection(CRITICAL_SECTION* c)
1426 #ifdef CRITSECS_NEWTYPE
1427 struct CRITSECT* cs = critsecs_get_unix(c);
1428 #else
1429 struct CRITSECT* cs = (*(struct CRITSECT**)c);
1430 #endif
1431 // struct CRITSECT* cs=(struct CRITSECT*)c;
1432 dbgprintf("LeaveCriticalSection(0x%x) 0x%x\n",c, cs);
1433 if (!cs)
1435 dbgprintf("Win32 Warning: Leaving uninitialized Critical Section %p!!\n", c);
1436 return;
1438 pthread_mutex_lock(&(cs->mutex));
1439 if (cs->lock_count == 0) {
1440 dbgprintf("Win32 Warning: Unlocking unlocked Critical Section %p!!\n", c);
1441 } else {
1442 cs->lock_count--;
1444 if (cs->lock_count == 0) {
1445 pthread_cond_signal(&(cs->unlocked));
1447 pthread_mutex_unlock(&(cs->mutex));
1448 return;
1451 static void expfree(void* mem); /* forward declaration */
1453 static void WINAPI expDeleteCriticalSection(CRITICAL_SECTION *c)
1455 #ifdef CRITSECS_NEWTYPE
1456 struct CRITSECT* cs = critsecs_get_unix(c);
1457 #else
1458 struct CRITSECT* cs= (*(struct CRITSECT**)c);
1459 #endif
1460 // struct CRITSECT* cs=(struct CRITSECT*)c;
1461 dbgprintf("DeleteCriticalSection(0x%x)\n",c);
1463 if (!cs)
1465 dbgprintf("Win32 Warning: Deleting uninitialized Critical Section %p!!\n", c);
1466 return;
1469 pthread_mutex_lock(&(cs->mutex));
1470 if (cs->lock_count > 0)
1472 dbgprintf("Win32 Warning: Deleting locked Critical Section %p!!\n", c);
1474 pthread_mutex_unlock(&(cs->mutex));
1476 #ifndef GARBAGE
1477 pthread_mutex_destroy(&(cs->mutex));
1478 pthread_cond_destroy(&(cs->unlocked));
1479 // released by GarbageCollector in my_relase otherwise
1480 #endif
1481 my_release(cs);
1482 #ifdef CRITSECS_NEWTYPE
1484 int i = critsecs_get_pos(c);
1486 if (i < 0)
1488 printf("DeleteCriticalSection(%p) error (critsec not found)\n", c);
1489 return;
1492 critsecs_list[i].cs_win = NULL;
1493 expfree(critsecs_list[i].cs_unix);
1494 critsecs_list[i].cs_unix = NULL;
1495 dbgprintf("DeleteCriticalSection -> itemno=%d\n", i);
1497 #endif
1498 return;
1500 static int WINAPI expGetCurrentThreadId(void)
1502 dbgprintf("GetCurrentThreadId() => %d\n", pthread_self());
1503 return pthread_self();
1505 static int WINAPI expGetCurrentProcess(void)
1507 dbgprintf("GetCurrentProcess() => %d\n", getpid());
1508 return getpid();
1511 #ifdef CONFIG_QTX_CODECS
1512 // this version is required for Quicktime codecs (.qtx/.qts) to work.
1513 // (they assume some pointers at FS: segment)
1515 //static int tls_count;
1516 static int tls_use_map[64];
1517 static int WINAPI expTlsAlloc(void)
1519 int i;
1520 for(i=0; i<64; i++)
1521 if(tls_use_map[i]==0)
1523 tls_use_map[i]=1;
1524 dbgprintf("TlsAlloc() => %d\n",i);
1525 return i;
1527 dbgprintf("TlsAlloc() => -1 (ERROR)\n");
1528 return -1;
1531 //static int WINAPI expTlsSetValue(DWORD index, void* value)
1532 static int WINAPI expTlsSetValue(int index, void* value)
1534 dbgprintf("TlsSetValue(%d,0x%x) => 1\n",index,value);
1535 // if((index<0) || (index>64))
1536 if((index>=64))
1537 return 0;
1538 *(void**)((char*)fs_seg+0x88+4*index) = value;
1539 return 1;
1542 static void* WINAPI expTlsGetValue(DWORD index)
1544 dbgprintf("TlsGetValue(%d)\n",index);
1545 // if((index<0) || (index>64))
1546 if((index>=64)) return NULL;
1547 return *(void**)((char*)fs_seg+0x88+4*index);
1550 static int WINAPI expTlsFree(int idx)
1552 int index = (int) idx;
1553 dbgprintf("TlsFree(%d)\n",index);
1554 if((index<0) || (index>64))
1555 return 0;
1556 tls_use_map[index]=0;
1557 return 1;
1560 #else
1561 struct tls_s {
1562 void* value;
1563 int used;
1564 struct tls_s* prev;
1565 struct tls_s* next;
1568 static void* WINAPI expTlsAlloc(void)
1570 if (g_tls == NULL)
1572 g_tls=my_mreq(sizeof(tls_t), 0);
1573 g_tls->next=g_tls->prev=NULL;
1575 else
1577 g_tls->next=my_mreq(sizeof(tls_t), 0);
1578 g_tls->next->prev=g_tls;
1579 g_tls->next->next=NULL;
1580 g_tls=g_tls->next;
1582 dbgprintf("TlsAlloc() => 0x%x\n", g_tls);
1583 if (g_tls)
1584 g_tls->value=0; /* XXX For Divx.dll */
1585 return g_tls;
1588 static int WINAPI expTlsSetValue(void* idx, void* value)
1590 tls_t* index = (tls_t*) idx;
1591 int result;
1592 if(index==0)
1593 result=0;
1594 else
1596 index->value=value;
1597 result=1;
1599 dbgprintf("TlsSetValue(index 0x%x, value 0x%x) => %d \n", index, value, result );
1600 return result;
1602 static void* WINAPI expTlsGetValue(void* idx)
1604 tls_t* index = (tls_t*) idx;
1605 void* result;
1606 if(index==0)
1607 result=0;
1608 else
1609 result=index->value;
1610 dbgprintf("TlsGetValue(index 0x%x) => 0x%x\n", index, result);
1611 return result;
1613 static int WINAPI expTlsFree(void* idx)
1615 tls_t* index = (tls_t*) idx;
1616 int result;
1617 if(index==0)
1618 result=0;
1619 else
1621 if(index->next)
1622 index->next->prev=index->prev;
1623 if(index->prev)
1624 index->prev->next=index->next;
1625 if (g_tls == index)
1626 g_tls = index->prev;
1627 my_release((void*)index);
1628 result=1;
1630 dbgprintf("TlsFree(index 0x%x) => %d\n", index, result);
1631 return result;
1633 #endif
1635 static void* WINAPI expLocalAlloc(int flags, int size)
1637 void* z = my_mreq(size, (flags & GMEM_ZEROINIT));
1638 if (z == 0)
1639 printf("LocalAlloc() failed\n");
1640 dbgprintf("LocalAlloc(%d, flags 0x%x) => 0x%x\n", size, flags, z);
1641 return z;
1644 static void* WINAPI expLocalReAlloc(int handle,int size, int flags)
1646 void *newpointer;
1647 int oldsize;
1649 newpointer=NULL;
1650 if (flags & LMEM_MODIFY) {
1651 dbgprintf("LocalReAlloc MODIFY\n");
1652 return (void *)handle;
1654 oldsize = my_size((void *)handle);
1655 newpointer = my_realloc((void *)handle,size);
1656 dbgprintf("LocalReAlloc(%x %d(old %d), flags 0x%x) => 0x%x\n", handle,size,oldsize, flags,newpointer);
1658 return newpointer;
1661 static void* WINAPI expLocalLock(void* z)
1663 dbgprintf("LocalLock(0x%x) => 0x%x\n", z, z);
1664 return z;
1667 static void* WINAPI expGlobalAlloc(int flags, int size)
1669 void* z;
1670 dbgprintf("GlobalAlloc(%d, flags 0x%X)\n", size, flags);
1672 z=my_mreq(size, (flags & GMEM_ZEROINIT));
1673 //z=calloc(size, 1);
1674 //z=malloc(size);
1675 if(z==0)
1676 printf("GlobalAlloc() failed\n");
1677 dbgprintf("GlobalAlloc(%d, flags 0x%x) => 0x%x\n", size, flags, z);
1678 return z;
1680 static void* WINAPI expGlobalLock(void* z)
1682 dbgprintf("GlobalLock(0x%x) => 0x%x\n", z, z);
1683 return z;
1685 // pvmjpg20 - but doesn't work anyway
1686 static int WINAPI expGlobalSize(void* amem)
1688 int size = 100000;
1689 #ifdef GARBAGE
1690 alloc_header* header = last_alloc;
1691 alloc_header* mem = (alloc_header*) amem - 1;
1692 if (amem == 0)
1693 return 0;
1694 pthread_mutex_lock(&memmut);
1695 while (header)
1697 if (header->deadbeef != 0xdeadbeef)
1699 dbgprintf("FATAL found corrupted memory! %p 0x%lx (%d)\n", header, header->deadbeef, alccnt);
1700 break;
1703 if (header == mem)
1705 size = header->size;
1706 break;
1709 header = header->prev;
1711 pthread_mutex_unlock(&memmut);
1712 #endif
1714 dbgprintf("GlobalSize(0x%x)\n", amem);
1715 return size;
1718 static int WINAPI expLoadIconA( long hinstance, char *name )
1720 dbgprintf("LoadIconA( %ld, 0x%x ) => 1\n",hinstance,name);
1721 return 1;
1724 static int WINAPI expLoadStringA(long instance, long id, void* buf, long size)
1726 int result=LoadStringA(instance, id, buf, size);
1727 // if(buf)
1728 dbgprintf("LoadStringA(instance 0x%x, id 0x%x, buffer 0x%x, size %d) => %d ( %s )\n",
1729 instance, id, buf, size, result, buf);
1730 // else
1731 // dbgprintf("LoadStringA(instance 0x%x, id 0x%x, buffer 0x%x, size %d) => %d\n",
1732 // instance, id, buf, size, result);
1733 return result;
1736 static long WINAPI expMultiByteToWideChar(long v1, long v2, char* s1, long siz1, short* s2, int siz2)
1738 /* FIXME */
1739 int i;
1740 int result;
1741 if(s2==0)
1742 result=1;
1743 else
1745 if(siz1>siz2/2)siz1=siz2/2;
1746 for(i=1; i<=siz1; i++)
1748 *s2=*s1;
1749 if(!*s1)break;
1750 s2++;
1751 s1++;
1753 result=i;
1755 if(s1)
1756 dbgprintf("MultiByteToWideChar(codepage %d, flags 0x%x, string 0x%x='%s',"
1757 "size %d, dest buffer 0x%x, dest size %d) => %d\n",
1758 v1, v2, s1, s1, siz1, s2, siz2, result);
1759 else
1760 dbgprintf("MultiByteToWideChar(codepage %d, flags 0x%x, string NULL,"
1761 "size %d, dest buffer 0x%x, dest size %d) =>\n",
1762 v1, v2, siz1, s2, siz2, result);
1763 return result;
1765 static void wch_print(const short* str)
1767 dbgprintf(" src: ");
1768 while(*str)dbgprintf("%c", *str++);
1769 dbgprintf("\n");
1771 static long WINAPI expWideCharToMultiByte(long v1, long v2, short* s1, long siz1,
1772 char* s2, int siz2, char* c3, int* siz3)
1774 int result;
1775 dbgprintf("WideCharToMultiByte(codepage %d, flags 0x%x, src 0x%x, src size %d, "
1776 "dest 0x%x, dest size %d, defch 0x%x, used_defch 0x%x)", v1, v2, s1, siz1, s2, siz2, c3, siz3);
1777 result=WideCharToMultiByte(v1, v2, s1, siz1, s2, siz2, c3, siz3);
1778 dbgprintf("=> %d\n", result);
1779 //if(s1)wch_print(s1);
1780 if(s2)dbgprintf(" dest: %s\n", s2);
1781 return result;
1784 static long WINAPI expGetVersionExA(OSVERSIONINFOA* c)
1786 dbgprintf("GetVersionExA(0x%x) => 1\n", c);
1787 c->dwOSVersionInfoSize=sizeof(*c);
1788 c->dwMajorVersion=5;
1789 c->dwMinorVersion=1;
1790 c->dwBuildNumber=0x5010a28;
1791 c->dwPlatformId=VER_PLATFORM_WIN32_NT;
1792 strcpy(c->szCSDVersion, "Service Pack 2");
1793 dbgprintf(" Major version: 5\n Minor version: 1\n Build number: 0x5010a28\n"
1794 " Platform Id: VER_PLATFORM_WIN32_NT\n Version string: 'Service Pack 2'\n");
1795 return 1;
1798 static long WINAPI expGetVersionExW(OSVERSIONINFOW* c)
1800 char CSDVersion[128];
1801 dbgprintf("GetVersionExW(0x%x) => 1\n", c);
1802 c->dwOSVersionInfoSize=sizeof(*c);
1803 c->dwMajorVersion=5;
1804 c->dwMinorVersion=1;
1805 c->dwBuildNumber=0x5010a28;
1806 c->dwPlatformId=VER_PLATFORM_WIN32_NT;
1807 strcpy(CSDVersion, "Service Pack 2");
1808 MultiByteToWideChar(65001, 0x0, CSDVersion, -1, c->szCSDVersion, 128);
1809 dbgprintf(" Major version: 5\n Minor version: 1\n Build number: 0x5010a28\n"
1810 " Platform Id: VER_PLATFORM_WIN32_NT\n Version string: 'Service Pack 2'\n");
1811 return 1;
1814 static HANDLE WINAPI expCreateSemaphoreA(char* v1, long init_count,
1815 long max_count, char* name)
1817 pthread_mutex_t *pm;
1818 pthread_cond_t *pc;
1819 HANDLE ret;
1821 mutex_list* pp;
1822 printf("CreateSemaphoreA(%p = %s)\n", name, (name ? name : "<null>"));
1823 pp=mlist;
1824 while(pp)
1826 printf("%p => ", pp);
1827 pp=pp->prev;
1829 printf("0\n");
1831 pthread_mutex_lock(&mlist_lock);
1832 if(mlist!=NULL)
1834 mutex_list* pp=mlist;
1835 if(name!=NULL)
1838 if((strcmp(pp->name, name)==0) && (pp->type==1))
1840 dbgprintf("CreateSemaphoreA(0x%x, init_count %d, max_count %d, name 0x%x='%s') => 0x%x\n",
1841 v1, init_count, max_count, name, name, mlist);
1842 ret = (HANDLE)mlist;
1843 pthread_mutex_unlock(&mlist_lock);
1844 return ret;
1846 }while((pp=pp->prev) != NULL);
1848 pm=mreq_private(sizeof(pthread_mutex_t), 0, AREATYPE_MUTEX);
1849 pthread_mutex_init(pm, NULL);
1850 pc=mreq_private(sizeof(pthread_cond_t), 0, AREATYPE_COND);
1851 pthread_cond_init(pc, NULL);
1852 if(mlist==NULL)
1854 mlist=mreq_private(sizeof(mutex_list), 00, AREATYPE_EVENT);
1855 mlist->next=mlist->prev=NULL;
1857 else
1859 mlist->next=mreq_private(sizeof(mutex_list), 00, AREATYPE_EVENT);
1860 mlist->next->prev=mlist;
1861 mlist->next->next=NULL;
1862 mlist=mlist->next;
1863 // printf("new semaphore %p\n", mlist);
1865 mlist->type=1; /* Type Semaphore */
1866 mlist->pm=pm;
1867 mlist->pc=pc;
1868 mlist->state=0;
1869 mlist->reset=0;
1870 mlist->semaphore=init_count;
1871 if(name!=NULL)
1872 strncpy(mlist->name, name, 64);
1873 else
1874 mlist->name[0]=0;
1875 if(pm==NULL)
1876 dbgprintf("ERROR::: CreateSemaphoreA failure\n");
1877 if(name)
1878 dbgprintf("CreateSemaphoreA(0x%x, init_count %d, max_count %d, name 0x%x='%s') => 0x%x\n",
1879 v1, init_count, max_count, name, name, mlist);
1880 else
1881 dbgprintf("CreateSemaphoreA(0x%x, init_count %d, max_count %d, name 0) => 0x%x\n",
1882 v1, init_count, max_count, mlist);
1883 ret = (HANDLE)mlist;
1884 pthread_mutex_unlock(&mlist_lock);
1885 return ret;
1888 static HANDLE WINAPI expCreateSemaphoreW(char* v1, long init_count,
1889 long max_count, const WCHAR* name)
1891 char ascii_name[256];
1892 char *aname = NULL;
1893 if (name) {
1894 WideCharToMultiByte(65001, 0x0, name, -1, ascii_name, 256, NULL, NULL);
1895 aname = ascii_name;
1897 return expCreateSemaphoreA(v1, init_count, max_count, aname);
1900 static long WINAPI expReleaseSemaphore(long hsem, long increment, long* prev_count)
1902 // The state of a semaphore object is signaled when its count
1903 // is greater than zero and nonsignaled when its count is equal to zero
1904 // Each time a waiting thread is released because of the semaphore's signaled
1905 // state, the count of the semaphore is decreased by one.
1906 mutex_list *ml = (mutex_list *)hsem;
1908 pthread_mutex_lock(ml->pm);
1909 if (prev_count != 0) *prev_count = ml->semaphore;
1910 if (ml->semaphore == 0) pthread_cond_signal(ml->pc);
1911 ml->semaphore += increment;
1912 pthread_mutex_unlock(ml->pm);
1913 dbgprintf("ReleaseSemaphore(semaphore 0x%x, increment %d, prev_count 0x%x) => 1\n",
1914 hsem, increment, prev_count);
1915 return 1;
1918 static HANDLE WINAPI expCreateMutexA(void *pSecAttr,
1919 char bInitialOwner, const char *name)
1921 pthread_mutex_t *pm;
1922 pthread_cond_t *pc;
1923 HANDLE ret;
1924 pthread_mutex_lock(&mlist_lock);
1925 if(mlist!=NULL)
1927 mutex_list* pp=mlist;
1928 if(name!=NULL)
1931 if((strcmp(pp->name, name)==0) && (pp->type==2))
1933 dbgprintf("CreateMutexA(0x%x, %d, '%s') => 0x%x\n", pSecAttr, bInitialOwner, name, mlist);
1934 ret = (HANDLE)mlist;
1935 pthread_mutex_unlock(&mlist_lock);
1936 return ret;
1938 }while((pp=pp->prev) != NULL);
1940 pm=mreq_private(sizeof(pthread_mutex_t), 0, AREATYPE_MUTEX);
1941 pthread_mutex_init(pm, NULL);
1942 pc=mreq_private(sizeof(pthread_cond_t), 0, AREATYPE_COND);
1943 pthread_cond_init(pc, NULL);
1944 if(mlist==NULL)
1946 mlist=mreq_private(sizeof(mutex_list), 00, AREATYPE_EVENT);
1947 mlist->next=mlist->prev=NULL;
1949 else
1951 mlist->next=mreq_private(sizeof(mutex_list), 00, AREATYPE_EVENT);
1952 mlist->next->prev=mlist;
1953 mlist->next->next=NULL;
1954 mlist=mlist->next;
1956 mlist->type=2; /* Type Mutex */
1957 mlist->pm=pm;
1958 mlist->pc=pc;
1959 mlist->state=0;
1960 mlist->reset=0;
1961 mlist->semaphore=0;
1962 if (bInitialOwner) {
1963 mlist->owner = pthread_self();
1964 mlist->lock_count = 1;
1965 } else {
1966 mlist->owner = (pthread_t)0;
1967 mlist->lock_count = 0;
1969 if(name!=NULL)
1970 strncpy(mlist->name, name, 64);
1971 else
1972 mlist->name[0]=0;
1973 if(pm==NULL)
1974 dbgprintf("ERROR::: CreateMutexA failure\n");
1975 if(name)
1976 dbgprintf("CreateMutexA(0x%x, %d, '%s') => 0x%x\n",
1977 pSecAttr, bInitialOwner, name, mlist);
1978 else
1979 dbgprintf("CreateMutexA(0x%x, %d, NULL) => 0x%x\n",
1980 pSecAttr, bInitialOwner, mlist);
1981 ret = (HANDLE)mlist;
1982 pthread_mutex_unlock(&mlist_lock);
1983 return ret;
1986 static HANDLE WINAPI expCreateMutexW(void *pSecAttr, char bInitialOwner, const WCHAR *name)
1988 char ascii_name[256];
1989 char *aname = NULL;
1990 if (name) {
1991 WideCharToMultiByte(65001, 0x0, name, -1, ascii_name, 256, NULL, NULL);
1992 aname = ascii_name;
1994 return expCreateMutexA(pSecAttr, bInitialOwner, aname);
1997 static int WINAPI expReleaseMutex(HANDLE hMutex)
1999 mutex_list *ml = (mutex_list *)hMutex;
2001 pthread_mutex_lock(ml->pm);
2002 if (--ml->lock_count == 0) pthread_cond_signal(ml->pc);
2003 pthread_mutex_unlock(ml->pm);
2004 return 1;
2007 static DWORD WINAPI expSignalObjectAndWait(HANDLE hObjectToSignal,
2008 HANDLE hObjectToWaitOn,
2009 DWORD dwMilliseconds,
2010 WIN_BOOL bAlertable) {
2011 mutex_list* mlist = (mutex_list*)hObjectToSignal;
2013 switch (mlist->type) {
2014 case 0: // Event
2015 expSetEvent(mlist);
2016 break;
2017 case 1: // Semaphore
2018 expReleaseSemaphore((long)mlist, 1, NULL);
2019 break;
2020 case 2: // Mutex
2021 expReleaseMutex((long)mlist);
2022 break;
2023 default:
2024 dbgprintf("Signalling unknown object type %d!\n", hObjectToSignal);
2026 return (DWORD)expWaitForSingleObject((void*)hObjectToWaitOn, dwMilliseconds);
2029 static long WINAPI expRegOpenKeyExA(long key, const char* subkey, long reserved, long access, int* newkey)
2031 long result=RegOpenKeyExA(key, subkey, reserved, access, newkey);
2032 dbgprintf("RegOpenKeyExA(key 0x%x, subkey %s, reserved %d, access 0x%x, pnewkey 0x%x) => %d\n",
2033 key, subkey, reserved, access, newkey, result);
2034 if(newkey)dbgprintf(" New key: 0x%x\n", *newkey);
2035 return result;
2037 static long WINAPI expRegCloseKey(long key)
2039 long result=RegCloseKey(key);
2040 dbgprintf("RegCloseKey(0x%x) => %d\n", key, result);
2041 return result;
2043 static long WINAPI expRegQueryValueExA(long key, const char* value, int* reserved, int* type, int* data, int* count)
2045 long result=RegQueryValueExA(key, value, reserved, type, data, count);
2046 dbgprintf("RegQueryValueExA(key 0x%x, value %s, reserved 0x%x, data 0x%x, count 0x%x)"
2047 " => 0x%x\n", key, value, reserved, data, count, result);
2048 if(data && count)dbgprintf(" read %d bytes: '%s'\n", *count, data);
2049 return result;
2052 //from wine source dlls/advapi32/registry.c
2053 static long WINAPI expRegCreateKeyA(long hkey, const char* name, int *retkey)
2055 dbgprintf("RegCreateKeyA(key 0x%x, name 0x%x='%s',newkey=0x%x)\n",hkey,name,retkey);
2056 return RegCreateKeyExA( hkey, name, 0, NULL,REG_OPTION_NON_VOLATILE,
2057 KEY_ALL_ACCESS , NULL, retkey, NULL );
2060 static long WINAPI expRegCreateKeyExA(long key, const char* name, long reserved,
2061 void* classs, long options, long security,
2062 void* sec_attr, int* newkey, int* status)
2064 long result=RegCreateKeyExA(key, name, reserved, classs, options, security, sec_attr, newkey, status);
2065 dbgprintf("RegCreateKeyExA(key 0x%x, name 0x%x='%s', reserved=0x%x,"
2066 " 0x%x, 0x%x, 0x%x, newkey=0x%x, status=0x%x) => %d\n",
2067 key, name, name, reserved, classs, options, security, sec_attr, newkey, status, result);
2068 if(!result && newkey) dbgprintf(" New key: 0x%x\n", *newkey);
2069 if(!result && status) dbgprintf(" New key status: 0x%x\n", *status);
2070 return result;
2072 static long WINAPI expRegSetValueExA(long key, const char* name, long v1, long v2, void* data, long size)
2074 long result=RegSetValueExA(key, name, v1, v2, data, size);
2075 dbgprintf("RegSetValueExA(key 0x%x, name '%s', 0x%x, 0x%x, data 0x%x -> 0x%x '%s', size=%d) => %d",
2076 key, name, v1, v2, data, *(int*)data, data, size, result);
2077 return result;
2080 static long WINAPI expRegOpenKeyA (long hKey, LPCSTR lpSubKey, int* phkResult)
2082 long result=RegOpenKeyExA(hKey, lpSubKey, 0, 0, phkResult);
2083 dbgprintf("RegOpenKeyExA(key 0x%x, subkey '%s', 0x%x) => %d\n",
2084 hKey, lpSubKey, phkResult, result);
2085 if(!result && phkResult) dbgprintf(" New key: 0x%x\n", *phkResult);
2086 return result;
2089 static DWORD WINAPI expRegEnumValueA(HKEY hkey, DWORD index, LPSTR value, LPDWORD val_count,
2090 LPDWORD reserved, LPDWORD type, LPBYTE data, LPDWORD count)
2092 return RegEnumValueA(hkey, index, value, val_count,
2093 reserved, type, data, count);
2096 static DWORD WINAPI expRegEnumKeyExA(HKEY hKey, DWORD dwIndex, LPSTR lpName, LPDWORD lpcbName,
2097 LPDWORD lpReserved, LPSTR lpClass, LPDWORD lpcbClass,
2098 LPFILETIME lpftLastWriteTime)
2100 return RegEnumKeyExA(hKey, dwIndex, lpName, lpcbName, lpReserved, lpClass,
2101 lpcbClass, lpftLastWriteTime);
2104 static long WINAPI expQueryPerformanceCounter(long long* z)
2106 longcount(z);
2107 dbgprintf("QueryPerformanceCounter(0x%x) => 1 ( %Ld )\n", z, *z);
2108 return 1;
2112 * dummy function RegQueryInfoKeyA(), required by vss codecs
2114 static DWORD WINAPI expRegQueryInfoKeyA( HKEY hkey, LPSTR class, LPDWORD class_len, LPDWORD reserved,
2115 LPDWORD subkeys, LPDWORD max_subkey, LPDWORD max_class,
2116 LPDWORD values, LPDWORD max_value, LPDWORD max_data,
2117 LPDWORD security, FILETIME *modif )
2119 return ERROR_SUCCESS;
2123 * return CPU clock (in kHz), using linux's /proc filesystem (/proc/cpuinfo)
2125 static double linux_cpuinfo_freq(void)
2127 double freq=-1;
2128 FILE *f;
2129 char line[200];
2130 char *s,*value;
2132 f = fopen ("/proc/cpuinfo", "r");
2133 if (f != NULL) {
2134 while (fgets(line,sizeof(line),f)!=NULL) {
2135 /* NOTE: the ':' is the only character we can rely on */
2136 if (!(value = strchr(line,':')))
2137 continue;
2138 /* terminate the valuename */
2139 *value++ = '\0';
2140 /* skip any leading spaces */
2141 while (*value==' ') value++;
2142 if ((s=strchr(value,'\n')))
2143 *s='\0';
2145 if (!strncasecmp(line, "cpu MHz",strlen("cpu MHz"))
2146 && sscanf(value, "%lf", &freq) == 1) {
2147 freq*=1000;
2148 break;
2151 fclose(f);
2153 return freq;
2157 static double solaris_kstat_freq(void)
2159 #if defined(HAVE_LIBKSTAT) && defined(KSTAT_DATA_INT32)
2161 * try to extract the CPU speed from the solaris kernel's kstat data
2163 kstat_ctl_t *kc;
2164 kstat_t *ksp;
2165 kstat_named_t *kdata;
2166 int mhz = 0;
2168 kc = kstat_open();
2169 if (kc != NULL)
2171 ksp = kstat_lookup(kc, "cpu_info", 0, "cpu_info0");
2173 /* kstat found and name/value pairs? */
2174 if (ksp != NULL && ksp->ks_type == KSTAT_TYPE_NAMED)
2176 /* read the kstat data from the kernel */
2177 if (kstat_read(kc, ksp, NULL) != -1)
2180 * lookup desired "clock_MHz" entry, check the expected
2181 * data type
2183 kdata = (kstat_named_t *)kstat_data_lookup(ksp, "clock_MHz");
2184 if (kdata != NULL && kdata->data_type == KSTAT_DATA_INT32)
2185 mhz = kdata->value.i32;
2188 kstat_close(kc);
2191 if (mhz > 0)
2192 return mhz * 1000.;
2193 #endif /* HAVE_LIBKSTAT */
2194 return -1; // kstat stuff is not available, CPU freq is unknown
2198 * Measure CPU freq using the pentium's time stamp counter register (TSC)
2200 static double tsc_freq(void)
2202 static double ofreq=0.0;
2203 int i;
2204 int x,y;
2205 i=time(NULL);
2206 if (ofreq != 0.0) return ofreq;
2207 while(i==time(NULL));
2208 x=localcount();
2209 i++;
2210 while(i==time(NULL));
2211 y=localcount();
2212 ofreq = (double)(y-x)/1000.;
2213 return ofreq;
2216 static double CPU_Freq(void)
2218 double freq;
2220 if ((freq = linux_cpuinfo_freq()) > 0)
2221 return freq;
2223 if ((freq = solaris_kstat_freq()) > 0)
2224 return freq;
2226 return tsc_freq();
2229 static long WINAPI expQueryPerformanceFrequency(long long* z)
2231 *z=(long long)CPU_Freq();
2232 dbgprintf("QueryPerformanceFrequency(0x%x) => 1 ( %Ld )\n", z, *z);
2233 return 1;
2235 static long WINAPI exptimeGetTime(void)
2237 struct timeval t;
2238 long result;
2239 gettimeofday(&t, 0);
2240 result=1000*t.tv_sec+t.tv_usec/1000;
2241 dbgprintf("timeGetTime() => %d\n", result);
2242 return result;
2244 static void* WINAPI expLocalHandle(void* v)
2246 dbgprintf("LocalHandle(0x%x) => 0x%x\n", v, v);
2247 return v;
2250 static void* WINAPI expGlobalHandle(void* v)
2252 dbgprintf("GlobalHandle(0x%x) => 0x%x\n", v, v);
2253 return v;
2255 static int WINAPI expGlobalUnlock(void* v)
2257 dbgprintf("GlobalUnlock(0x%x) => 1\n", v);
2258 return 1;
2260 static void* WINAPI expGlobalFree(void* v)
2262 dbgprintf("GlobalFree(0x%x) => 0\n", v);
2263 my_release(v);
2264 //free(v);
2265 return 0;
2268 static void* WINAPI expGlobalReAlloc(void* v, int size, int flags)
2270 void* result=my_realloc(v, size);
2271 //void* result=realloc(v, size);
2272 dbgprintf("GlobalReAlloc(0x%x, size %d, flags 0x%x) => 0x%x\n", v,size,flags,result);
2273 return result;
2276 static int WINAPI expLocalUnlock(void* v)
2278 dbgprintf("LocalUnlock(0x%x) => 1\n", v);
2279 return 1;
2282 static void* WINAPI expLocalFree(void* v)
2284 dbgprintf("LocalFree(0x%x) => 0\n", v);
2285 my_release(v);
2286 return 0;
2288 static HRSRC WINAPI expFindResourceA(HMODULE module, char* name, char* type)
2290 HRSRC result;
2292 result=FindResourceA(module, name, type);
2293 dbgprintf("FindResourceA(module 0x%x, name 0x%x(%s), type 0x%x(%s)) => 0x%x\n",
2294 module, name, HIWORD(name) ? name : "UNICODE", type, HIWORD(type) ? type : "UNICODE", result);
2295 return result;
2298 static HGLOBAL WINAPI expLoadResource(HMODULE module, HRSRC res)
2300 HGLOBAL result=LoadResource(module, res);
2301 dbgprintf("LoadResource(module 0x%x, resource 0x%x) => 0x%x\n", module, res, result);
2302 return result;
2304 static void* WINAPI expLockResource(long res)
2306 void* result=LockResource(res);
2307 dbgprintf("LockResource(0x%x) => 0x%x\n", res, result);
2308 return result;
2310 static int WINAPI expFreeResource(long res)
2312 int result=FreeResource(res);
2313 dbgprintf("FreeResource(0x%x) => %d\n", res, result);
2314 return result;
2316 //bool fun(HANDLE)
2317 //!0 on success
2318 static int WINAPI expCloseHandle(long v1)
2320 dbgprintf("CloseHandle(0x%x) => 1\n", v1);
2321 /* do not close stdin,stdout and stderr */
2322 if (v1 > 2)
2323 if (!close(v1))
2324 return 0;
2325 return 1;
2328 static const char* WINAPI expGetCommandLineA(void)
2330 dbgprintf("GetCommandLineA() => \"c:\\aviplay.exe\"\n");
2331 return "c:\\aviplay.exe";
2333 static short envs[]={'p', 'a', 't', 'h', ' ', 'c', ':', '\\', 0, 0};
2334 static LPWSTR WINAPI expGetEnvironmentStringsW(void)
2336 dbgprintf("GetEnvironmentStringsW() => 0\n", envs);
2337 return 0;
2339 static void * WINAPI expRtlZeroMemory(void *p, size_t len)
2341 void* result=memset(p,0,len);
2342 dbgprintf("RtlZeroMemory(0x%x, len %d) => 0x%x\n",p,len,result);
2343 return result;
2345 static void * WINAPI expRtlMoveMemory(void *dst, void *src, size_t len)
2347 void* result=memmove(dst,src,len);
2348 dbgprintf("RtlMoveMemory (dest 0x%x, src 0x%x, len %d) => 0x%x\n",dst,src,len,result);
2349 return result;
2352 static void * WINAPI expRtlFillMemory(void *p, int ch, size_t len)
2354 void* result=memset(p,ch,len);
2355 dbgprintf("RtlFillMemory(0x%x, char 0x%x, len %d) => 0x%x\n",p,ch,len,result);
2356 return result;
2358 static int WINAPI expFreeEnvironmentStringsW(short* strings)
2360 dbgprintf("FreeEnvironmentStringsW(0x%x) => 1\n", strings);
2361 return 1;
2363 static int WINAPI expFreeEnvironmentStringsA(char* strings)
2365 dbgprintf("FreeEnvironmentStringsA(0x%x) => 1\n", strings);
2366 return 1;
2369 static const char ch_envs[]=
2370 "__MSVCRT_HEAP_SELECT=__GLOBAL_HEAP_SELECTED,1\r\n"
2371 "PATH=C:\\;C:\\windows\\;C:\\windows\\system\r\n";
2372 static LPCSTR WINAPI expGetEnvironmentStrings(void)
2374 dbgprintf("GetEnvironmentStrings() => 0x%x\n", ch_envs);
2375 return (LPCSTR)ch_envs;
2376 // dbgprintf("GetEnvironmentStrings() => 0\n");
2377 // return 0;
2380 static int WINAPI expGetStartupInfoA(STARTUPINFOA *s)
2382 dbgprintf("GetStartupInfoA(0x%x) => 1\n");
2383 memset(s, 0, sizeof(*s));
2384 s->cb=sizeof(*s);
2385 // s->lpReserved="Reserved";
2386 // s->lpDesktop="Desktop";
2387 // s->lpTitle="Title";
2388 // s->dwX=s->dwY=0;
2389 // s->dwXSize=s->dwYSize=200;
2390 s->dwFlags=s->wShowWindow=1;
2391 // s->hStdInput=s->hStdOutput=s->hStdError=0x1234;
2392 dbgprintf(" cb=%d\n", s->cb);
2393 dbgprintf(" lpReserved='%s'\n", s->lpReserved);
2394 dbgprintf(" lpDesktop='%s'\n", s->lpDesktop);
2395 dbgprintf(" lpTitle='%s'\n", s->lpTitle);
2396 dbgprintf(" dwX=%d dwY=%d dwXSize=%d dwYSize=%d\n",
2397 s->dwX, s->dwY, s->dwXSize, s->dwYSize);
2398 dbgprintf(" dwXCountChars=%d dwYCountChars=%d dwFillAttribute=%d\n",
2399 s->dwXCountChars, s->dwYCountChars, s->dwFillAttribute);
2400 dbgprintf(" dwFlags=0x%x wShowWindow=0x%x cbReserved2=0x%x\n",
2401 s->dwFlags, s->wShowWindow, s->cbReserved2);
2402 dbgprintf(" lpReserved2=0x%x hStdInput=0x%x hStdOutput=0x%x hStdError=0x%x\n",
2403 s->lpReserved2, s->hStdInput, s->hStdOutput, s->hStdError);
2404 return 1;
2407 static int WINAPI expGetStdHandle(int z)
2409 dbgprintf("GetStdHandle(0x%x) => 0x%x\n", z+0x1234);
2410 return z+0x1234;
2413 #ifdef CONFIG_QTX_CODECS
2414 #define FILE_HANDLE_quicktimeqts ((HANDLE)0x444)
2415 #define FILE_HANDLE_quicktimeqtx ((HANDLE)0x445)
2416 #endif
2418 static int WINAPI expGetFileType(int handle)
2420 dbgprintf("GetFileType(0x%x) => 0x3 = pipe\n", handle);
2421 return 0x3;
2423 #ifdef CONFIG_QTX_CODECS
2424 static int WINAPI expGetFileAttributesA(char *filename)
2426 dbgprintf("GetFileAttributesA(%s) => FILE_ATTR_NORMAL\n", filename);
2427 if (strstr(filename, "QuickTime.qts"))
2428 return FILE_ATTRIBUTE_SYSTEM;
2429 return FILE_ATTRIBUTE_NORMAL;
2431 #endif
2432 static int WINAPI expSetHandleCount(int count)
2434 dbgprintf("SetHandleCount(0x%x) => 1\n", count);
2435 return 1;
2437 static int WINAPI expGetACP(void)
2439 dbgprintf("GetACP() => 0\n");
2440 return 0;
2442 static int WINAPI expGetModuleFileNameA(int module, char* s, int len)
2444 WINE_MODREF *mr;
2445 int result;
2446 //printf("File name of module %X (%s) requested\n", module, s);
2448 if (module == 0 && len >= 12)
2450 /* return caller program name */
2451 strcpy(s, "aviplay.dll");
2452 result=1;
2454 else if(s==0)
2455 result=0;
2456 else
2457 if(len<35)
2458 result=0;
2459 else
2461 result=1;
2462 strcpy(s, "c:\\windows\\system\\");
2463 mr=MODULE32_LookupHMODULE(module);
2464 if(mr==0)//oops
2465 strcat(s, "aviplay.dll");
2466 else
2467 if(strrchr(mr->filename, '/')==NULL)
2468 strcat(s, mr->filename);
2469 else
2470 strcat(s, strrchr(mr->filename, '/')+1);
2472 if(!s)
2473 dbgprintf("GetModuleFileNameA(0x%x, 0x%x, %d) => %d\n",
2474 module, s, len, result);
2475 else
2476 dbgprintf("GetModuleFileNameA(0x%x, 0x%x, %d) => %d ( '%s' )\n",
2477 module, s, len, result, s);
2478 return result;
2481 static int WINAPI expGetModuleBaseNameA(int process, int module, char* s, int len)
2483 int result = 0;
2485 if (s && len) {
2486 av_strlcpy(s, "aviplay.dll", len);
2487 result = strlen(s);
2490 dbgprintf("GetModuleBaseNameA(0x%x, 0x%x, 0x%x, %d) => %d\n",
2491 process, module, s, len, result);
2493 return result;
2496 static int WINAPI expSetUnhandledExceptionFilter(void* filter)
2498 dbgprintf("SetUnhandledExceptionFilter(0x%x) => 1\n", filter);
2499 return 1;//unsupported and probably won't ever be supported
2502 static int WINAPI expLoadLibraryA(char* name)
2504 int result = 0;
2505 char* lastbc;
2506 if (!name)
2507 return -1;
2508 // we skip to the last backslash
2509 // this is effectively eliminating weird characters in
2510 // the text output windows
2512 lastbc = strrchr(name, '\\');
2513 if (lastbc)
2515 int i;
2516 lastbc++;
2517 for (i = 0; 1 ;i++)
2519 name[i] = *lastbc++;
2520 if (!name[i])
2521 break;
2524 if(strncmp(name, "c:\\windows\\", 11)==0) name += 11;
2525 if(strncmp(name, ".\\", 2)==0) name += 2;
2527 dbgprintf("Entering LoadLibraryA(%s)\n", name);
2529 // PIMJ and VIVO audio are loading kernel32.dll
2530 if (strcasecmp(name, "kernel32.dll") == 0 || strcasecmp(name, "kernel32") == 0)
2531 return MODULE_HANDLE_kernel32;
2532 // return ERROR_SUCCESS; /* yeah, we have also the kernel32 calls */
2533 /* exported -> do not return failed! */
2535 if (strcasecmp(name, "user32.dll") == 0 || strcasecmp(name, "user32") == 0)
2536 // return MODULE_HANDLE_kernel32;
2537 return MODULE_HANDLE_user32;
2539 #ifdef CONFIG_QTX_CODECS
2540 if (strcasecmp(name, "wininet.dll") == 0 || strcasecmp(name, "wininet") == 0)
2541 return MODULE_HANDLE_wininet;
2542 if (strcasecmp(name, "ddraw.dll") == 0 || strcasecmp(name, "ddraw") == 0)
2543 return MODULE_HANDLE_ddraw;
2544 if (strcasecmp(name, "advapi32.dll") == 0 || strcasecmp(name, "advapi32") == 0)
2545 return MODULE_HANDLE_advapi32;
2546 #endif
2548 if (strcasecmp(name, "comdlg32.dll") == 0 || strcasecmp(name, "comdlg32") == 0)
2549 return MODULE_HANDLE_comdlg32;
2550 if (strcasecmp(name, "msvcrt.dll") == 0 || strcasecmp(name, "msvcrt") == 0)
2551 return MODULE_HANDLE_msvcrt;
2552 if (strcasecmp(name, "ole32.dll") == 0 || strcasecmp(name, "ole32") == 0)
2553 return MODULE_HANDLE_ole32;
2554 if (strcasecmp(name, "winmm.dll") == 0 || strcasecmp(name, "winmm") == 0)
2555 return MODULE_HANDLE_winmm;
2556 if (strcasecmp(name, "psapi.dll") == 0 || strcasecmp(name, "psapi") == 0)
2557 return MODULE_HANDLE_psapi;
2559 result=LoadLibraryA(name);
2560 dbgprintf("Returned LoadLibraryA(0x%x='%s'), codec_path=%s => 0x%x\n",
2561 name, name, codec_path, result);
2563 return result;
2566 static int WINAPI expFreeLibrary(int module)
2568 #ifdef CONFIG_QTX_CODECS
2569 int result=0; /* FIXME:XXX: qtx svq3 frees up qt.qts */
2570 #else
2571 int result=FreeLibrary(module);
2572 #endif
2573 dbgprintf("FreeLibrary(0x%x) => %d\n", module, result);
2574 return result;
2577 static void* WINAPI expGetProcAddress(HMODULE mod, char* name)
2579 void* result;
2580 switch(mod){
2581 case MODULE_HANDLE_kernel32:
2582 result=LookupExternalByName("kernel32.dll", name); break;
2583 case MODULE_HANDLE_user32:
2584 result=LookupExternalByName("user32.dll", name); break;
2585 #ifdef CONFIG_QTX_CODECS
2586 case MODULE_HANDLE_wininet:
2587 result=LookupExternalByName("wininet.dll", name); break;
2588 case MODULE_HANDLE_ddraw:
2589 result=LookupExternalByName("ddraw.dll", name); break;
2590 case MODULE_HANDLE_advapi32:
2591 result=LookupExternalByName("advapi32.dll", name); break;
2592 #endif
2593 case MODULE_HANDLE_comdlg32:
2594 result=LookupExternalByName("comdlg32.dll", name); break;
2595 case MODULE_HANDLE_msvcrt:
2596 result=LookupExternalByName("msvcrt.dll", name); break;
2597 case MODULE_HANDLE_ole32:
2598 result=LookupExternalByName("ole32.dll", name); break;
2599 case MODULE_HANDLE_winmm:
2600 result=LookupExternalByName("winmm.dll", name); break;
2601 case MODULE_HANDLE_psapi:
2602 result=LookupExternalByName("psapi.dll", name); break;
2603 default:
2604 result=GetProcAddress(mod, name);
2606 if((unsigned int)name > 0xffff)
2607 dbgprintf("GetProcAddress(0x%x, '%s') => 0x%x\n", mod, name, result);
2608 else
2609 dbgprintf("GetProcAddress(0x%x, '%d') => 0x%x\n", mod, (int)name, result);
2610 return result;
2613 static long WINAPI expCreateFileMappingA(int hFile, void* lpAttr,
2614 long flProtect, long dwMaxHigh,
2615 long dwMaxLow, const char* name)
2617 long result=CreateFileMappingA(hFile, lpAttr, flProtect, dwMaxHigh, dwMaxLow, name);
2618 if(!name)
2619 dbgprintf("CreateFileMappingA(file 0x%x, lpAttr 0x%x,"
2620 "flProtect 0x%x, dwMaxHigh 0x%x, dwMaxLow 0x%x, name 0) => %d\n",
2621 hFile, lpAttr, flProtect, dwMaxHigh, dwMaxLow, result);
2622 else
2623 dbgprintf("CreateFileMappingA(file 0x%x, lpAttr 0x%x,"
2624 "flProtect 0x%x, dwMaxHigh 0x%x, dwMaxLow 0x%x, name 0x%x='%s') => %d\n",
2625 hFile, lpAttr, flProtect, dwMaxHigh, dwMaxLow, name, name, result);
2626 return result;
2629 static long WINAPI expOpenFileMappingA(long hFile, long hz, const char* name)
2631 long result=OpenFileMappingA(hFile, hz, name);
2632 if(!name)
2633 dbgprintf("OpenFileMappingA(0x%x, 0x%x, 0) => %d\n",
2634 hFile, hz, result);
2635 else
2636 dbgprintf("OpenFileMappingA(0x%x, 0x%x, 0x%x='%s') => %d\n",
2637 hFile, hz, name, name, result);
2638 return result;
2641 static void* WINAPI expMapViewOfFile(HANDLE file, DWORD mode, DWORD offHigh,
2642 DWORD offLow, DWORD size)
2644 dbgprintf("MapViewOfFile(0x%x, 0x%x, 0x%x, 0x%x, size %d) => 0x%x\n",
2645 file,mode,offHigh,offLow,size,(char*)file+offLow);
2646 return (char*)file+offLow;
2649 static void* WINAPI expUnmapViewOfFile(void* view)
2651 dbgprintf("UnmapViewOfFile(0x%x) => 0\n", view);
2652 return 0;
2655 static void* WINAPI expSleep(int time)
2657 #if HAVE_NANOSLEEP
2658 /* solaris doesn't have thread safe usleep */
2659 struct timespec tsp;
2660 tsp.tv_sec = time / 1000000;
2661 tsp.tv_nsec = (time % 1000000) * 1000;
2662 nanosleep(&tsp, NULL);
2663 #else
2664 usleep(time);
2665 #endif
2666 dbgprintf("Sleep(%d) => 0\n", time);
2667 return 0;
2670 // why does IV32 codec want to call this? I don't know ...
2671 static int WINAPI expCreateCompatibleDC(int hdc)
2673 int dc = 0;//0x81;
2674 //dbgprintf("CreateCompatibleDC(%d) => 0x81\n", hdc);
2675 dbgprintf("CreateCompatibleDC(%d) => %d\n", hdc, dc);
2676 return dc;
2679 static int WINAPI expGetDeviceCaps(int hdc, int unk)
2681 dbgprintf("GetDeviceCaps(0x%x, %d) => 0\n", hdc, unk);
2682 #ifdef CONFIG_QTX_CODECS
2683 #define BITSPIXEL 12
2684 #define PLANES 14
2685 if (unk == BITSPIXEL)
2686 return 24;
2687 if (unk == PLANES)
2688 return 1;
2689 #endif
2690 return 1;
2693 static WIN_BOOL WINAPI expDeleteDC(int hdc)
2695 dbgprintf("DeleteDC(0x%x) => 0\n", hdc);
2696 if (hdc == 0x81)
2697 return 1;
2698 return 0;
2701 static WIN_BOOL WINAPI expDeleteObject(int hdc)
2703 dbgprintf("DeleteObject(0x%x) => 1\n", hdc);
2704 /* FIXME - implement code here */
2705 return 1;
2708 /* btvvc32.drv wants this one */
2709 static void* WINAPI expGetWindowDC(int hdc)
2711 dbgprintf("GetWindowDC(%d) => 0x0\n", hdc);
2712 return 0;
2715 #ifdef CONFIG_QTX_CODECS
2716 static int WINAPI expGetWindowRect(HWND win, RECT *r)
2718 dbgprintf("GetWindowRect(0x%x, 0x%x) => 1\n", win, r);
2719 /* (win == 0) => desktop */
2720 r->right = PSEUDO_SCREEN_WIDTH;
2721 r->left = 0;
2722 r->bottom = PSEUDO_SCREEN_HEIGHT;
2723 r->top = 0;
2724 return 1;
2727 static int WINAPI expMonitorFromWindow(HWND win, int flags)
2729 dbgprintf("MonitorFromWindow(0x%x, 0x%x) => 0\n", win, flags);
2730 return 0;
2733 static int WINAPI expMonitorFromRect(RECT *r, int flags)
2735 dbgprintf("MonitorFromRect(0x%x, 0x%x) => 0\n", r, flags);
2736 return 0;
2739 static int WINAPI expMonitorFromPoint(void *p, int flags)
2741 dbgprintf("MonitorFromPoint(0x%x, 0x%x) => 0\n", p, flags);
2742 return 0;
2745 static int WINAPI expEnumDisplayMonitors(void *dc, RECT *r,
2746 int WINAPI (*callback_proc)(HMONITOR, HDC, LPRECT, LPARAM), void *callback_param)
2748 dbgprintf("EnumDisplayMonitors(0x%x, 0x%x, 0x%x, 0x%x) => ?\n",
2749 dc, r, callback_proc, callback_param);
2750 return callback_proc(0, (HDC)dc, r, (LPARAM)callback_param);
2753 #if 0
2754 typedef struct tagMONITORINFO {
2755 DWORD cbSize;
2756 RECT rcMonitor;
2757 RECT rcWork;
2758 DWORD dwFlags;
2759 } MONITORINFO, *LPMONITORINFO;
2760 #endif
2762 #define CCHDEVICENAME 8
2763 typedef struct tagMONITORINFOEX {
2764 DWORD cbSize;
2765 RECT rcMonitor;
2766 RECT rcWork;
2767 DWORD dwFlags;
2768 TCHAR szDevice[CCHDEVICENAME];
2769 } MONITORINFOEX, *LPMONITORINFOEX;
2771 static int WINAPI expGetMonitorInfoA(void *mon, LPMONITORINFO lpmi)
2773 dbgprintf("GetMonitorInfoA(0x%x, 0x%x) => 1\n", mon, lpmi);
2775 lpmi->rcMonitor.right = lpmi->rcWork.right = PSEUDO_SCREEN_WIDTH;
2776 lpmi->rcMonitor.left = lpmi->rcWork.left = 0;
2777 lpmi->rcMonitor.bottom = lpmi->rcWork.bottom = PSEUDO_SCREEN_HEIGHT;
2778 lpmi->rcMonitor.top = lpmi->rcWork.top = 0;
2780 lpmi->dwFlags = 1; /* primary monitor */
2782 if (lpmi->cbSize == sizeof(MONITORINFOEX))
2784 LPMONITORINFOEX lpmiex = (LPMONITORINFOEX)lpmi;
2785 dbgprintf("MONITORINFOEX!\n");
2786 strncpy(lpmiex->szDevice, "Monitor1", CCHDEVICENAME);
2789 return 1;
2792 static int WINAPI expEnumDisplayDevicesA(const char *device, int devnum,
2793 void *dispdev, int flags)
2795 dbgprintf("EnumDisplayDevicesA(0x%x = %s, %d, 0x%x, %x) => 1\n",
2796 device, device, devnum, dispdev, flags);
2797 return 1;
2800 static int WINAPI expIsWindowVisible(HWND win)
2802 dbgprintf("IsWindowVisible(0x%x) => 1\n", win);
2803 return 1;
2806 static HWND WINAPI expGetActiveWindow(void)
2808 dbgprintf("GetActiveWindow() => 0\n");
2809 return (HWND)0;
2812 static int WINAPI expGetClassNameA(HWND win, LPTSTR classname, int maxcount)
2814 strncat(classname, "QuickTime", maxcount);
2815 dbgprintf("GetClassNameA(0x%x, 0x%x, %d) => %d\n",
2816 win, classname, maxcount, strlen(classname));
2817 return strlen(classname);
2820 #define LPWNDCLASS void *
2821 static int WINAPI expGetClassInfoA(HINSTANCE inst, LPCSTR classname, LPWNDCLASS wndclass)
2823 dbgprintf("GetClassInfoA(0x%x, 0x%x = %s, 0x%x) => 1\n", inst,
2824 classname, classname, wndclass);
2825 return 1;
2828 static int WINAPI expGetWindowLongA(HWND win, int index)
2830 dbgprintf("GetWindowLongA(0x%x, %d) => 0\n", win, index);
2831 return 1;
2834 static int WINAPI expGetObjectA(HGDIOBJ hobj, int objsize, LPVOID obj)
2836 dbgprintf("GetObjectA(0x%x, %d, 0x%x) => %d\n", hobj, objsize, obj, objsize);
2837 return objsize;
2840 static int WINAPI expCreateRectRgn(int x, int y, int width, int height)
2842 dbgprintf("CreateRectRgn(%d, %d, %d, %d) => 0\n", x, y, width, height);
2843 return 0;
2846 static int WINAPI expEnumWindows(int (*callback_func)(HWND, LPARAM), void *callback_param)
2848 int i, i2;
2849 dbgprintf("EnumWindows(0x%x, 0x%x) => 1\n", callback_func, callback_param);
2850 i = callback_func(0, (LPARAM)callback_param);
2851 i2 = callback_func(1, (LPARAM)callback_param);
2852 return i && i2;
2855 static int WINAPI expGetWindowThreadProcessId(HWND win, int *pid_data)
2857 int tid = pthread_self();
2858 dbgprintf("GetWindowThreadProcessId(0x%x, 0x%x) => %d\n",
2859 win, pid_data, tid);
2860 if (pid_data)
2861 *(int*)pid_data = tid;
2862 return tid;
2865 //HWND WINAPI CreateWindowExA(DWORD,LPCSTR,LPCSTR,DWORD,INT,INT,
2866 // INT,INT,HWND,HMENU,HINSTANCE,LPVOID);
2868 static HWND WINAPI expCreateWindowExA(int exstyle, const char *classname,
2869 const char *winname, int style, int x, int y, int w, int h,
2870 HWND parent, HMENU menu, HINSTANCE inst, LPVOID param)
2872 printf("CreateWindowEx() called\n");
2873 dbgprintf("CreateWindowEx(%d, 0x%x = %s, 0x%x = %s, %d, %d, %d, %d, %d, 0x%x, 0x%x, 0x%x, 0x%x) => 1\n",
2874 exstyle, classname, classname, winname, winname, style, x, y, w, h,
2875 parent, menu, inst, param);
2876 printf("CreateWindowEx() called okey\n");
2877 return 1;
2880 static int WINAPI expwaveOutGetNumDevs(void)
2882 dbgprintf("waveOutGetNumDevs() => 0\n");
2883 return 0;
2885 #endif
2888 * Returns the number of milliseconds, modulo 2^32, since the start
2889 * of the wineserver.
2891 static int WINAPI expGetTickCount(void)
2893 static int tcstart = 0;
2894 struct timeval t;
2895 int tc;
2896 gettimeofday( &t, NULL );
2897 tc = ((t.tv_sec * 1000) + (t.tv_usec / 1000)) - tcstart;
2898 if (tcstart == 0)
2900 tcstart = 0;
2901 tc = 0;
2903 dbgprintf("GetTickCount() => %d\n", tc);
2904 return tc;
2907 static int WINAPI expCreateFontA(void)
2909 dbgprintf("CreateFontA() => 0x0\n");
2910 return 1;
2913 /* tried to get pvmjpg work in a different way - no success */
2914 static int WINAPI expDrawTextA(int hDC, char* lpString, int nCount,
2915 LPRECT lpRect, unsigned int uFormat)
2917 dbgprintf("expDrawTextA(%p,...) => 8\n", hDC);
2918 return 8;
2921 static int WINAPI expGetPrivateProfileIntA(const char* appname,
2922 const char* keyname,
2923 int default_value,
2924 const char* filename)
2926 int size=255;
2927 char buffer[256];
2928 char* fullname;
2929 int result;
2931 buffer[255]=0;
2932 if(!(appname && keyname && filename) )
2934 dbgprintf("GetPrivateProfileIntA('%s', '%s', %d, '%s') => %d\n", appname, keyname, default_value, filename, default_value );
2935 return default_value;
2937 fullname=malloc(50+strlen(appname)+strlen(keyname)+strlen(filename));
2938 strcpy(fullname, "Software\\IniFileMapping\\");
2939 strcat(fullname, appname);
2940 strcat(fullname, "\\");
2941 strcat(fullname, keyname);
2942 strcat(fullname, "\\");
2943 strcat(fullname, filename);
2944 result=RegQueryValueExA(HKEY_LOCAL_MACHINE, fullname, NULL, NULL, (int*)buffer, &size);
2945 if((size>=0)&&(size<256))
2946 buffer[size]=0;
2947 // printf("GetPrivateProfileIntA(%s, %s, %s) -> %s\n", appname, keyname, filename, buffer);
2948 free(fullname);
2949 if(result)
2950 result=default_value;
2951 else
2952 result=atoi(buffer);
2953 dbgprintf("GetPrivateProfileIntA('%s', '%s', %d, '%s') => %d\n", appname, keyname, default_value, filename, result);
2954 return result;
2956 static int WINAPI expGetProfileIntA(const char* appname,
2957 const char* keyname,
2958 int default_value)
2960 dbgprintf("GetProfileIntA -> ");
2961 return expGetPrivateProfileIntA(appname, keyname, default_value, "default");
2964 static int WINAPI expGetPrivateProfileStringA(const char* appname,
2965 const char* keyname,
2966 const char* def_val,
2967 char* dest, unsigned int len,
2968 const char* filename)
2970 int result;
2971 int size;
2972 char* fullname;
2973 dbgprintf("GetPrivateProfileStringA('%s', '%s', def_val '%s', 0x%x, 0x%x, '%s')", appname, keyname, def_val, dest, len, filename );
2974 if(!(appname && keyname && filename) ) return 0;
2975 fullname=malloc(50+strlen(appname)+strlen(keyname)+strlen(filename));
2976 strcpy(fullname, "Software\\IniFileMapping\\");
2977 strcat(fullname, appname);
2978 strcat(fullname, "\\");
2979 strcat(fullname, keyname);
2980 strcat(fullname, "\\");
2981 strcat(fullname, filename);
2982 size=len;
2983 result=RegQueryValueExA(HKEY_LOCAL_MACHINE, fullname, NULL, NULL, (int*)dest, &size);
2984 free(fullname);
2985 if(result)
2987 strncpy(dest, def_val, size);
2988 if (strlen(def_val)< size) size = strlen(def_val);
2990 dbgprintf(" => %d ( '%s' )\n", size, dest);
2991 return size;
2993 static int WINAPI expWritePrivateProfileStringA(const char* appname,
2994 const char* keyname,
2995 const char* string,
2996 const char* filename)
2998 char* fullname;
2999 dbgprintf("WritePrivateProfileStringA('%s', '%s', '%s', '%s')", appname, keyname, string, filename );
3000 if(!(appname && keyname && filename) )
3002 dbgprintf(" => -1\n");
3003 return -1;
3005 fullname=malloc(50+strlen(appname)+strlen(keyname)+strlen(filename));
3006 strcpy(fullname, "Software\\IniFileMapping\\");
3007 strcat(fullname, appname);
3008 strcat(fullname, "\\");
3009 strcat(fullname, keyname);
3010 strcat(fullname, "\\");
3011 strcat(fullname, filename);
3012 RegSetValueExA(HKEY_LOCAL_MACHINE, fullname, 0, REG_SZ, (int*)string, strlen(string));
3013 // printf("RegSetValueExA(%s,%d)\n", string, strlen(string));
3014 // printf("WritePrivateProfileStringA(%s, %s, %s, %s)\n", appname, keyname, string, filename );
3015 free(fullname);
3016 dbgprintf(" => 0\n");
3017 return 0;
3020 unsigned int GetPrivateProfileIntA_(const char* appname, const char* keyname, INT default_value, const char* filename)
3022 return expGetPrivateProfileIntA(appname, keyname, default_value, filename);
3024 int GetPrivateProfileStringA_(const char* appname, const char* keyname,
3025 const char* def_val, char* dest, unsigned int len, const char* filename)
3027 return expGetPrivateProfileStringA(appname, keyname, def_val, dest, len, filename);
3029 int WritePrivateProfileStringA_(const char* appname, const char* keyname,
3030 const char* string, const char* filename)
3032 return expWritePrivateProfileStringA(appname, keyname, string, filename);
3037 static int WINAPI expDefDriverProc(int private, int id, int msg, int arg1, int arg2)
3039 dbgprintf("DefDriverProc(0x%x, 0x%x, 0x%x, 0x%x, 0x%x) => 0\n", private, id, msg, arg1, arg2);
3040 return 0;
3043 static int WINAPI expSizeofResource(int v1, int v2)
3045 int result=SizeofResource(v1, v2);
3046 dbgprintf("SizeofResource(0x%x, 0x%x) => %d\n", v1, v2, result);
3047 return result;
3050 static int WINAPI expGetLastError(void)
3052 int result=GetLastError();
3053 dbgprintf("GetLastError() => 0x%x\n", result);
3054 return result;
3057 static void WINAPI expSetLastError(int error)
3059 dbgprintf("SetLastError(0x%x)\n", error);
3060 SetLastError(error);
3063 static int WINAPI expStringFromGUID2(GUID* guid, char* str, int cbMax)
3065 int result=snprintf(str, cbMax, "%.8x-%.4x-%.4x-%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x",
3066 guid->f1, guid->f2, guid->f3,
3067 (unsigned char)guid->f4[0], (unsigned char)guid->f4[1],
3068 (unsigned char)guid->f4[2], (unsigned char)guid->f4[3],
3069 (unsigned char)guid->f4[4], (unsigned char)guid->f4[5],
3070 (unsigned char)guid->f4[6], (unsigned char)guid->f4[7]);
3071 dbgprintf("StringFromGUID2(0x%x, 0x%x='%s', %d) => %d\n", guid, str, str, cbMax, result);
3072 return result;
3076 static int WINAPI expGetFileVersionInfoSizeA(const char* name, int* lpHandle)
3078 dbgprintf("GetFileVersionInfoSizeA(0x%x='%s', 0x%X) => 0\n", name, name, lpHandle);
3079 return 0;
3082 static int WINAPI expIsBadStringPtrW(const short* string, int nchars)
3084 int result;
3085 if(string==0)result=1; else result=0;
3086 dbgprintf("IsBadStringPtrW(0x%x, %d) => %d", string, nchars, result);
3087 if(string)wch_print(string);
3088 return result;
3090 static int WINAPI expIsBadStringPtrA(const char* string, int nchars)
3092 return expIsBadStringPtrW((const short*)string, nchars);
3094 static long WINAPI expInterlockedExchangeAdd( long* dest, long incr )
3096 long ret;
3097 __asm__ volatile
3099 "lock; xaddl %0,(%1)"
3100 : "=r" (ret)
3101 : "r" (dest), "0" (incr)
3102 : "memory"
3104 return ret;
3107 static long WINAPI expInterlockedCompareExchange( unsigned long* dest, unsigned long exchange, unsigned long comperand)
3109 unsigned long retval = *dest;
3110 if(*dest == comperand)
3111 *dest = exchange;
3112 return retval;
3115 static long WINAPI expInterlockedIncrement( long* dest )
3117 long result=expInterlockedExchangeAdd( dest, 1 ) + 1;
3118 dbgprintf("InterlockedIncrement(0x%x => %d) => %d\n", dest, *dest, result);
3119 return result;
3121 static long WINAPI expInterlockedDecrement( long* dest )
3123 long result=expInterlockedExchangeAdd( dest, -1 ) - 1;
3124 dbgprintf("InterlockedDecrement(0x%x => %d) => %d\n", dest, *dest, result);
3125 return result;
3128 static void WINAPI expOutputDebugStringA( const char* string )
3130 dbgprintf("OutputDebugStringA(0x%x='%s')\n", string);
3131 fprintf(stderr, "DEBUG: %s\n", string);
3134 static int WINAPI expGetDC(int hwnd)
3136 dbgprintf("GetDC(0x%x) => 1\n", hwnd);
3137 return 1;
3140 static int WINAPI expReleaseDC(int hwnd, int hdc)
3142 dbgprintf("ReleaseDC(0x%x, 0x%x) => 1\n", hwnd, hdc);
3143 return 1;
3146 static int WINAPI expGetDesktopWindow(void)
3148 dbgprintf("GetDesktopWindow() => 0\n");
3149 return 0;
3152 static int cursor[100];
3154 static int WINAPI expLoadCursorA(int handle,LPCSTR name)
3156 dbgprintf("LoadCursorA(%d, 0x%x='%s') => 0x%x\n", handle, name, (int)&cursor[0]);
3157 return (int)&cursor[0];
3159 static int WINAPI expSetCursor(void *cursor)
3161 dbgprintf("SetCursor(0x%x) => 0x%x\n", cursor, cursor);
3162 return (int)cursor;
3164 static int WINAPI expGetCursorPos(void *cursor)
3166 dbgprintf("GetCursorPos(0x%x) => 0x%x\n", cursor, cursor);
3167 return 1;
3169 #ifdef CONFIG_QTX_CODECS
3170 static int show_cursor = 0;
3171 static int WINAPI expShowCursor(int show)
3173 dbgprintf("ShowCursor(%d) => %d\n", show, show);
3174 if (show)
3175 show_cursor++;
3176 else
3177 show_cursor--;
3178 return show_cursor;
3180 #endif
3181 static int WINAPI expRegisterWindowMessageA(char *message)
3183 dbgprintf("RegisterWindowMessageA(%s)\n", message);
3184 return 1;
3186 static int WINAPI expGetProcessVersion(int pid)
3188 dbgprintf("GetProcessVersion(%d)\n", pid);
3189 return 1;
3191 static int WINAPI expGetCurrentThread(void)
3193 /* FIXME! */
3194 dbgprintf("GetCurrentThread() => %x\n", 0xcfcf9898);
3195 return 0xcfcf9898;
3197 static int WINAPI expGetOEMCP(void)
3199 dbgprintf("GetOEMCP()\n");
3200 return 1;
3202 static int WINAPI expGetCPInfo(int cp,void *info)
3204 dbgprintf("GetCPInfo()\n");
3205 return 0;
3207 #ifdef CONFIG_QTX_CODECS
3208 #define SM_CXSCREEN 0
3209 #define SM_CYSCREEN 1
3210 #define SM_XVIRTUALSCREEN 76
3211 #define SM_YVIRTUALSCREEN 77
3212 #define SM_CXVIRTUALSCREEN 78
3213 #define SM_CYVIRTUALSCREEN 79
3214 #define SM_CMONITORS 80
3215 #endif
3216 static int WINAPI expGetSystemMetrics(int index)
3218 dbgprintf("GetSystemMetrics(%d)\n", index);
3219 #ifdef CONFIG_QTX_CODECS
3220 switch(index)
3222 case SM_XVIRTUALSCREEN:
3223 case SM_YVIRTUALSCREEN:
3224 return 0;
3225 case SM_CXSCREEN:
3226 case SM_CXVIRTUALSCREEN:
3227 return PSEUDO_SCREEN_WIDTH;
3228 case SM_CYSCREEN:
3229 case SM_CYVIRTUALSCREEN:
3230 return PSEUDO_SCREEN_HEIGHT;
3231 case SM_CMONITORS:
3232 return 1;
3234 #endif
3235 return 1;
3237 static int WINAPI expGetSysColor(int index)
3239 dbgprintf("GetSysColor(%d) => 1\n", index);
3240 return 1;
3242 static int WINAPI expGetSysColorBrush(int index)
3244 dbgprintf("GetSysColorBrush(%d)\n", index);
3245 return 1;
3250 static int WINAPI expGetSystemPaletteEntries(int hdc, int iStartIndex, int nEntries, void* lppe)
3252 dbgprintf("GetSystemPaletteEntries(0x%x, 0x%x, 0x%x, 0x%x) => 0\n",
3253 hdc, iStartIndex, nEntries, lppe);
3254 return 0;
3258 typedef struct TIME_ZONE_INFORMATION {
3259 long Bias;
3260 char StandardName[32];
3261 SYSTEMTIME StandardDate;
3262 long StandardBias;
3263 char DaylightName[32];
3264 SYSTEMTIME DaylightDate;
3265 long DaylightBias;
3266 } TIME_ZONE_INFORMATION, *LPTIME_ZONE_INFORMATION;
3269 static int WINAPI expGetTimeZoneInformation(LPTIME_ZONE_INFORMATION lpTimeZoneInformation)
3271 const short name[]={'C', 'e', 'n', 't', 'r', 'a', 'l', ' ', 'S', 't', 'a',
3272 'n', 'd', 'a', 'r', 'd', ' ', 'T', 'i', 'm', 'e', 0};
3273 const short pname[]={'C', 'e', 'n', 't', 'r', 'a', 'l', ' ', 'D', 'a', 'y',
3274 'l', 'i', 'g', 'h', 't', ' ', 'T', 'i', 'm', 'e', 0};
3275 dbgprintf("GetTimeZoneInformation(0x%x) => TIME_ZONE_ID_STANDARD\n");
3276 memset(lpTimeZoneInformation, 0, sizeof(TIME_ZONE_INFORMATION));
3277 lpTimeZoneInformation->Bias=360;//GMT-6
3278 memcpy(lpTimeZoneInformation->StandardName, name, sizeof(name));
3279 lpTimeZoneInformation->StandardDate.wMonth=10;
3280 lpTimeZoneInformation->StandardDate.wDay=5;
3281 lpTimeZoneInformation->StandardDate.wHour=2;
3282 lpTimeZoneInformation->StandardBias=0;
3283 memcpy(lpTimeZoneInformation->DaylightName, pname, sizeof(pname));
3284 lpTimeZoneInformation->DaylightDate.wMonth=4;
3285 lpTimeZoneInformation->DaylightDate.wDay=1;
3286 lpTimeZoneInformation->DaylightDate.wHour=2;
3287 lpTimeZoneInformation->DaylightBias=-60;
3288 return TIME_ZONE_ID_STANDARD;
3291 static void WINAPI expGetLocalTime(SYSTEMTIME* systime)
3293 time_t local_time;
3294 struct tm *local_tm;
3295 struct timeval tv;
3297 dbgprintf("GetLocalTime(0x%x)\n");
3298 gettimeofday(&tv, NULL);
3299 local_time=tv.tv_sec;
3300 local_tm=localtime(&local_time);
3302 systime->wYear = local_tm->tm_year + 1900;
3303 systime->wMonth = local_tm->tm_mon + 1;
3304 systime->wDayOfWeek = local_tm->tm_wday;
3305 systime->wDay = local_tm->tm_mday;
3306 systime->wHour = local_tm->tm_hour;
3307 systime->wMinute = local_tm->tm_min;
3308 systime->wSecond = local_tm->tm_sec;
3309 systime->wMilliseconds = (tv.tv_usec / 1000) % 1000;
3310 dbgprintf(" Year: %d\n Month: %d\n Day of week: %d\n"
3311 " Day: %d\n Hour: %d\n Minute: %d\n Second: %d\n"
3312 " Milliseconds: %d\n",
3313 systime->wYear, systime->wMonth, systime->wDayOfWeek, systime->wDay,
3314 systime->wHour, systime->wMinute, systime->wSecond, systime->wMilliseconds);
3317 static int WINAPI expGetSystemTime(SYSTEMTIME* systime)
3319 time_t local_time;
3320 struct tm *local_tm;
3321 struct timeval tv;
3323 dbgprintf("GetSystemTime(0x%x)\n", systime);
3324 gettimeofday(&tv, NULL);
3325 local_time=tv.tv_sec;
3326 local_tm=gmtime(&local_time);
3328 systime->wYear = local_tm->tm_year + 1900;
3329 systime->wMonth = local_tm->tm_mon + 1;
3330 systime->wDayOfWeek = local_tm->tm_wday;
3331 systime->wDay = local_tm->tm_mday;
3332 systime->wHour = local_tm->tm_hour;
3333 systime->wMinute = local_tm->tm_min;
3334 systime->wSecond = local_tm->tm_sec;
3335 systime->wMilliseconds = (tv.tv_usec / 1000) % 1000;
3336 dbgprintf(" Year: %d\n Month: %d\n Day of week: %d\n"
3337 " Day: %d\n Hour: %d\n Minute: %d\n Second: %d\n"
3338 " Milliseconds: %d\n",
3339 systime->wYear, systime->wMonth, systime->wDayOfWeek, systime->wDay,
3340 systime->wHour, systime->wMinute, systime->wSecond, systime->wMilliseconds);
3341 return 0;
3344 #define SECS_1601_TO_1970 ((369 * 365 + 89) * 86400ULL)
3345 static void WINAPI expGetSystemTimeAsFileTime(FILETIME* systime)
3347 struct timeval tv;
3348 unsigned long long secs;
3350 dbgprintf("GetSystemTime(0x%x)\n", systime);
3351 gettimeofday(&tv, NULL);
3352 secs = (tv.tv_sec + SECS_1601_TO_1970) * 10000000;
3353 secs += tv.tv_usec * 10;
3354 systime->dwLowDateTime = secs & 0xffffffff;
3355 systime->dwHighDateTime = (secs >> 32);
3358 static int WINAPI expGetEnvironmentVariableA(const char* name, char* field, int size)
3360 //char *p;
3361 // printf("%s %x %x\n", name, field, size);
3362 if(field)field[0]=0;
3364 p = getenv(name);
3365 if (p) strncpy(field,p,size);
3367 if (strcmp(name,"__MSVCRT_HEAP_SELECT")==0)
3368 strcpy(field,"__GLOBAL_HEAP_SELECTED,1");
3369 dbgprintf("GetEnvironmentVariableA(0x%x='%s', 0x%x, %d) => %d\n", name, name, field, size, strlen(field));
3370 return strlen(field);
3373 static int WINAPI expSetEnvironmentVariableA(const char *name, const char *value)
3375 dbgprintf("SetEnvironmentVariableA(%s, %s)\n", name, value);
3376 return 0;
3379 static void* WINAPI expCoTaskMemAlloc(ULONG cb)
3381 return my_mreq(cb, 0);
3383 static void WINAPI expCoTaskMemFree(void* cb)
3385 my_release(cb);
3391 void* CoTaskMemAlloc(unsigned long cb)
3393 return expCoTaskMemAlloc(cb);
3395 void CoTaskMemFree(void* cb)
3397 expCoTaskMemFree(cb);
3400 struct COM_OBJECT_INFO
3402 GUID clsid;
3403 long (*GetClassObject) (GUID* clsid, const GUID* iid, void** ppv);
3406 static struct COM_OBJECT_INFO* com_object_table=0;
3407 static int com_object_size=0;
3408 int RegisterComClass(const GUID* clsid, GETCLASSOBJECT gcs)
3410 if(!clsid || !gcs)
3411 return -1;
3412 com_object_table=realloc(com_object_table, sizeof(struct COM_OBJECT_INFO)*(++com_object_size));
3413 com_object_table[com_object_size-1].clsid=*clsid;
3414 com_object_table[com_object_size-1].GetClassObject=gcs;
3415 return 0;
3418 int UnregisterComClass(const GUID* clsid, GETCLASSOBJECT gcs)
3420 int found = 0;
3421 int i = 0;
3422 if(!clsid || !gcs)
3423 return -1;
3425 if (com_object_table == 0)
3426 printf("Warning: UnregisterComClass() called without any registered class\n");
3427 while (i < com_object_size)
3429 if (found && i > 0)
3431 memcpy(&com_object_table[i - 1].clsid,
3432 &com_object_table[i].clsid, sizeof(GUID));
3433 com_object_table[i - 1].GetClassObject =
3434 com_object_table[i].GetClassObject;
3436 else if (memcmp(&com_object_table[i].clsid, clsid, sizeof(GUID)) == 0
3437 && com_object_table[i].GetClassObject == gcs)
3439 found++;
3441 i++;
3443 if (found)
3445 if (--com_object_size == 0)
3447 free(com_object_table);
3448 com_object_table = 0;
3451 return 0;
3455 const GUID IID_IUnknown =
3457 0x00000000, 0x0000, 0x0000,
3458 {0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}
3460 const GUID IID_IClassFactory =
3462 0x00000001, 0x0000, 0x0000,
3463 {0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}
3466 static long WINAPI expCoCreateInstance(GUID* rclsid, struct IUnknown* pUnkOuter,
3467 long dwClsContext, const GUID* riid, void** ppv)
3469 int i;
3470 struct COM_OBJECT_INFO* ci=0;
3471 for(i=0; i<com_object_size; i++)
3472 if(!memcmp(rclsid, &com_object_table[i].clsid, sizeof(GUID)))
3473 ci=&com_object_table[i];
3474 if(!ci)return REGDB_E_CLASSNOTREG;
3475 // in 'real' world we should mess with IClassFactory here
3476 i=ci->GetClassObject(rclsid, riid, ppv);
3477 return i;
3480 long CoCreateInstance(GUID* rclsid, struct IUnknown* pUnkOuter,
3481 long dwClsContext, const GUID* riid, void** ppv)
3483 return expCoCreateInstance(rclsid, pUnkOuter, dwClsContext, riid, ppv);
3486 static int WINAPI expIsRectEmpty(CONST RECT *lprc)
3488 int r = 0;
3489 int w,h;
3490 //trapbug();
3491 if (lprc)
3493 w = lprc->right - lprc->left;
3494 h = lprc->bottom - lprc->top;
3495 if (w <= 0 || h <= 0)
3496 r = 1;
3498 else
3499 r = 1;
3501 dbgprintf("IsRectEmpty(%p) => %s\n", lprc, (r) ? "TRUE" : "FALSE");
3502 //printf("Rect: left: %d, top: %d, right: %d, bottom: %d\n", lprc->left, lprc->top, lprc->right, lprc->bottom);
3503 // return 0; // wmv9?
3504 return r; // TM20
3507 static int _adjust_fdiv=0; //what's this? - used to adjust division
3508 static int _winver = 0x510; // windows version
3513 static unsigned int WINAPI expGetTempPathA(unsigned int len, char* path)
3515 dbgprintf("GetTempPathA(%d, 0x%x)", len, path);
3516 if(len<5)
3518 dbgprintf(" => 0\n");
3519 return 0;
3521 strcpy(path, "/tmp");
3522 dbgprintf(" => 5 ( '/tmp' )\n");
3523 return 5;
3526 FYI:
3527 typedef struct
3529 DWORD dwFileAttributes;
3530 FILETIME ftCreationTime;
3531 FILETIME ftLastAccessTime;
3532 FILETIME ftLastWriteTime;
3533 DWORD nFileSizeHigh;
3534 DWORD nFileSizeLow;
3535 DWORD dwReserved0;
3536 DWORD dwReserved1;
3537 CHAR cFileName[260];
3538 CHAR cAlternateFileName[14];
3539 } WIN32_FIND_DATAA, *LPWIN32_FIND_DATAA;
3542 static DIR* qtx_dir=NULL;
3544 static WIN_BOOL WINAPI expFindNextFileA(HANDLE h,LPWIN32_FIND_DATAA lpfd)
3546 #ifdef CONFIG_QTX_CODECS
3547 dbgprintf("FindNextFileA(0x%x, 0x%x) => 0\n", h, lpfd);
3548 if(h==FILE_HANDLE_quicktimeqtx){
3549 struct dirent* d;
3550 if(!qtx_dir) return 0;
3551 while((d=readdir(qtx_dir))){
3552 char* x=strrchr(d->d_name,'.');
3553 if(!x) continue;
3554 if(strcmp(x,".qtx")) continue;
3555 strcpy(lpfd->cFileName,d->d_name);
3556 // sprintf(lpfd->cAlternateFileName,"%-8s.qtx",d->d_name);
3557 strcpy(lpfd->cAlternateFileName,"foobar.qtx");
3558 dbgprintf("### FindNext: %s\n",lpfd->cFileName);
3559 return 1;
3561 closedir(qtx_dir); qtx_dir=NULL;
3562 return 0;
3564 #endif
3565 return 0;
3568 static HANDLE WINAPI expFindFirstFileA(LPCSTR s, LPWIN32_FIND_DATAA lpfd)
3570 dbgprintf("FindFirstFileA(0x%x='%s', 0x%x) => 0\n", s, s, lpfd);
3571 // printf("\n### FindFirstFileA('%s')...\n",s);
3572 #ifdef CONFIG_QTX_CODECS
3573 if(strstr(s, "quicktime\\*.QTX")){
3574 dbgprintf("FindFirstFileA(0x%x='%s', 0x%x) => QTX\n", s, s, lpfd);
3575 dbgprintf("\n### Searching for QuickTime plugins (*.qtx) at %s...\n",
3576 codec_path);
3577 qtx_dir = opendir(codec_path);
3578 if(!qtx_dir) return (HANDLE)-1;
3579 memset(lpfd,0,sizeof(*lpfd));
3580 if(expFindNextFileA(FILE_HANDLE_quicktimeqtx,lpfd))
3581 return FILE_HANDLE_quicktimeqtx;
3582 printf("loader: Couldn't find the QuickTime plugins (.qtx files) at %s\n",
3583 codec_path);
3584 return (HANDLE)-1;
3586 #if 0
3587 if(strstr(s, "QuickTime.qts")){
3588 dbgprintf("FindFirstFileA(0x%x='%s', 0x%x) => QTS\n", s, s, lpfd);
3589 // if(!strcmp(s,"C:\\windows\\QuickTime.qts\\QuickTime.qts\\*.QTX"))
3590 // return (HANDLE)-1;
3591 strcpy(lpfd->cFileName, "QuickTime.qts");
3592 strcpy(lpfd->cAlternateFileName, "QuickT~1.qts");
3593 return FILE_HANDLE_quicktimeqts;
3595 #endif
3596 #endif
3597 if(strstr(s, "*.vwp")){
3598 // hack for VoxWare codec plugins:
3599 strcpy(lpfd->cFileName, "msms001.vwp");
3600 strcpy(lpfd->cAlternateFileName, "msms001.vwp");
3601 return (HANDLE)0;
3603 // return 'file not found'
3604 return (HANDLE)-1;
3607 static WIN_BOOL WINAPI expFindClose(HANDLE h)
3609 dbgprintf("FindClose(0x%x) => 0\n", h);
3610 #ifdef CONFIG_QTX_CODECS
3611 // if(h==FILE_HANDLE_quicktimeqtx && qtx_dir){
3612 // closedir(qtx_dir);
3613 // qtx_dir=NULL;
3614 // }
3615 #endif
3616 return 0;
3618 static UINT WINAPI expSetErrorMode(UINT i)
3620 dbgprintf("SetErrorMode(%d) => 0\n", i);
3621 return 0;
3623 static UINT WINAPI expGetWindowsDirectoryA(LPSTR s,UINT c)
3625 char windir[]="c:\\windows";
3626 int result;
3627 strncpy(s, windir, c);
3628 result=1+((c<strlen(windir))?c:strlen(windir));
3629 dbgprintf("GetWindowsDirectoryA(0x%x, %d) => %d\n", s, c, result);
3630 return result;
3632 #ifdef CONFIG_QTX_CODECS
3633 static UINT WINAPI expGetCurrentDirectoryA(UINT c, LPSTR s)
3635 char curdir[]="c:\\";
3636 int result;
3637 strncpy(s, curdir, c);
3638 result=1+((c<strlen(curdir))?c:strlen(curdir));
3639 dbgprintf("GetCurrentDirectoryA(0x%x, %d) => %d\n", s, c, result);
3640 return result;
3643 static int WINAPI expSetCurrentDirectoryA(const char *pathname)
3645 dbgprintf("SetCurrentDirectoryA(0x%x = %s) => 1\n", pathname, pathname);
3646 #if 0
3647 if (strrchr(pathname, '\\'))
3648 chdir(strcat(strrchr(pathname, '\\')+1, '/'));
3649 else
3650 chdir(pathname);
3651 #endif
3652 return 1;
3655 static int WINAPI expCreateDirectoryA(const char *pathname, void *sa)
3657 dbgprintf("CreateDirectory(0x%x = %s, 0x%x) => 1\n",
3658 pathname, pathname, sa);
3659 #if 0
3660 p = strrchr(pathname, '\\')+1;
3661 strcpy(&buf[0], p); /* should be strncpy */
3662 if (!strlen(p))
3664 buf[0] = '.';
3665 buf[1] = 0;
3667 #if 0
3668 if (strrchr(pathname, '\\'))
3669 mkdir(strcat(strrchr(pathname, '\\')+1, '/'), 666);
3670 else
3671 mkdir(pathname, 666);
3672 #endif
3673 mkdir(&buf);
3674 #endif
3675 return 1;
3677 #endif
3678 static WIN_BOOL WINAPI expDeleteFileA(LPCSTR s)
3680 dbgprintf("DeleteFileA(0x%x='%s') => 0\n", s, s);
3681 return 0;
3683 static WIN_BOOL WINAPI expFileTimeToLocalFileTime(const FILETIME* cpf, LPFILETIME pf)
3685 dbgprintf("FileTimeToLocalFileTime(0x%x, 0x%x) => 0\n", cpf, pf);
3686 return 0;
3689 static UINT WINAPI expGetTempFileNameA(LPCSTR cs1,LPCSTR cs2,UINT i,LPSTR ps)
3691 char mask[16]="/tmp/AP_XXXXXX";
3692 int result;
3693 dbgprintf("GetTempFileNameA(0x%x='%s', 0x%x='%s', %d, 0x%x)", cs1, cs1, cs2, cs2, i, ps);
3694 if(i && i<10)
3696 dbgprintf(" => -1\n");
3697 return -1;
3699 result=mkstemp(mask);
3700 sprintf(ps, "AP%d", result);
3701 dbgprintf(" => %d\n", strlen(ps));
3702 return strlen(ps);
3705 // This func might need proper implementation if we want AngelPotion codec.
3706 // They try to open APmpeg4v1.apl with it.
3707 // DLL will close opened file with CloseHandle().
3709 static HANDLE WINAPI expCreateFileA(LPCSTR cs1,DWORD i1,DWORD i2,
3710 LPSECURITY_ATTRIBUTES p1, DWORD i3,DWORD i4,HANDLE i5)
3712 dbgprintf("CreateFileA(0x%x='%s', %d, %d, 0x%x, %d, %d, 0x%x)\n", cs1, cs1, i1,
3713 i2, p1, i3, i4, i5);
3714 if((!cs1) || (strlen(cs1)<2))return -1;
3716 #ifdef CONFIG_QTX_CODECS
3717 if(strstr(cs1, "QuickTime.qts"))
3719 int result;
3720 char* tmp = malloc(strlen(codec_path) + 50);
3721 strcpy(tmp, codec_path);
3722 strcat(tmp, "/");
3723 strcat(tmp, "QuickTime.qts");
3724 result=open(tmp, O_RDONLY);
3725 free(tmp);
3726 return result;
3728 if(strstr(cs1, ".qtx"))
3730 int result;
3731 char* tmp = malloc(strlen(codec_path) + 250);
3732 char* x=strrchr(cs1,'\\');
3733 sprintf(tmp, "%s/%s", codec_path, x ? (x + 1) : cs1);
3734 // printf("### Open: %s -> %s\n",cs1,tmp);
3735 result=open(tmp, O_RDONLY);
3736 free(tmp);
3737 return result;
3739 #endif
3741 if(strncmp(cs1, "AP", 2) == 0)
3743 int result;
3744 char* tmp = malloc(strlen(codec_path) + 50);
3745 strcpy(tmp, codec_path);
3746 strcat(tmp, "/");
3747 strcat(tmp, "APmpg4v1.apl");
3748 result=open(tmp, O_RDONLY);
3749 free(tmp);
3750 return result;
3752 if (strstr(cs1, "vp3") || strstr(cs1, ".fpf") || strstr(cs1, ".col"))
3754 int r;
3755 int flg = 0;
3756 char* tmp=malloc(20 + strlen(cs1));
3757 strcpy(tmp, "/tmp/");
3758 strcat(tmp, cs1);
3759 r = 4;
3760 while (tmp[r])
3762 if (tmp[r] == ':' || tmp[r] == '\\')
3763 tmp[r] = '_';
3764 r++;
3766 if (GENERIC_READ & i1)
3767 flg |= O_RDONLY;
3768 else if (GENERIC_WRITE & i1)
3770 flg |= O_WRONLY | O_CREAT;
3771 printf("Warning: openning filename %s %d (flags; 0x%x) for write\n", tmp, r, flg);
3773 r=open(tmp, flg, S_IRWXU);
3774 free(tmp);
3775 return r;
3778 // Needed by wnvplay1.dll
3779 if (strstr(cs1, "WINNOV.bmp"))
3781 int r;
3782 r=open("/dev/null", O_RDONLY);
3783 return r;
3786 #if 0
3787 /* we need this for some virtualdub filters */
3789 int r;
3790 int flg = 0;
3791 if (GENERIC_READ & i1)
3792 flg |= O_RDONLY;
3793 else if (GENERIC_WRITE & i1)
3795 flg |= O_WRONLY;
3796 printf("Warning: openning filename %s %d (flags; 0x%x) for write\n", cs1, r, flg);
3798 r=open(cs1, flg);
3799 return r;
3801 #endif
3803 return atoi(cs1+2);
3805 static UINT WINAPI expGetSystemDirectoryA(
3806 char* lpBuffer, // address of buffer for system directory
3807 UINT uSize // size of directory buffer
3809 dbgprintf("GetSystemDirectoryA(%p,%d)\n", lpBuffer,uSize);
3810 if(!lpBuffer) strcpy(lpBuffer,".");
3811 return 1;
3814 static char sysdir[]=".";
3815 static LPCSTR WINAPI expGetSystemDirectoryA(void)
3817 dbgprintf("GetSystemDirectoryA() => 0x%x='%s'\n", sysdir, sysdir);
3818 return sysdir;
3821 static DWORD WINAPI expGetFullPathNameA
3823 LPCTSTR lpFileName,
3824 DWORD nBufferLength,
3825 LPTSTR lpBuffer,
3826 LPTSTR lpFilePart
3828 if(!lpFileName) return 0;
3829 dbgprintf("GetFullPathNameA('%s',%d,%p,%p)\n",lpFileName,nBufferLength,
3830 lpBuffer, lpFilePart);
3831 #if 0
3832 #ifdef CONFIG_QTX_CODECS
3833 strcpy(lpFilePart, "Quick123.qts");
3834 #else
3835 strcpy(lpFilePart, lpFileName);
3836 #endif
3837 #else
3838 if (strrchr(lpFileName, '\\'))
3839 lpFilePart = strrchr(lpFileName, '\\');
3840 else
3841 lpFilePart = (LPTSTR)lpFileName;
3842 #endif
3843 strcpy(lpBuffer, lpFileName);
3844 // strncpy(lpBuffer, lpFileName, rindex(lpFileName, '\\')-lpFileName);
3845 return strlen(lpBuffer);
3848 static DWORD WINAPI expGetShortPathNameA
3850 LPCSTR longpath,
3851 LPSTR shortpath,
3852 DWORD shortlen
3854 if(!longpath) return 0;
3855 dbgprintf("GetShortPathNameA('%s',%p,%d)\n",longpath,shortpath,shortlen);
3856 strcpy(shortpath,longpath);
3857 return strlen(shortpath);
3860 static WIN_BOOL WINAPI expReadFile(HANDLE h,LPVOID pv,DWORD size,LPDWORD rd,LPOVERLAPPED unused)
3862 int result;
3863 dbgprintf("ReadFile(%d, 0x%x, %d -> 0x%x)\n", h, pv, size, rd);
3864 result=read(h, pv, size);
3865 if(rd)*rd=result;
3866 if(!result)return 0;
3867 return 1;
3870 static WIN_BOOL WINAPI expWriteFile(HANDLE h,LPCVOID pv,DWORD size,LPDWORD wr,LPOVERLAPPED unused)
3872 int result;
3873 dbgprintf("WriteFile(%d, 0x%x, %d -> 0x%x)\n", h, pv, size, wr);
3874 if(h==1234)h=1;
3875 result=write(h, pv, size);
3876 if(wr)*wr=result;
3877 if(!result)return 0;
3878 return 1;
3880 static DWORD WINAPI expSetFilePointer(HANDLE h, LONG val, LPLONG ext, DWORD whence)
3882 int wh;
3883 dbgprintf("SetFilePointer(%d, 0x%x, 0x%x = %d, %d)\n", h, val, ext, ext ? *ext : 0, whence);
3884 //why would DLL want temporary file with >2Gb size?
3885 switch(whence)
3887 case FILE_BEGIN:
3888 wh=SEEK_SET;break;
3889 case FILE_END:
3890 wh=SEEK_END;break;
3891 case FILE_CURRENT:
3892 wh=SEEK_CUR;break;
3893 default:
3894 return -1;
3896 #ifdef CONFIG_QTX_CODECS
3897 if (val == 0 && ext != 0)
3898 val = val&(*ext);
3899 #endif
3900 return lseek(h, val, wh);
3903 static HDRVR WINAPI expOpenDriverA(LPCSTR szDriverName, LPCSTR szSectionName,
3904 LPARAM lParam2)
3906 dbgprintf("OpenDriverA(0x%x='%s', 0x%x='%s', 0x%x) => -1\n", szDriverName, szDriverName, szSectionName, szSectionName, lParam2);
3907 return -1;
3909 static HDRVR WINAPI expOpenDriver(LPCSTR szDriverName, LPCSTR szSectionName,
3910 LPARAM lParam2)
3912 dbgprintf("OpenDriver(0x%x='%s', 0x%x='%s', 0x%x) => -1\n", szDriverName, szDriverName, szSectionName, szSectionName, lParam2);
3913 return -1;
3917 static WIN_BOOL WINAPI expGetProcessAffinityMask(HANDLE hProcess,
3918 LPDWORD lpProcessAffinityMask,
3919 LPDWORD lpSystemAffinityMask)
3921 dbgprintf("GetProcessAffinityMask(0x%x, 0x%x, 0x%x) => 1\n",
3922 hProcess, lpProcessAffinityMask, lpSystemAffinityMask);
3923 if(lpProcessAffinityMask)*lpProcessAffinityMask=1;
3924 if(lpSystemAffinityMask)*lpSystemAffinityMask=1;
3925 return 1;
3928 // Fake implementation: does nothing, but does it right :)
3929 static WIN_BOOL WINAPI expSetProcessAffinityMask(HANDLE hProcess,
3930 LPDWORD dwProcessAffinityMask)
3932 dbgprintf("SetProcessAffinityMask(0x%x, 0x%x) => 1\n",
3933 hProcess, dwProcessAffinityMask);
3935 return 1;
3938 static int WINAPI expMulDiv(int nNumber, int nNumerator, int nDenominator)
3940 static const long long max_int=0x7FFFFFFFLL;
3941 static const long long min_int=-0x80000000LL;
3942 long long tmp=(long long)nNumber*(long long)nNumerator;
3943 dbgprintf("expMulDiv %d * %d / %d\n", nNumber, nNumerator, nDenominator);
3944 if(!nDenominator)return 1;
3945 tmp/=nDenominator;
3946 if(tmp<min_int) return 1;
3947 if(tmp>max_int) return 1;
3948 return (int)tmp;
3951 static LONG WINAPI explstrcmpiA(const char* str1, const char* str2)
3953 LONG result=strcasecmp(str1, str2);
3954 dbgprintf("strcmpi(0x%x='%s', 0x%x='%s') => %d\n", str1, str1, str2, str2, result);
3955 return result;
3958 static LONG WINAPI explstrlenA(const char* str1)
3960 LONG result=strlen(str1);
3961 dbgprintf("strlen(0x%x='%.50s') => %d\n", str1, str1, result);
3962 return result;
3965 static LONG WINAPI explstrcpyA(char* str1, const char* str2)
3967 int result= (int) strcpy(str1, str2);
3968 dbgprintf("strcpy(0x%.50x, 0x%.50x='%.50s') => %d\n", str1, str2, str2, result);
3969 return result;
3971 static LONG WINAPI explstrcpynA(char* str1, const char* str2,int len)
3973 int result;
3974 if (strlen(str2)>len)
3975 result = (int) strncpy(str1, str2,len);
3976 else
3977 result = (int) strcpy(str1,str2);
3978 dbgprintf("strncpy(0x%x, 0x%x='%s' len %d strlen %d) => %x\n", str1, str2, str2,len, strlen(str2),result);
3979 return result;
3981 static LONG WINAPI explstrcatA(char* str1, const char* str2)
3983 int result= (int) strcat(str1, str2);
3984 dbgprintf("strcat(0x%x, 0x%x='%s') => %d\n", str1, str2, str2, result);
3985 return result;
3989 static LONG WINAPI expInterlockedExchange(long *dest, long l)
3991 long retval = *dest;
3992 *dest = l;
3993 return retval;
3996 static void WINAPI expInitCommonControls(void)
3998 dbgprintf("InitCommonControls called!\n");
3999 return;
4002 #ifdef CONFIG_QTX_CODECS
4003 /* needed by QuickTime.qts */
4004 static HWND WINAPI expCreateUpDownControl (DWORD style, INT x, INT y, INT cx, INT cy,
4005 HWND parent, INT id, HINSTANCE inst,
4006 HWND buddy, INT maxVal, INT minVal, INT curVal)
4008 dbgprintf("CreateUpDownControl(...)\n");
4009 return 0;
4011 #endif
4013 /* alex: implement this call! needed for 3ivx */
4014 static HRESULT WINAPI expCoCreateFreeThreadedMarshaler(void *pUnkOuter, void **ppUnkInner)
4016 dbgprintf("CoCreateFreeThreadedMarshaler(%p, %p) called!\n",
4017 pUnkOuter, ppUnkInner);
4018 // return 0;
4019 return ERROR_CALL_NOT_IMPLEMENTED;
4023 static int WINAPI expDuplicateHandle(HANDLE hSourceProcessHandle, // handle to source process
4024 HANDLE hSourceHandle, // handle to duplicate
4025 HANDLE hTargetProcessHandle, // handle to target process
4026 HANDLE* lpTargetHandle, // duplicate handle
4027 DWORD dwDesiredAccess, // requested access
4028 int bInheritHandle, // handle inheritance option
4029 DWORD dwOptions // optional actions
4032 dbgprintf("DuplicateHandle(%p, %p, %p, %p, 0x%x, %d, %d) called\n",
4033 hSourceProcessHandle, hSourceHandle, hTargetProcessHandle,
4034 lpTargetHandle, dwDesiredAccess, bInheritHandle, dwOptions);
4035 *lpTargetHandle = hSourceHandle;
4036 return 1;
4039 static HRESULT WINAPI expCoInitializeEx(LPVOID lpReserved, DWORD dwCoInit)
4041 dbgprintf("CoInitializeEx(%p, %d) called\n", lpReserved, dwCoInit);
4042 return S_OK;
4045 // required by PIM1 codec (used by win98 PCTV Studio capture sw)
4046 static HRESULT WINAPI expCoInitialize(
4047 LPVOID lpReserved /* [in] pointer to win32 malloc interface
4048 (obsolete, should be NULL) */
4052 * Just delegate to the newer method.
4054 return expCoInitializeEx(lpReserved, COINIT_APARTMENTTHREADED);
4057 static void WINAPI expCoUninitialize(void)
4059 dbgprintf("CoUninitialize() called\n");
4062 /* allow static linking */
4063 HRESULT WINAPI CoInitializeEx(LPVOID lpReserved, DWORD dwCoInit)
4065 return expCoInitializeEx(lpReserved, dwCoInit);
4067 HRESULT WINAPI CoInitialize(LPVOID lpReserved)
4069 return expCoInitialize(lpReserved);
4071 void WINAPI CoUninitialize(void)
4073 expCoUninitialize();
4076 static DWORD WINAPI expSetThreadAffinityMask
4078 HANDLE hThread,
4079 DWORD dwThreadAffinityMask
4081 return 0;
4085 * no WINAPI functions - CDECL
4087 static void* expmalloc(int size)
4089 //printf("malloc");
4090 // return malloc(size);
4091 void* result=my_mreq(size,0);
4092 dbgprintf("malloc(0x%x) => 0x%x\n", size,result);
4093 if(result==0)
4094 printf("WARNING: malloc() failed\n");
4095 return result;
4097 static void expfree(void* mem)
4099 // return free(mem);
4100 dbgprintf("free(%p)\n", mem);
4101 my_release(mem);
4103 /* needed by atrac3.acm */
4104 static void *expcalloc(int num, int size)
4106 void* result=my_mreq(num*size,1);
4107 dbgprintf("calloc(%d,%d) => %p\n", num,size,result);
4108 if(result==0)
4109 printf("WARNING: calloc() failed\n");
4110 return result;
4112 static void* expnew(int size)
4114 // printf("NEW:: Call from address %08x\n STACK DUMP:\n", *(-1+(int*)&size));
4115 // printf("%08x %08x %08x %08x\n",
4116 // size, *(1+(int*)&size),
4117 // *(2+(int*)&size),*(3+(int*)&size));
4118 void* result;
4119 assert(size >= 0);
4121 result=my_mreq(size,0);
4122 dbgprintf("new(%d) => %p\n", size, result);
4123 if (result==0)
4124 printf("WARNING: new() failed\n");
4125 return result;
4128 static int expdelete(void* memory)
4130 dbgprintf("delete(%p)\n", memory);
4131 my_release(memory);
4132 return 0;
4136 * local definition - we need only the last two members at this point
4137 * otherwice we would have to introduce here GUIDs and some more types..
4139 typedef struct __attribute__((__packed__))
4141 char hay[0x40];
4142 unsigned long cbFormat; //0x40
4143 char* pbFormat; //0x44
4144 } MY_MEDIA_TYPE;
4145 static HRESULT WINAPI expMoCopyMediaType(MY_MEDIA_TYPE* dest, const MY_MEDIA_TYPE* src)
4147 if (!dest || !src)
4148 return E_POINTER;
4149 memcpy(dest, src, sizeof(MY_MEDIA_TYPE));
4150 if (dest->cbFormat)
4152 dest->pbFormat = (char*) my_mreq(dest->cbFormat, 0);
4153 if (!dest->pbFormat)
4154 return E_OUTOFMEMORY;
4155 memcpy(dest->pbFormat, src->pbFormat, dest->cbFormat);
4157 return S_OK;
4159 static HRESULT WINAPI expMoInitMediaType(MY_MEDIA_TYPE* dest, DWORD cbFormat)
4161 if (!dest)
4162 return E_POINTER;
4163 memset(dest, 0, sizeof(MY_MEDIA_TYPE));
4164 if (cbFormat)
4166 dest->pbFormat = (char*) my_mreq(cbFormat, 0);
4167 if (!dest->pbFormat)
4168 return E_OUTOFMEMORY;
4170 return S_OK;
4172 static HRESULT WINAPI expMoCreateMediaType(MY_MEDIA_TYPE** dest, DWORD cbFormat)
4174 if (!dest)
4175 return E_POINTER;
4176 *dest = my_mreq(sizeof(MY_MEDIA_TYPE), 0);
4177 return expMoInitMediaType(*dest, cbFormat);
4179 static HRESULT WINAPI expMoDuplicateMediaType(MY_MEDIA_TYPE** dest, const void* src)
4181 if (!dest)
4182 return E_POINTER;
4183 *dest = my_mreq(sizeof(MY_MEDIA_TYPE), 0);
4184 return expMoCopyMediaType(*dest, src);
4186 static HRESULT WINAPI expMoFreeMediaType(MY_MEDIA_TYPE* dest)
4188 if (!dest)
4189 return E_POINTER;
4190 if (dest->pbFormat)
4192 my_release(dest->pbFormat);
4193 dest->pbFormat = 0;
4194 dest->cbFormat = 0;
4196 return S_OK;
4198 static HRESULT WINAPI expMoDeleteMediaType(MY_MEDIA_TYPE* dest)
4200 if (!dest)
4201 return E_POINTER;
4202 expMoFreeMediaType(dest);
4203 my_release(dest);
4204 return S_OK;
4207 static int exp_snprintf( char *str, int size, const char *format, ... )
4209 int x;
4210 va_list va;
4211 va_start(va, format);
4212 x=snprintf(str,size,format,va);
4213 dbgprintf("_snprintf( 0x%x, %d, %s, ... ) => %d\n",str,size,format,x);
4214 va_end(va);
4215 return x;
4218 #if 0
4219 static int exp_initterm(int v1, int v2)
4221 dbgprintf("_initterm(0x%x, 0x%x) => 0\n", v1, v2);
4222 return 0;
4224 #else
4225 /* merged from wine - 2002.04.21 */
4226 typedef void (*INITTERMFUNC)(void);
4227 static int exp_initterm(INITTERMFUNC *start, INITTERMFUNC *end)
4229 dbgprintf("_initterm(0x%x, 0x%x) %p\n", start, end, *start);
4230 while (start < end)
4232 if (*start)
4234 //printf("call _initfunc: from: %p %d\n", *start);
4235 // ok this trick with push/pop is necessary as otherwice
4236 // edi/esi registers are being trashed
4237 void* p = *start;
4238 __asm__ volatile
4240 "pushl %%ebx \n\t"
4241 "pushl %%ecx \n\t"
4242 "pushl %%edx \n\t"
4243 "pushl %%edi \n\t"
4244 "pushl %%esi \n\t"
4245 "call *%%eax \n\t"
4246 "popl %%esi \n\t"
4247 "popl %%edi \n\t"
4248 "popl %%edx \n\t"
4249 "popl %%ecx \n\t"
4250 "popl %%ebx \n\t"
4252 : "a"(p)
4253 : "memory"
4255 //printf("done %p %d:%d\n", end);
4257 start++;
4259 return 0;
4261 #endif
4263 /* Fake _initterm_e from msvcr80.dll, needed by sirenacm.dll
4264 * NOTE: If I make this an alias for _initterm, then sirenacm.dll tries to call
4265 other uninmplemented functions; keep this in mind if some future codec needs
4266 a real implementation of this function */
4267 static int exp_initterm_e(INITTERMFUNC *start, INITTERMFUNC *end)
4269 dbgprintf("_initterm_e(0x%x, 0x%x)\n", start, end);
4270 return 0;
4273 static void* exp__dllonexit(void)
4275 // FIXME extract from WINE
4276 return NULL;
4279 static int expwsprintfA(char* string, const char* format, ...)
4281 va_list va;
4282 int result;
4283 va_start(va, format);
4284 result = vsprintf(string, format, va);
4285 dbgprintf("wsprintfA(0x%x, '%s', ...) => %d\n", string, format, result);
4286 va_end(va);
4287 return result;
4290 static int expsprintf(char* str, const char* format, ...)
4292 va_list args;
4293 int r;
4294 dbgprintf("sprintf(0x%x, %s)\n", str, format);
4295 va_start(args, format);
4296 r = vsprintf(str, format, args);
4297 va_end(args);
4298 return r;
4300 static int expsscanf(const char* str, const char* format, ...)
4302 va_list args;
4303 int r;
4304 dbgprintf("sscanf(%s, %s)\n", str, format);
4305 va_start(args, format);
4306 r = vsscanf(str, format, args);
4307 va_end(args);
4308 return r;
4310 static void* expfopen(const char* path, const char* mode)
4312 printf("fopen: \"%s\" mode:%s\n", path, mode);
4313 //return fopen(path, mode);
4314 return fdopen(0, mode); // everything on screen
4316 static int expfprintf(void* stream, const char* format, ...)
4318 va_list args;
4319 int r = 0;
4320 dbgprintf("fprintf(%p, %s, ...)\n", stream, format);
4321 va_start(args, format);
4322 r = vfprintf((FILE*) stream, format, args);
4323 va_end(args);
4324 return r;
4327 static int expprintf(const char* format, ...)
4329 va_list args;
4330 int r;
4331 dbgprintf("printf(%s, ...)\n", format);
4332 va_start(args, format);
4333 r = vprintf(format, args);
4334 va_end(args);
4335 return r;
4338 static char* expgetenv(const char* varname)
4340 char* v = getenv(varname);
4341 dbgprintf("getenv(%s) => %s\n", varname, v);
4342 return v;
4345 static void* expwcscpy(WCHAR* dst, const WCHAR* src)
4347 WCHAR* p = dst;
4348 while ((*p++ = *src++))
4350 return dst;
4353 static char* expstrrchr(char* string, int value)
4355 char* result=strrchr(string, value);
4356 if(result)
4357 dbgprintf("strrchr(0x%x='%s', %d) => 0x%x='%s'", string, string, value, result, result);
4358 else
4359 dbgprintf("strrchr(0x%x='%s', %d) => 0", string, string, value);
4360 return result;
4363 static char* expstrchr(char* string, int value)
4365 char* result=strchr(string, value);
4366 if(result)
4367 dbgprintf("strchr(0x%x='%s', %d) => 0x%x='%s'", string, string, value, result, result);
4368 else
4369 dbgprintf("strchr(0x%x='%s', %d) => 0", string, string, value);
4370 return result;
4372 static int expstrlen(char* str)
4374 int result=strlen(str);
4375 dbgprintf("strlen(0x%x='%s') => %d\n", str, str, result);
4376 return result;
4378 static char* expstrcpy(char* str1, const char* str2)
4380 char* result= strcpy(str1, str2);
4381 dbgprintf("strcpy(0x%x, 0x%x='%s') => %p\n", str1, str2, str2, result);
4382 return result;
4384 static char* expstrncpy(char* str1, const char* str2, size_t count)
4386 char* result= strncpy(str1, str2, count);
4387 dbgprintf("strncpy(0x%x, 0x%x='%s', %d) => %p\n", str1, str2, str2, count, result);
4388 return result;
4390 static int expstrcmp(const char* str1, const char* str2)
4392 int result=strcmp(str1, str2);
4393 dbgprintf("strcmp(0x%x='%s', 0x%x='%s') => %d\n", str1, str1, str2, str2, result);
4394 return result;
4396 static int expstrncmp(const char* str1, const char* str2,int x)
4398 int result=strncmp(str1, str2,x);
4399 dbgprintf("strcmp(0x%x='%s', 0x%x='%s') => %d\n", str1, str1, str2, str2, result);
4400 return result;
4402 static char* expstrcat(char* str1, const char* str2)
4404 char* result = strcat(str1, str2);
4405 dbgprintf("strcat(0x%x='%s', 0x%x='%s') => %p\n", str1, str1, str2, str2, result);
4406 return result;
4408 static char* exp_strdup(const char* str1)
4410 int l = strlen(str1);
4411 char* result = (char*) my_mreq(l + 1,0);
4412 if (result)
4413 strcpy(result, str1);
4414 dbgprintf("_strdup(0x%x='%s') => %p\n", str1, str1, result);
4415 return result;
4417 static int expisalnum(int c)
4419 int result= (int) isalnum(c);
4420 dbgprintf("isalnum(0x%x='%c' => %d\n", c, c, result);
4421 return result;
4423 static int expisspace(int c)
4425 int result= (int) isspace(c);
4426 dbgprintf("isspace(0x%x='%c' => %d\n", c, c, result);
4427 return result;
4429 static int expisalpha(int c)
4431 int result= (int) isalpha(c);
4432 dbgprintf("isalpha(0x%x='%c' => %d\n", c, c, result);
4433 return result;
4435 static int expisdigit(int c)
4437 int result= (int) isdigit(c);
4438 dbgprintf("isdigit(0x%x='%c' => %d\n", c, c, result);
4439 return result;
4441 static void* expmemmove(void* dest, void* src, int n)
4443 void* result = memmove(dest, src, n);
4444 dbgprintf("memmove(0x%x, 0x%x, %d) => %p\n", dest, src, n, result);
4445 return result;
4447 static int expmemcmp(void* dest, void* src, int n)
4449 int result = memcmp(dest, src, n);
4450 dbgprintf("memcmp(0x%x, 0x%x, %d) => %d\n", dest, src, n, result);
4451 return result;
4453 static void* expmemcpy(void* dest, void* src, int n)
4455 void *result = memcpy(dest, src, n);
4456 dbgprintf("memcpy(0x%x, 0x%x, %d) => %p\n", dest, src, n, result);
4457 return result;
4459 static void* expmemset(void* dest, int c, size_t n)
4461 void *result = memset(dest, c, n);
4462 dbgprintf("memset(0x%x, %d, %d) => %p\n", dest, c, n, result);
4463 return result;
4465 static time_t exptime(time_t* t)
4467 time_t result = time(t);
4468 dbgprintf("time(0x%x) => %d\n", t, result);
4469 return result;
4472 static int exprand(void)
4474 return rand();
4477 static void expsrand(int seed)
4479 srand(seed);
4482 #if 1
4484 // preferred compilation with -O2 -ffast-math !
4486 static double explog10(double x)
4488 /*printf("Log10 %f => %f 0x%Lx\n", x, log10(x), *((int64_t*)&x));*/
4489 return log10(x);
4492 static double expcos(double x)
4494 /*printf("Cos %f => %f 0x%Lx\n", x, cos(x), *((int64_t*)&x));*/
4495 return cos(x);
4498 #else
4500 static void explog10(void)
4502 __asm__ volatile
4504 "fldl 8(%esp) \n\t"
4505 "fldln2 \n\t"
4506 "fxch %st(1) \n\t"
4507 "fyl2x \n\t"
4511 static void expcos(void)
4513 __asm__ volatile
4515 "fldl 8(%esp) \n\t"
4516 "fcos \n\t"
4520 #endif
4522 // this seem to be the only how to make this function working properly
4523 // ok - I've spent tremendous amount of time (many many many hours
4524 // of debuging fixing & testing - it's almost unimaginable - kabi
4526 // _ftol - operated on the float value which is already on the FPU stack
4528 static void exp_ftol(void)
4530 __asm__ volatile
4532 "sub $12, %esp \n\t"
4533 "fstcw -2(%ebp) \n\t"
4534 "wait \n\t"
4535 "movw -2(%ebp), %ax \n\t"
4536 "orb $0x0C, %ah \n\t"
4537 "movw %ax, -4(%ebp) \n\t"
4538 "fldcw -4(%ebp) \n\t"
4539 "fistpl -12(%ebp) \n\t"
4540 "fldcw -2(%ebp) \n\t"
4541 "movl -12(%ebp), %eax \n\t"
4542 //Note: gcc 3.03 does not do the following op if it
4543 // knows that ebp=esp
4544 "movl %ebp, %esp \n\t"
4548 #define FPU_DOUBLES(var1,var2) double var1,var2; \
4549 __asm__ volatile( "fstpl %0;fwait" : "=m" (var2) : ); \
4550 __asm__ volatile( "fstpl %0;fwait" : "=m" (var1) : )
4552 static double exp_CIpow(void)
4554 FPU_DOUBLES(x,y);
4556 dbgprintf("_CIpow(%f, %f)\n", x, y);
4557 return pow(x, y);
4560 static double exppow(double x, double y)
4562 /*printf("Pow %f %f 0x%Lx 0x%Lx => %f\n", x, y, *((int64_t*)&x), *((int64_t*)&y), pow(x, y));*/
4563 return pow(x, y);
4566 static double expldexp(double x, int expo)
4568 /*printf("Cos %f => %f 0x%Lx\n", x, cos(x), *((int64_t*)&x));*/
4569 return ldexp(x, expo);
4572 static double expfrexp(double x, int* expo)
4574 /*printf("Cos %f => %f 0x%Lx\n", x, cos(x), *((int64_t*)&x));*/
4575 return frexp(x, expo);
4580 static int exp_stricmp(const char* s1, const char* s2)
4582 return strcasecmp(s1, s2);
4585 /* from declaration taken from Wine sources - this fountion seems to be
4586 * undocumented in any M$ doc */
4587 static int exp_setjmp3(void* jmpbuf, int x)
4589 //dbgprintf("!!!!UNIMPLEMENTED: setjmp3(%p, %d) => 0\n", jmpbuf, x);
4590 //return 0;
4591 __asm__ volatile
4593 //"mov 4(%%esp), %%edx \n\t"
4594 "mov (%%esp), %%eax \n\t"
4595 "mov %%eax, (%%edx) \n\t" // store ebp
4597 //"mov %%ebp, (%%edx) \n\t"
4598 "mov %%ebx, 4(%%edx) \n\t"
4599 "mov %%edi, 8(%%edx) \n\t"
4600 "mov %%esi, 12(%%edx) \n\t"
4601 "mov %%esp, 16(%%edx) \n\t"
4603 "mov 4(%%esp), %%eax \n\t"
4604 "mov %%eax, 20(%%edx) \n\t"
4606 "movl $0x56433230, 32(%%edx) \n\t" // VC20 ??
4607 "movl $0, 36(%%edx) \n\t"
4608 : // output
4609 : "d"(jmpbuf) // input
4610 : "eax"
4612 __asm__ volatile
4614 "mov %%fs:0, %%eax \n\t" // unsure
4615 "mov %%eax, 24(%%edx) \n\t"
4616 "cmp $0xffffffff, %%eax \n\t"
4617 "jnz l1 \n\t"
4618 "mov %%eax, 28(%%edx) \n\t"
4619 "l1: \n\t"
4622 : "eax"
4625 return 0;
4628 static DWORD WINAPI expGetCurrentProcessId(void)
4630 dbgprintf("GetCurrentProcessId(void) => %d\n", getpid());
4631 return getpid(); //(DWORD)NtCurrentTeb()->pid;
4635 typedef struct {
4636 UINT wPeriodMin;
4637 UINT wPeriodMax;
4638 } TIMECAPS, *LPTIMECAPS;
4640 static MMRESULT WINAPI exptimeGetDevCaps(LPTIMECAPS lpCaps, UINT wSize)
4642 dbgprintf("timeGetDevCaps(%p, %u) !\n", lpCaps, wSize);
4644 lpCaps->wPeriodMin = 1;
4645 lpCaps->wPeriodMax = 65535;
4646 return 0;
4649 static MMRESULT WINAPI exptimeBeginPeriod(UINT wPeriod)
4651 dbgprintf("timeBeginPeriod(%u) !\n", wPeriod);
4653 if (wPeriod < 1 || wPeriod > 65535) return 96+1; //TIMERR_NOCANDO;
4654 return 0;
4657 #ifdef CONFIG_QTX_CODECS
4658 static MMRESULT WINAPI exptimeEndPeriod(UINT wPeriod)
4660 dbgprintf("timeEndPeriod(%u) !\n", wPeriod);
4662 if (wPeriod < 1 || wPeriod > 65535) return 96+1; //TIMERR_NOCANDO;
4663 return 0;
4665 #endif
4667 static void WINAPI expGlobalMemoryStatus(
4668 LPMEMORYSTATUS lpmem
4670 static MEMORYSTATUS cached_memstatus;
4671 static int cache_lastchecked = 0;
4672 SYSTEM_INFO si;
4673 FILE *f;
4675 if (time(NULL)==cache_lastchecked) {
4676 memcpy(lpmem,&cached_memstatus,sizeof(MEMORYSTATUS));
4677 return;
4680 f = fopen( "/proc/meminfo", "r" );
4681 if (f)
4683 char buffer[256];
4684 int total, used, free, shared, buffers, cached;
4686 lpmem->dwLength = sizeof(MEMORYSTATUS);
4687 lpmem->dwTotalPhys = lpmem->dwAvailPhys = 0;
4688 lpmem->dwTotalPageFile = lpmem->dwAvailPageFile = 0;
4689 while (fgets( buffer, sizeof(buffer), f ))
4691 /* old style /proc/meminfo ... */
4692 if (sscanf( buffer, "Mem: %d %d %d %d %d %d", &total, &used, &free, &shared, &buffers, &cached ))
4694 lpmem->dwTotalPhys += total;
4695 lpmem->dwAvailPhys += free + buffers + cached;
4697 if (sscanf( buffer, "Swap: %d %d %d", &total, &used, &free ))
4699 lpmem->dwTotalPageFile += total;
4700 lpmem->dwAvailPageFile += free;
4703 /* new style /proc/meminfo ... */
4704 if (sscanf(buffer, "MemTotal: %d", &total))
4705 lpmem->dwTotalPhys = total*1024;
4706 if (sscanf(buffer, "MemFree: %d", &free))
4707 lpmem->dwAvailPhys = free*1024;
4708 if (sscanf(buffer, "SwapTotal: %d", &total))
4709 lpmem->dwTotalPageFile = total*1024;
4710 if (sscanf(buffer, "SwapFree: %d", &free))
4711 lpmem->dwAvailPageFile = free*1024;
4712 if (sscanf(buffer, "Buffers: %d", &buffers))
4713 lpmem->dwAvailPhys += buffers*1024;
4714 if (sscanf(buffer, "Cached: %d", &cached))
4715 lpmem->dwAvailPhys += cached*1024;
4717 fclose( f );
4719 if (lpmem->dwTotalPhys)
4721 DWORD TotalPhysical = lpmem->dwTotalPhys+lpmem->dwTotalPageFile;
4722 DWORD AvailPhysical = lpmem->dwAvailPhys+lpmem->dwAvailPageFile;
4723 lpmem->dwMemoryLoad = (TotalPhysical-AvailPhysical)
4724 / (TotalPhysical / 100);
4726 } else
4728 /* FIXME: should do something for other systems */
4729 lpmem->dwMemoryLoad = 0;
4730 lpmem->dwTotalPhys = 16*1024*1024;
4731 lpmem->dwAvailPhys = 16*1024*1024;
4732 lpmem->dwTotalPageFile = 16*1024*1024;
4733 lpmem->dwAvailPageFile = 16*1024*1024;
4735 expGetSystemInfo(&si);
4736 lpmem->dwTotalVirtual = (uint8_t *)si.lpMaximumApplicationAddress-(uint8_t *)si.lpMinimumApplicationAddress;
4737 /* FIXME: we should track down all the already allocated VM pages and substract them, for now arbitrarily remove 64KB so that it matches NT */
4738 lpmem->dwAvailVirtual = lpmem->dwTotalVirtual-64*1024;
4739 memcpy(&cached_memstatus,lpmem,sizeof(MEMORYSTATUS));
4740 cache_lastchecked = time(NULL);
4742 /* it appears some memory display programs want to divide by these values */
4743 if(lpmem->dwTotalPageFile==0)
4744 lpmem->dwTotalPageFile++;
4746 if(lpmem->dwAvailPageFile==0)
4747 lpmem->dwAvailPageFile++;
4750 static INT WINAPI expGetThreadPriority(HANDLE hthread)
4752 dbgprintf("GetThreadPriority(%p)\n",hthread);
4753 return 0;
4756 /**********************************************************************
4757 * SetThreadPriority [KERNEL32.@] Sets priority for thread.
4759 * RETURNS
4760 * Success: TRUE
4761 * Failure: FALSE
4763 static WIN_BOOL WINAPI expSetThreadPriority(
4764 HANDLE hthread, /* [in] Handle to thread */
4765 INT priority) /* [in] Thread priority level */
4767 dbgprintf("SetThreadPriority(%p,%d)\n",hthread,priority);
4768 return TRUE;
4771 static void WINAPI expTerminateProcess( DWORD process, DWORD status )
4773 printf("EXIT - process %ld code %ld\n", process, status);
4774 exit(status);
4777 static void WINAPI expExitProcess( DWORD status )
4779 printf("EXIT - code %ld\n",status);
4780 exit(status);
4783 static INT WINAPI expMessageBoxA(HWND hWnd, LPCSTR text, LPCSTR title, UINT type){
4784 printf("MSGBOX '%s' '%s' (%d)\n",text,title,type);
4785 #ifdef CONFIG_QTX_CODECS
4786 if (type == MB_ICONHAND && !strlen(text) && !strlen(title))
4787 return IDIGNORE;
4788 #endif
4789 return IDOK;
4792 /* these are needed for mss1 */
4795 * \brief this symbol is defined within exp_EH_prolog_dummy
4796 * \param dest jump target
4798 void exp_EH_prolog(void *dest);
4799 void exp_EH_prolog_dummy(void);
4800 //! just a dummy function that acts a container for the asm section
4801 void exp_EH_prolog_dummy(void) {
4802 __asm__ volatile (
4803 // take care, this "function" may not change flags or
4804 // registers besides eax (which is also why we can't use
4805 // exp_EH_prolog_dummy directly)
4806 MANGLE(exp_EH_prolog)": \n\t"
4807 "pop %eax \n\t"
4808 "push %ebp \n\t"
4809 "mov %esp, %ebp \n\t"
4810 "lea -12(%esp), %esp \n\t"
4811 "jmp *%eax \n\t"
4815 #include <netinet/in.h>
4816 static WINAPI inline unsigned long int exphtonl(unsigned long int hostlong)
4818 // dbgprintf("htonl(%x) => %x\n", hostlong, htonl(hostlong));
4819 return htonl(hostlong);
4822 static WINAPI inline unsigned long int expntohl(unsigned long int netlong)
4824 // dbgprintf("ntohl(%x) => %x\n", netlong, ntohl(netlong));
4825 return ntohl(netlong);
4828 static char* WINAPI expSysAllocStringLen(char *pch, unsigned cch)
4830 char *str;
4831 dbgprintf("SysAllocStringLen('%s', %d)\n", pch, cch);
4832 str = malloc(cch * 2 + sizeof(unsigned) + 2);
4833 *(unsigned *)str = cch;
4834 str += sizeof(unsigned);
4835 if (pch)
4836 memcpy(str, pch, cch * 2);
4837 str[cch * 2] = 0;
4838 str[cch * 2 + 1] = 0;
4839 return str;
4842 static void WINAPI expSysFreeString(char *str)
4844 if (str) {
4845 free(str - sizeof(unsigned));
4849 static void WINAPI expVariantInit(void* p)
4851 printf("InitCommonControls called!\n");
4852 return;
4855 static int WINAPI expRegisterClassA(const void/*WNDCLASSA*/ *wc)
4857 dbgprintf("RegisterClassA(%p) => random id\n", wc);
4858 return time(NULL); /* be precise ! */
4861 static int WINAPI expUnregisterClassA(const char *className, HINSTANCE hInstance)
4863 dbgprintf("UnregisterClassA(%s, %p) => 0\n", className, hInstance);
4864 return 0;
4867 #ifdef CONFIG_QTX_CODECS
4868 /* should be fixed bcs it's not fully strlen equivalent */
4869 static int expSysStringByteLen(void *str)
4871 dbgprintf("SysStringByteLen(%p) => %d\n", str, strlen(str));
4872 return strlen(str);
4875 static int expDirectDrawCreate(void)
4877 dbgprintf("DirectDrawCreate(...) => NULL\n");
4878 return 0;
4881 #if 1
4882 typedef struct tagPALETTEENTRY {
4883 BYTE peRed;
4884 BYTE peGreen;
4885 BYTE peBlue;
4886 BYTE peFlags;
4887 } PALETTEENTRY;
4889 typedef struct tagLOGPALETTE {
4890 WORD palVersion;
4891 WORD palNumEntries;
4892 PALETTEENTRY palPalEntry[1];
4893 } LOGPALETTE;
4895 static HPALETTE WINAPI expCreatePalette(CONST LOGPALETTE *lpgpl)
4897 HPALETTE test;
4898 int i;
4900 dbgprintf("CreatePalette(%x) => NULL\n", lpgpl);
4902 i = sizeof(LOGPALETTE)+((lpgpl->palNumEntries-1)*sizeof(PALETTEENTRY));
4903 test = (HPALETTE)malloc(i);
4904 memcpy((void *)test, lpgpl, i);
4906 return test;
4908 #else
4909 static int expCreatePalette(void)
4911 dbgprintf("CreatePalette(...) => NULL\n");
4912 return NULL;
4914 #endif
4916 static int WINAPI expGetClientRect(HWND win, RECT *r)
4918 dbgprintf("GetClientRect(0x%x, 0x%x) => 1\n", win, r);
4919 r->right = PSEUDO_SCREEN_WIDTH;
4920 r->left = 0;
4921 r->bottom = PSEUDO_SCREEN_HEIGHT;
4922 r->top = 0;
4923 return 1;
4926 #if 0
4927 typedef struct tagPOINT {
4928 LONG x;
4929 LONG y;
4930 } POINT, *PPOINT;
4931 #endif
4933 static int WINAPI expClientToScreen(HWND win, POINT *p)
4935 dbgprintf("ClientToScreen(0x%x, 0x%x = %d,%d) => 1\n", win, p, p->x, p->y);
4936 p->x = 0;
4937 p->y = 0;
4938 return 1;
4940 #endif
4942 /* for m3jpeg */
4943 static int WINAPI expSetThreadIdealProcessor(HANDLE thread, int proc)
4945 dbgprintf("SetThreadIdealProcessor(0x%x, %x) => 0\n", thread, proc);
4946 return 0;
4949 static int WINAPI expMessageBeep(int type)
4951 dbgprintf("MessageBeep(%d) => 1\n", type);
4952 return 1;
4955 static int WINAPI expDialogBoxParamA(void *inst, const char *name,
4956 HWND parent, void *dialog_func, void *init_param)
4958 dbgprintf("DialogBoxParamA(0x%x, 0x%x = %s, 0x%x, 0x%x, 0x%x) => 0x42424242\n",
4959 inst, name, name, parent, dialog_func, init_param);
4960 return 0x42424242;
4963 static void WINAPI expRegisterClipboardFormatA(const char *name) {
4964 dbgprintf("RegisterClipboardFormatA(0x%x = %s)\n", name, name);
4967 /* needed by imagepower mjpeg2k */
4968 static void *exprealloc(void *ptr, size_t size)
4970 dbgprintf("realloc(0x%x, %x)\n", ptr, size);
4971 if (!ptr)
4972 return my_mreq(size,0);
4973 else
4974 return my_realloc(ptr, size);
4977 /* Fake GetOpenFileNameA from comdlg32.dll for ViVD codec */
4978 static WIN_BOOL WINAPI expGetOpenFileNameA(/*LPOPENFILENAMEA*/ void* lpfn)
4980 return 1;
4983 static const char * WINAPI expPathFindExtensionA(const char *path) {
4984 const char *ext;
4985 if (!path)
4986 ext = NULL;
4987 else {
4988 ext = strrchr(path, '.');
4989 if (!ext)
4990 ext = &path[strlen(path)];
4992 dbgprintf("PathFindExtensionA(0x%x = %s) => 0x%x, %s\n", path, path, ext, ext);
4993 return ext;
4996 static const char * WINAPI expPathFindFileNameA(const char *path) {
4997 const char *name;
4998 if (!path || strlen(path) < 2)
4999 name = path;
5000 else {
5001 name = strrchr(path - 1, '\\');
5002 if (!name)
5003 name = path;
5005 dbgprintf("PathFindFileNameA(0x%x = %s) => 0x%x, %s\n", path, path, name, name);
5006 return name;
5009 static double expfloor(double x)
5011 dbgprintf("floor(%f)\n", x);
5012 return floor(x);
5015 #define FPU_DOUBLE(var) double var; \
5016 __asm__ volatile( "fstpl %0;fwait" : "=m" (var) : )
5018 static double exp_CIcos(void)
5020 FPU_DOUBLE(x);
5022 dbgprintf("_CIcos(%f)\n", x);
5023 return cos(x);
5026 static double exp_CIsin(void)
5028 FPU_DOUBLE(x);
5030 dbgprintf("_CIsin(%f)\n", x);
5031 return sin(x);
5034 static double exp_CIsqrt(void)
5036 FPU_DOUBLE(x);
5038 dbgprintf("_CIsqrt(%f)\n", x);
5039 return sqrt(x);
5042 /* Needed by rp8 sipr decoder */
5043 static LPSTR WINAPI expCharNextA(LPCSTR ptr)
5045 if (!*ptr) return (LPSTR)ptr;
5046 // dbgprintf("CharNextA(0x%08x), %s\n", ptr, ptr);
5047 return (LPSTR)(ptr + 1);
5050 // Fake implementation, needed by wvc1dmod.dll
5051 static int WINAPI expPropVariantClear(void *pvar)
5053 // dbgprintf("PropVariantclear (0x%08x), %s\n", ptr, ptr);
5054 return 1;
5057 // This define is fake, the real thing is a struct
5058 #define LPDEVMODEA void*
5059 // Dummy implementation, always return 1
5060 // Required for frapsvid.dll 2.8.1, return value does not matter
5061 static WIN_BOOL WINAPI expEnumDisplaySettingsA(LPCSTR name ,DWORD n,
5062 LPDEVMODEA devmode)
5064 dbgprintf("EnumDisplaySettingsA (dummy) => 1\n");
5065 return 1;
5068 // Fake implementation of _decode_pointer from msvcr80.dll, needed by sirenacm.dll
5069 // NOTE: undocumented function, probably the declaration is not right
5070 static int exp_decode_pointer(void *ptr)
5072 dbgprintf("_decode_pointer (0x%08x)\n", ptr);
5073 return 0;
5076 /* Fake implementation of sdt::_Lockit::_Lockit(void) from msvcp60.dll
5077 Needed by SCLS.DLL */
5078 static int exp_0Lockit_dummy(void)
5080 dbgprintf("0Lockit_dummy (??0_Lockit@std@@QAE@XZ)\n");
5081 return 0;
5084 /* Fake implementation of sdt::_Lockit::~_Lockit(void) from msvcp60.dll
5085 Needed by SCLS.DLL */
5086 static int exp_1Lockit_dummy(void)
5088 dbgprintf("1Lockit_dummy (??1_Lockit@std@@QAE@XZ)\n");
5089 return 0;
5092 static void * WINAPI expEncodePointer(void *p)
5094 return p;
5097 static void * WINAPI expDecodePointer(void *p)
5099 return p;
5102 static DWORD WINAPI expGetThreadLocale(void)
5104 return 0;
5108 * Very incomplete implementation, return an error for almost all cases.
5110 static DWORD WINAPI expGetLocaleInfoA(DWORD locale, DWORD lctype, char* lpLCData, int cchData)
5112 if (lctype == 0x1004) { // LOCALE_IDEFAULTANSICODEPAGE
5113 if (cchData < 4)
5114 return cchData == 0 ? 4 : 0;
5115 strcpy(lpLCData, "437");
5116 return 4;
5118 return 0;
5121 struct exports
5123 char name[64];
5124 int id;
5125 void* func;
5127 struct libs
5129 char name[64];
5130 int length;
5131 const struct exports* exps;
5134 #define FF(X,Y) \
5135 {#X, Y, (void*)exp##X},
5137 #define UNDEFF(X, Y) \
5138 {#X, Y, (void*)-1},
5140 static const struct exports exp_kernel32[]=
5142 FF(GetVolumeInformationA,-1)
5143 FF(GetDriveTypeA,-1)
5144 FF(GetLogicalDriveStringsA,-1)
5145 FF(IsBadWritePtr, 357)
5146 FF(IsBadReadPtr, 354)
5147 FF(IsBadStringPtrW, -1)
5148 FF(IsBadStringPtrA, -1)
5149 FF(DisableThreadLibraryCalls, -1)
5150 FF(CreateThread, -1)
5151 FF(ResumeThread, -1)
5152 FF(CreateEventA, -1)
5153 FF(CreateEventW, -1)
5154 FF(SetEvent, -1)
5155 FF(ResetEvent, -1)
5156 FF(WaitForSingleObject, -1)
5157 #ifdef CONFIG_QTX_CODECS
5158 FF(WaitForMultipleObjects, -1)
5159 FF(ExitThread, -1)
5160 #endif
5161 FF(GetSystemInfo, -1)
5162 FF(GetVersion, 332)
5163 FF(HeapCreate, 461)
5164 FF(HeapAlloc, -1)
5165 FF(HeapDestroy, -1)
5166 FF(HeapFree, -1)
5167 FF(HeapSize, -1)
5168 FF(HeapReAlloc,-1)
5169 FF(GetProcessHeap, -1)
5170 FF(VirtualAlloc, -1)
5171 FF(VirtualFree, -1)
5172 FF(InitializeCriticalSection, -1)
5173 FF(InitializeCriticalSectionAndSpinCount, -1)
5174 FF(EnterCriticalSection, -1)
5175 FF(LeaveCriticalSection, -1)
5176 FF(DeleteCriticalSection, -1)
5177 FF(TlsAlloc, -1)
5178 FF(TlsFree, -1)
5179 FF(TlsGetValue, -1)
5180 FF(TlsSetValue, -1)
5181 FF(GetCurrentThreadId, -1)
5182 FF(GetCurrentProcess, -1)
5183 FF(LocalAlloc, -1)
5184 FF(LocalReAlloc,-1)
5185 FF(LocalLock, -1)
5186 FF(GlobalAlloc, -1)
5187 FF(GlobalReAlloc, -1)
5188 FF(GlobalLock, -1)
5189 FF(GlobalSize, -1)
5190 FF(MultiByteToWideChar, 427)
5191 FF(WideCharToMultiByte, -1)
5192 FF(GetVersionExA, -1)
5193 FF(GetVersionExW, -1)
5194 FF(CreateSemaphoreA, -1)
5195 FF(CreateSemaphoreW, -1)
5196 FF(QueryPerformanceCounter, -1)
5197 FF(QueryPerformanceFrequency, -1)
5198 FF(LocalHandle, -1)
5199 FF(LocalUnlock, -1)
5200 FF(LocalFree, -1)
5201 FF(GlobalHandle, -1)
5202 FF(GlobalUnlock, -1)
5203 FF(GlobalFree, -1)
5204 FF(LoadResource, -1)
5205 FF(ReleaseSemaphore, -1)
5206 FF(CreateMutexA, -1)
5207 FF(CreateMutexW, -1)
5208 FF(ReleaseMutex, -1)
5209 FF(SignalObjectAndWait, -1)
5210 FF(FindResourceA, -1)
5211 FF(LockResource, -1)
5212 FF(FreeResource, -1)
5213 FF(SizeofResource, -1)
5214 FF(CloseHandle, -1)
5215 FF(GetCommandLineA, -1)
5216 FF(GetEnvironmentStringsW, -1)
5217 FF(FreeEnvironmentStringsW, -1)
5218 FF(FreeEnvironmentStringsA, -1)
5219 FF(GetEnvironmentStrings, -1)
5220 FF(GetStartupInfoA, -1)
5221 FF(GetStdHandle, -1)
5222 FF(GetFileType, -1)
5223 #ifdef CONFIG_QTX_CODECS
5224 FF(GetFileAttributesA, -1)
5225 #endif
5226 FF(SetHandleCount, -1)
5227 FF(GetACP, -1)
5228 FF(GetModuleFileNameA, -1)
5229 FF(SetUnhandledExceptionFilter, -1)
5230 FF(LoadLibraryA, -1)
5231 FF(GetProcAddress, -1)
5232 FF(FreeLibrary, -1)
5233 FF(CreateFileMappingA, -1)
5234 FF(OpenFileMappingA, -1)
5235 FF(MapViewOfFile, -1)
5236 FF(UnmapViewOfFile, -1)
5237 FF(Sleep, -1)
5238 FF(GetModuleHandleA, -1)
5239 FF(GetModuleHandleW, -1)
5240 FF(GetProfileIntA, -1)
5241 FF(GetPrivateProfileIntA, -1)
5242 FF(GetPrivateProfileStringA, -1)
5243 FF(WritePrivateProfileStringA, -1)
5244 FF(GetLastError, -1)
5245 FF(SetLastError, -1)
5246 FF(InterlockedIncrement, -1)
5247 FF(InterlockedDecrement, -1)
5248 FF(GetTimeZoneInformation, -1)
5249 FF(OutputDebugStringA, -1)
5250 FF(GetLocalTime, -1)
5251 FF(GetSystemTime, -1)
5252 FF(GetSystemTimeAsFileTime, -1)
5253 FF(GetEnvironmentVariableA, -1)
5254 FF(SetEnvironmentVariableA, -1)
5255 FF(RtlZeroMemory,-1)
5256 FF(RtlMoveMemory,-1)
5257 FF(RtlFillMemory,-1)
5258 FF(GetTempPathA,-1)
5259 FF(FindFirstFileA,-1)
5260 FF(FindNextFileA,-1)
5261 FF(FindClose,-1)
5262 FF(FileTimeToLocalFileTime,-1)
5263 FF(DeleteFileA,-1)
5264 FF(ReadFile,-1)
5265 FF(WriteFile,-1)
5266 FF(SetFilePointer,-1)
5267 FF(GetTempFileNameA,-1)
5268 FF(CreateFileA,-1)
5269 FF(GetSystemDirectoryA,-1)
5270 FF(GetWindowsDirectoryA,-1)
5271 #ifdef CONFIG_QTX_CODECS
5272 FF(GetCurrentDirectoryA,-1)
5273 FF(SetCurrentDirectoryA,-1)
5274 FF(CreateDirectoryA,-1)
5275 #endif
5276 FF(GetShortPathNameA,-1)
5277 FF(GetFullPathNameA,-1)
5278 FF(SetErrorMode, -1)
5279 FF(IsProcessorFeaturePresent, -1)
5280 FF(IsDebuggerPresent, -1)
5281 FF(GetProcessAffinityMask, -1)
5282 FF(InterlockedExchange, -1)
5283 FF(InterlockedCompareExchange, -1)
5284 FF(MulDiv, -1)
5285 FF(lstrcmpiA, -1)
5286 FF(lstrlenA, -1)
5287 FF(lstrcpyA, -1)
5288 FF(lstrcatA, -1)
5289 FF(lstrcpynA,-1)
5290 FF(GetProcessVersion,-1)
5291 FF(GetCurrentThread,-1)
5292 FF(GetOEMCP,-1)
5293 FF(GetCPInfo,-1)
5294 FF(DuplicateHandle,-1)
5295 FF(GetTickCount, -1)
5296 FF(SetThreadAffinityMask,-1)
5297 FF(GetCurrentProcessId,-1)
5298 FF(GlobalMemoryStatus,-1)
5299 FF(GetThreadPriority,-1)
5300 FF(SetThreadPriority,-1)
5301 FF(TerminateProcess,-1)
5302 FF(ExitProcess,-1)
5303 {"LoadLibraryExA", -1, (void*)&LoadLibraryExA},
5304 FF(SetThreadIdealProcessor,-1)
5305 FF(SetProcessAffinityMask, -1)
5306 FF(EncodePointer, -1)
5307 FF(DecodePointer, -1)
5308 FF(GetThreadLocale, -1)
5309 FF(GetLocaleInfoA, -1)
5310 UNDEFF(FlsAlloc, -1)
5311 UNDEFF(FlsGetValue, -1)
5312 UNDEFF(FlsSetValue, -1)
5313 UNDEFF(FlsFree, -1)
5316 static const struct exports exp_msvcrt[]={
5317 FF(malloc, -1)
5318 FF(_initterm, -1)
5319 FF(__dllonexit, -1)
5320 FF(_snprintf,-1)
5321 FF(free, -1)
5322 {"??3@YAXPAX@Z", -1, expdelete},
5323 {"??2@YAPAXI@Z", -1, expnew},
5324 {"_adjust_fdiv", -1, (void*)&_adjust_fdiv},
5325 {"_winver",-1,(void*)&_winver},
5326 FF(strrchr, -1)
5327 FF(strchr, -1)
5328 FF(strlen, -1)
5329 FF(strcpy, -1)
5330 FF(strncpy, -1)
5331 FF(wcscpy, -1)
5332 FF(strcmp, -1)
5333 FF(strncmp, -1)
5334 FF(strcat, -1)
5335 FF(_stricmp,-1)
5336 FF(_strdup,-1)
5337 FF(_setjmp3,-1)
5338 FF(isalnum, -1)
5339 FF(isspace, -1)
5340 FF(isalpha, -1)
5341 FF(isdigit, -1)
5342 FF(memmove, -1)
5343 FF(memcmp, -1)
5344 FF(memset, -1)
5345 FF(memcpy, -1)
5346 FF(time, -1)
5347 FF(rand, -1)
5348 FF(srand, -1)
5349 FF(log10, -1)
5350 FF(pow, -1)
5351 FF(cos, -1)
5352 FF(_ftol,-1)
5353 FF(_CIpow,-1)
5354 FF(_CIcos,-1)
5355 FF(_CIsin,-1)
5356 FF(_CIsqrt,-1)
5357 FF(ldexp,-1)
5358 FF(frexp,-1)
5359 FF(sprintf,-1)
5360 FF(sscanf,-1)
5361 FF(fopen,-1)
5362 FF(fprintf,-1)
5363 FF(printf,-1)
5364 FF(getenv,-1)
5365 FF(floor,-1)
5366 /* needed by frapsvid.dll */
5367 {"strstr",-1,(char *)&strstr},
5368 {"qsort",-1,(void *)&qsort},
5369 FF(_EH_prolog,-1)
5370 FF(calloc,-1)
5371 {"ceil",-1,(void*)&ceil},
5372 /* needed by imagepower mjpeg2k */
5373 {"clock",-1,(void*)&clock},
5374 {"memchr",-1,(void*)&memchr},
5375 {"vfprintf",-1,(void*)&vfprintf},
5376 // {"realloc",-1,(void*)&realloc},
5377 FF(realloc,-1)
5378 {"puts",-1,(void*)&puts}
5380 static const struct exports exp_winmm[]={
5381 FF(GetDriverModuleHandle, -1)
5382 FF(timeGetTime, -1)
5383 FF(DefDriverProc, -1)
5384 FF(OpenDriverA, -1)
5385 FF(OpenDriver, -1)
5386 FF(timeGetDevCaps, -1)
5387 FF(timeBeginPeriod, -1)
5388 #ifdef CONFIG_QTX_CODECS
5389 FF(timeEndPeriod, -1)
5390 FF(waveOutGetNumDevs, -1)
5391 #endif
5393 static const struct exports exp_psapi[]={
5394 FF(GetModuleBaseNameA, -1)
5396 static const struct exports exp_user32[]={
5397 FF(LoadIconA,-1)
5398 FF(LoadStringA, -1)
5399 FF(wsprintfA, -1)
5400 FF(GetDC, -1)
5401 FF(GetDesktopWindow, -1)
5402 FF(ReleaseDC, -1)
5403 FF(IsRectEmpty, -1)
5404 FF(LoadCursorA,-1)
5405 FF(SetCursor,-1)
5406 FF(GetCursorPos,-1)
5407 #ifdef CONFIG_QTX_CODECS
5408 FF(ShowCursor,-1)
5409 #endif
5410 FF(RegisterWindowMessageA,-1)
5411 FF(GetSystemMetrics,-1)
5412 FF(GetSysColor,-1)
5413 FF(GetSysColorBrush,-1)
5414 FF(GetWindowDC, -1)
5415 FF(DrawTextA, -1)
5416 FF(MessageBoxA, -1)
5417 FF(RegisterClassA, -1)
5418 FF(UnregisterClassA, -1)
5419 #ifdef CONFIG_QTX_CODECS
5420 FF(GetWindowRect, -1)
5421 FF(MonitorFromWindow, -1)
5422 FF(MonitorFromRect, -1)
5423 FF(MonitorFromPoint, -1)
5424 FF(EnumDisplayMonitors, -1)
5425 FF(GetMonitorInfoA, -1)
5426 FF(EnumDisplayDevicesA, -1)
5427 FF(GetClientRect, -1)
5428 FF(ClientToScreen, -1)
5429 FF(IsWindowVisible, -1)
5430 FF(GetActiveWindow, -1)
5431 FF(GetClassNameA, -1)
5432 FF(GetClassInfoA, -1)
5433 FF(GetWindowLongA, -1)
5434 FF(EnumWindows, -1)
5435 FF(GetWindowThreadProcessId, -1)
5436 FF(CreateWindowExA, -1)
5437 #endif
5438 FF(MessageBeep, -1)
5439 FF(DialogBoxParamA, -1)
5440 FF(RegisterClipboardFormatA, -1)
5441 FF(CharNextA, -1)
5442 FF(EnumDisplaySettingsA, -1)
5444 static const struct exports exp_advapi32[]={
5445 FF(RegCloseKey, -1)
5446 FF(RegCreateKeyA, -1)
5447 FF(RegCreateKeyExA, -1)
5448 FF(RegEnumKeyExA, -1)
5449 FF(RegEnumValueA, -1)
5450 FF(RegOpenKeyA, -1)
5451 FF(RegOpenKeyExA, -1)
5452 FF(RegQueryValueExA, -1)
5453 FF(RegSetValueExA, -1)
5454 FF(RegQueryInfoKeyA, -1)
5456 static const struct exports exp_gdi32[]={
5457 FF(CreateCompatibleDC, -1)
5458 FF(CreateFontA, -1)
5459 FF(DeleteDC, -1)
5460 FF(DeleteObject, -1)
5461 FF(GetDeviceCaps, -1)
5462 FF(GetSystemPaletteEntries, -1)
5463 #ifdef CONFIG_QTX_CODECS
5464 FF(CreatePalette, -1)
5465 FF(GetObjectA, -1)
5466 FF(CreateRectRgn, -1)
5467 #endif
5469 static const struct exports exp_version[]={
5470 FF(GetFileVersionInfoSizeA, -1)
5472 static const struct exports exp_ole32[]={
5473 FF(CoCreateFreeThreadedMarshaler,-1)
5474 FF(CoCreateInstance, -1)
5475 FF(CoInitialize, -1)
5476 FF(CoInitializeEx, -1)
5477 FF(CoUninitialize, -1)
5478 FF(CoTaskMemAlloc, -1)
5479 FF(CoTaskMemFree, -1)
5480 FF(StringFromGUID2, -1)
5481 FF(PropVariantClear, -1)
5483 // do we really need crtdll ???
5484 // msvcrt is the correct place probably...
5485 static const struct exports exp_crtdll[]={
5486 FF(memcpy, -1)
5487 FF(wcscpy, -1)
5489 static const struct exports exp_comctl32[]={
5490 FF(StringFromGUID2, -1)
5491 FF(InitCommonControls, 17)
5492 #ifdef CONFIG_QTX_CODECS
5493 FF(CreateUpDownControl, 16)
5494 #endif
5496 static const struct exports exp_wsock32[]={
5497 FF(htonl,8)
5498 FF(ntohl,14)
5500 static const struct exports exp_msdmo[]={
5501 FF(memcpy, -1) // just test
5502 FF(MoCopyMediaType, -1)
5503 FF(MoCreateMediaType, -1)
5504 FF(MoDeleteMediaType, -1)
5505 FF(MoDuplicateMediaType, -1)
5506 FF(MoFreeMediaType, -1)
5507 FF(MoInitMediaType, -1)
5509 static const struct exports exp_oleaut32[]={
5510 FF(SysAllocStringLen, 4)
5511 FF(SysFreeString, 6)
5512 FF(VariantInit, 8)
5513 #ifdef CONFIG_QTX_CODECS
5514 FF(SysStringByteLen, 149)
5515 #endif
5518 /* realplayer8:
5519 DLL Name: PNCRT.dll
5520 vma: Hint/Ord Member-Name
5521 22ff4 615 free
5522 2302e 250 _ftol
5523 22fea 666 malloc
5524 2303e 609 fprintf
5525 2305e 167 _adjust_fdiv
5526 23052 280 _initterm
5528 22ffc 176 _beginthreadex
5529 23036 284 _iob
5530 2300e 85 __CxxFrameHandler
5531 23022 411 _purecall
5533 #ifdef REALPLAYER
5534 static const struct exports exp_pncrt[]={
5535 FF(malloc, -1) // just test
5536 FF(free, -1) // just test
5537 FF(fprintf, -1) // just test
5538 {"_adjust_fdiv", -1, (void*)&_adjust_fdiv},
5539 FF(_ftol,-1)
5540 FF(_initterm, -1)
5541 {"??3@YAXPAX@Z", -1, expdelete},
5542 {"??2@YAPAXI@Z", -1, expnew},
5543 FF(__dllonexit, -1)
5544 FF(strncpy, -1)
5545 FF(_CIpow,-1)
5546 FF(calloc,-1)
5547 FF(memmove, -1)
5548 FF(ldexp, -1)
5549 FF(frexp, -1)
5551 #endif
5553 #ifdef CONFIG_QTX_CODECS
5554 static const struct exports exp_ddraw[]={
5555 FF(DirectDrawCreate, -1)
5557 #endif
5559 static const struct exports exp_comdlg32[]={
5560 FF(GetOpenFileNameA, -1)
5563 static const struct exports exp_shlwapi[]={
5564 FF(PathFindExtensionA, -1)
5565 FF(PathFindFileNameA, -1)
5568 static const struct exports exp_msvcr80[]={
5569 FF(_CIpow,-1)
5570 FF(_CIsin,-1)
5571 FF(_CIcos,-1)
5572 FF(_CIsqrt,-1)
5573 FF(memset,-1)
5574 FF(_initterm_e, -1)
5575 FF(_initterm, -1)
5576 FF(_decode_pointer, -1)
5577 /* needed by KGV1-VFW.dll */
5578 {"??2@YAPAXI@Z", -1, expnew},
5579 {"??3@YAXPAX@Z", -1, expdelete}
5582 static const struct exports exp_msvcp60[]={
5583 {"??0_Lockit@std@@QAE@XZ", -1, exp_0Lockit_dummy},
5584 {"??1_Lockit@std@@QAE@XZ", -1, exp_1Lockit_dummy}
5587 static const struct exports exp_msvcr100[]={
5588 FF(memcpy, -1)
5589 FF(memset, -1)
5590 FF(_initterm_e, -1)
5591 FF(_initterm, -1)
5592 {"??2@YAPAXI@Z", -1, expnew},
5593 {"??3@YAXPAX@Z", -1, expdelete}
5596 #define LL(X) \
5597 {#X".dll", sizeof(exp_##X)/sizeof(struct exports), exp_##X},
5599 static const struct libs libraries[]={
5600 LL(kernel32)
5601 LL(msvcrt)
5602 LL(winmm)
5603 LL(psapi)
5604 LL(user32)
5605 LL(advapi32)
5606 LL(gdi32)
5607 LL(version)
5608 LL(ole32)
5609 LL(oleaut32)
5610 LL(crtdll)
5611 LL(comctl32)
5612 LL(wsock32)
5613 LL(msdmo)
5614 #ifdef REALPLAYER
5615 LL(pncrt)
5616 #endif
5617 #ifdef CONFIG_QTX_CODECS
5618 LL(ddraw)
5619 #endif
5620 LL(comdlg32)
5621 LL(shlwapi)
5622 LL(msvcr80)
5623 LL(msvcp60)
5624 LL(msvcr100)
5627 static WIN_BOOL WINAPI ext_stubs(void)
5629 // NOTE! these magic values will be replaced at runtime, make sure
5630 // add_stub can still find them if you change them.
5631 volatile int idx = 0x0deadabc;
5632 // make sure gcc does not do eip-relative call or something like that
5633 void (* volatile my_printf)(char *, char *) = (void *)0xdeadfbcd;
5634 my_printf("Called unk_%s\n", export_names[idx]);
5635 return 0;
5638 #define MAX_STUB_SIZE 0x60
5639 #define MAX_NUM_STUBS 200
5640 static int pos=0;
5641 static char *extcode = NULL;
5643 static void* add_stub(void)
5645 int i;
5646 int found = 0;
5647 // generated code in runtime!
5648 char* answ;
5649 if (!extcode)
5650 extcode = mmap_anon(NULL, MAX_NUM_STUBS * MAX_STUB_SIZE,
5651 PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE, 0);
5652 answ = extcode + pos * MAX_STUB_SIZE;
5653 if (pos >= MAX_NUM_STUBS) {
5654 printf("too many stubs, expect crash\n");
5655 return NULL;
5657 memcpy(answ, ext_stubs, MAX_STUB_SIZE);
5658 for (i = 0; i < MAX_STUB_SIZE - 3; i++) {
5659 int *magic = (int *)(answ + i);
5660 if (*magic == 0x0deadabc) {
5661 *magic = pos;
5662 found |= 1;
5664 if (*magic == 0xdeadfbcd) {
5665 *magic = (intptr_t)printf;
5666 found |= 2;
5669 if (found != 3) {
5670 printf("magic code not found in ext_subs, expect crash\n");
5671 return NULL;
5673 pos++;
5674 return (void*)answ;
5677 void* LookupExternal(const char* library, int ordinal)
5679 int i,j;
5680 if(library==0)
5682 printf("ERROR: library=0\n");
5683 return (void*)ext_unknown;
5685 // printf("%x %x\n", &unk_exp1, &unk_exp2);
5687 dbgprintf("External func %s:%d\n", library, ordinal);
5689 for(i=0; i<sizeof(libraries)/sizeof(struct libs); i++)
5691 if(strcasecmp(library, libraries[i].name))
5692 continue;
5693 for(j=0; j<libraries[i].length; j++)
5695 if(ordinal!=libraries[i].exps[j].id)
5696 continue;
5697 //printf("Hit: 0x%p\n", libraries[i].exps[j].func);
5698 return libraries[i].exps[j].func;
5702 #ifndef LOADLIB_TRY_NATIVE
5703 /* hack for truespeech and vssh264*/
5704 if (!strcmp(library, "tsd32.dll") || !strcmp(library,"vssh264dec.dll") || !strcmp(library,"LCMW2.dll") || !strcmp(library,"VDODEC32.dll"))
5705 #endif
5706 /* ok, this is a hack, and a big memory leak. should be fixed. - alex */
5708 int hand;
5709 WINE_MODREF *wm;
5710 void *func;
5712 hand = LoadLibraryA(library);
5713 if (!hand)
5714 goto no_dll;
5715 wm = MODULE32_LookupHMODULE(hand);
5716 if (!wm)
5718 FreeLibrary(hand);
5719 goto no_dll;
5721 func = PE_FindExportedFunction(wm, (LPCSTR) ordinal, 0);
5722 if (!func)
5724 printf("No such ordinal in external dll\n");
5725 FreeLibrary((int)hand);
5726 goto no_dll;
5729 printf("External dll loaded (offset: 0x%x, func: %p)\n",
5730 hand, func);
5731 return func;
5734 no_dll:
5735 if(pos>150)return 0;
5736 snprintf(export_names[pos], sizeof(export_names[pos]), "%s:%d", library, ordinal);
5737 return add_stub();
5740 void* LookupExternalByName(const char* library, const char* name)
5742 int i,j;
5743 // return (void*)ext_unknown;
5744 if(library==0)
5746 printf("ERROR: library=0\n");
5747 return (void*)ext_unknown;
5749 if((unsigned long)name<=0xffff)
5751 return LookupExternal(library, (int)name);
5753 dbgprintf("External func %s:%s\n", library, name);
5754 for(i=0; i<sizeof(libraries)/sizeof(struct libs); i++)
5756 if(strcasecmp(library, libraries[i].name))
5757 continue;
5758 for(j=0; j<libraries[i].length; j++)
5760 if(strcmp(name, libraries[i].exps[j].name))
5761 continue;
5762 if((unsigned int)(libraries[i].exps[j].func) == -1)
5763 return NULL; //undefined func
5764 // printf("Hit: 0x%08X\n", libraries[i].exps[j].func);
5765 return libraries[i].exps[j].func;
5769 #ifndef LOADLIB_TRY_NATIVE
5770 /* hack for vss h264 */
5771 if (!strcmp(library,"vssh264core.dll") || !strcmp(library,"3ivx.dll"))
5772 #endif
5773 /* ok, this is a hack, and a big memory leak. should be fixed. - alex */
5775 int hand;
5776 WINE_MODREF *wm;
5777 void *func;
5779 hand = LoadLibraryA(library);
5780 if (!hand)
5781 goto no_dll_byname;
5782 wm = MODULE32_LookupHMODULE(hand);
5783 if (!wm)
5785 FreeLibrary(hand);
5786 goto no_dll_byname;
5788 func = PE_FindExportedFunction(wm, name, 0);
5789 if (!func)
5791 printf("No such name in external dll\n");
5792 FreeLibrary((int)hand);
5793 goto no_dll_byname;
5796 printf("External dll loaded (offset: 0x%x, func: %p)\n",
5797 hand, func);
5798 return func;
5801 no_dll_byname:
5802 if(pos>150)return 0;// to many symbols
5803 snprintf(export_names[pos], sizeof(export_names[pos]), "%s", name);
5804 return add_stub();
5807 void my_garbagecollection(void)
5809 #ifdef GARBAGE
5810 int unfree = 0, unfreecnt = 0;
5812 int max_fatal = 8;
5813 free_registry();
5814 while (last_alloc)
5816 alloc_header* mem = last_alloc + 1;
5817 unfree += my_size(mem);
5818 unfreecnt++;
5819 if (my_release(mem) != 0)
5820 // avoid endless loop when memory is trashed
5821 if (--max_fatal < 0)
5822 break;
5824 dbgprintf("Total Unfree %d bytes cnt %d [%p,%d]\n",unfree, unfreecnt, last_alloc, alccnt);
5825 #endif
5826 g_tls = NULL;
5827 pthread_mutex_lock(&list_lock);
5828 list = NULL;
5829 pthread_mutex_unlock(&list_lock);