Second attempt to fix compilation of dvdread (I don't really like this but it might...
[vlc/asuraparaju-public.git] / libs / loader / win32.c
blob7f4acf121296f902d385b21ad02325ddfe536df4
1 /*
2 * $Id$
4 * Originally distributed under LPGL 2.1 (or later) by the Wine project.
6 * Modified for use with MPlayer, detailed CVS changelog at
7 * http://www.mplayerhq.hu/cgi-bin/cvsweb.cgi/main/
9 * File now distributed as part of VLC media player with no modifications.
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
26 /***********************************************************
28 Win32 emulation code. Functions that emulate
29 responses from corresponding Win32 API calls.
30 Since we are not going to be able to load
31 virtually any DLL, we can only implement this
32 much, adding needed functions with each new codec.
34 Basic principle of implementation: it's not good
35 for DLL to know too much about its environment.
37 ************************************************************/
39 #include "config.h"
41 #ifdef MPLAYER
42 #ifdef USE_QTX_CODECS
43 #define QTX
44 #endif
45 #define REALPLAYER
46 //#define LOADLIB_TRY_NATIVE
47 #endif
49 #ifdef QTX
50 #define PSEUDO_SCREEN_WIDTH /*640*/800
51 #define PSEUDO_SCREEN_HEIGHT /*480*/600
52 #endif
54 #include "wine/winbase.h"
55 #include "wine/winreg.h"
56 #include "wine/winnt.h"
57 #include "wine/winerror.h"
58 #include "wine/debugtools.h"
59 #include "wine/module.h"
60 #include "wine/winuser.h"
62 #include <stdio.h>
63 #include "win32.h"
65 #include "registry.h"
66 #include "loader.h"
67 #include "com.h"
68 #include "ext.h"
70 #include <stdlib.h>
71 #include <assert.h>
72 #include <stdarg.h>
73 #include <ctype.h>
74 #include <pthread.h>
75 #include <errno.h>
76 #ifdef HAVE_MALLOC_H
77 #include <malloc.h>
78 #endif
79 #include <time.h>
80 #include <math.h>
81 #include <unistd.h>
82 #include <fcntl.h>
83 #include <sys/types.h>
84 #include <dirent.h>
85 #include <sys/time.h>
86 #include <sys/timeb.h>
87 #ifdef HAVE_KSTAT
88 #include <kstat.h>
89 #endif
91 #if HAVE_VSSCANF
92 int vsscanf( const char *str, const char *format, va_list ap);
93 #else
94 /* system has no vsscanf. try to provide one */
95 static int vsscanf( const char *str, const char *format, va_list ap)
97 long p1 = va_arg(ap, long);
98 long p2 = va_arg(ap, long);
99 long p3 = va_arg(ap, long);
100 long p4 = va_arg(ap, long);
101 long p5 = va_arg(ap, long);
102 return sscanf(str, format, p1, p2, p3, p4, p5);
104 #endif
106 static char* def_path = WIN32_PATH;
108 static void do_cpuid(unsigned int ax, unsigned int *regs)
110 __asm__ __volatile__
112 "pushl %%ebx; pushl %%ecx; pushl %%edx;"
113 ".byte 0x0f, 0xa2;"
114 "movl %%eax, (%2);"
115 "movl %%ebx, 4(%2);"
116 "movl %%ecx, 8(%2);"
117 "movl %%edx, 12(%2);"
118 "popl %%edx; popl %%ecx; popl %%ebx;"
119 : "=a" (ax)
120 : "0" (ax), "S" (regs)
123 static unsigned int c_localcount_tsc()
125 int a;
126 __asm__ __volatile__
128 "rdtsc\n\t"
129 :"=a"(a)
131 :"edx"
133 return a;
135 static void c_longcount_tsc(long long* z)
137 __asm__ __volatile__
139 "pushl %%ebx\n\t"
140 "movl %%eax, %%ebx\n\t"
141 "rdtsc\n\t"
142 "movl %%eax, 0(%%ebx)\n\t"
143 "movl %%edx, 4(%%ebx)\n\t"
144 "popl %%ebx\n\t"
145 ::"a"(z)
146 :"edx"
149 static unsigned int c_localcount_notsc()
151 struct timeval tv;
152 unsigned limit=~0;
153 limit/=1000000;
154 gettimeofday(&tv, 0);
155 return limit*tv.tv_usec;
157 static void c_longcount_notsc(long long* z)
159 struct timeval tv;
160 unsigned long long result;
161 unsigned limit=~0;
162 if(!z)return;
163 limit/=1000000;
164 gettimeofday(&tv, 0);
165 result=tv.tv_sec;
166 result<<=32;
167 result+=limit*tv.tv_usec;
168 *z=result;
170 static unsigned int localcount_stub(void);
171 static void longcount_stub(long long*);
172 static unsigned int (*localcount)()=localcount_stub;
173 static void (*longcount)(long long*)=longcount_stub;
175 static pthread_mutex_t memmut;
177 static unsigned int localcount_stub(void)
179 unsigned int regs[4];
180 do_cpuid(1, regs);
181 if ((regs[3] & 0x00000010) != 0)
183 localcount=c_localcount_tsc;
184 longcount=c_longcount_tsc;
186 else
188 localcount=c_localcount_notsc;
189 longcount=c_longcount_notsc;
191 return localcount();
193 static void longcount_stub(long long* z)
195 unsigned int regs[4];
196 do_cpuid(1, regs);
197 if ((regs[3] & 0x00000010) != 0)
199 localcount=c_localcount_tsc;
200 longcount=c_longcount_tsc;
202 else
204 localcount=c_localcount_notsc;
205 longcount=c_longcount_notsc;
207 longcount(z);
210 #ifdef MPLAYER
211 #include "../mp_msg.h"
212 #endif
213 int LOADER_DEBUG=1; // active only if compiled with -DDETAILED_OUT
214 //#define DETAILED_OUT
215 static inline void dbgprintf(const char* fmt, ...)
217 #ifdef DETAILED_OUT
218 if(LOADER_DEBUG)
220 FILE* f;
221 va_list va;
222 va_start(va, fmt);
223 f=fopen("./log", "a");
224 vprintf(fmt, va);
225 fflush(stdout);
226 if(f)
228 vfprintf(f, fmt, va);
229 fsync(fileno(f));
230 fclose(f);
232 va_end(va);
234 #endif
235 #ifdef MPLAYER
236 if (verbose > 2)
238 va_list va;
240 va_start(va, fmt);
241 vprintf(fmt, va);
242 // mp_dbg(MSGT_WIN32, MSGL_DBG3, fmt, va);
243 va_end(va);
245 fflush(stdout);
246 #endif
250 char export_names[300][32]={
251 "name1",
252 //"name2",
253 //"name3"
255 //#define min(x,y) ((x)<(y)?(x):(y))
257 void destroy_event(void* event);
259 struct th_list_t;
260 typedef struct th_list_t{
261 int id;
262 void* thread;
263 struct th_list_t* next;
264 struct th_list_t* prev;
265 } th_list;
268 // have to be cleared by GARBAGE COLLECTOR
269 static unsigned char* heap=NULL;
270 static int heap_counter=0;
271 static tls_t* g_tls=NULL;
272 static th_list* list=NULL;
274 static void test_heap(void)
276 int offset=0;
277 if(heap==0)
278 return;
279 while(offset<heap_counter)
281 if(*(int*)(heap+offset)!=0x433476)
283 printf("Heap corruption at address %d\n", offset);
284 return;
286 offset+=8+*(int*)(heap+offset+4);
288 for(;offset<min(offset+1000, 20000000); offset++)
289 if(heap[offset]!=0xCC)
291 printf("Free heap corruption at address %d\n", offset);
294 #undef MEMORY_DEBUG
296 #ifdef MEMORY_DEBUG
298 static void* my_mreq(int size, int to_zero)
300 static int test=0;
301 test++;
302 if(test%10==0)printf("Memory: %d bytes allocated\n", heap_counter);
303 // test_heap();
304 if(heap==NULL)
306 heap=malloc(20000000);
307 memset(heap, 0xCC,20000000);
309 if(heap==0)
311 printf("No enough memory\n");
312 return 0;
314 if(heap_counter+size>20000000)
316 printf("No enough memory\n");
317 return 0;
319 *(int*)(heap+heap_counter)=0x433476;
320 heap_counter+=4;
321 *(int*)(heap+heap_counter)=size;
322 heap_counter+=4;
323 printf("Allocated %d bytes of memory: sys %d, user %d-%d\n", size, heap_counter-8, heap_counter, heap_counter+size);
324 if(to_zero)
325 memset(heap+heap_counter, 0, size);
326 else
327 memset(heap+heap_counter, 0xcc, size); // make crash reproducable
328 heap_counter+=size;
329 return heap+heap_counter-size;
331 static int my_release(char* memory)
333 // test_heap();
334 if(memory==NULL)
336 printf("ERROR: free(0)\n");
337 return 0;
339 if(*(int*)(memory-8)!=0x433476)
341 printf("MEMORY CORRUPTION !!!!!!!!!!!!!!!!!!!\n");
342 return 0;
344 printf("Freed %d bytes of memory\n", *(int*)(memory-4));
345 // memset(memory-8, *(int*)(memory-4), 0xCC);
346 return 0;
349 #else
350 #define GARBAGE
351 typedef struct alloc_header_t alloc_header;
352 struct alloc_header_t
354 // let's keep allocated data 16 byte aligned
355 alloc_header* prev;
356 alloc_header* next;
357 long deadbeef;
358 long size;
359 long type;
360 long reserved1;
361 long reserved2;
362 long reserved3;
365 #ifdef GARBAGE
366 static alloc_header* last_alloc = NULL;
367 static int alccnt = 0;
368 #endif
370 #define AREATYPE_CLIENT 0
371 #define AREATYPE_EVENT 1
372 #define AREATYPE_MUTEX 2
373 #define AREATYPE_COND 3
374 #define AREATYPE_CRITSECT 4
376 /* -- critical sections -- */
377 struct CRITSECT
379 pthread_t id;
380 pthread_mutex_t mutex;
381 int locked;
382 long deadbeef;
385 void* mreq_private(int size, int to_zero, int type);
386 void* mreq_private(int size, int to_zero, int type)
388 int nsize = size + sizeof(alloc_header);
389 alloc_header* header = (alloc_header* ) malloc(nsize);
390 if (!header)
391 return 0;
392 if (to_zero)
393 memset(header, 0, nsize);
394 #ifdef GARBAGE
395 if (!last_alloc)
397 pthread_mutex_init(&memmut, NULL);
398 pthread_mutex_lock(&memmut);
400 else
402 pthread_mutex_lock(&memmut);
403 last_alloc->next = header; /* set next */
406 header->prev = last_alloc;
407 header->next = 0;
408 last_alloc = header;
409 alccnt++;
410 pthread_mutex_unlock(&memmut);
411 #endif
412 header->deadbeef = 0xdeadbeef;
413 header->size = size;
414 header->type = type;
416 //if (alccnt < 40000) printf("MY_REQ: %p\t%d t:%d (cnt:%d)\n", header, size, type, alccnt);
417 return header + 1;
420 static int my_release(void* memory)
422 alloc_header* header = (alloc_header*) memory - 1;
423 #ifdef GARBAGE
424 alloc_header* prevmem;
425 alloc_header* nextmem;
427 if (memory == 0)
428 return 0;
430 if (header->deadbeef != (long) 0xdeadbeef)
432 dbgprintf("FATAL releasing corrupted memory! %p 0x%lx (%d)\n", header, header->deadbeef, alccnt);
433 return 0;
436 pthread_mutex_lock(&memmut);
438 switch(header->type)
440 case AREATYPE_EVENT:
441 destroy_event(memory);
442 break;
443 case AREATYPE_COND:
444 pthread_cond_destroy((pthread_cond_t*)memory);
445 break;
446 case AREATYPE_MUTEX:
447 pthread_mutex_destroy((pthread_mutex_t*)memory);
448 break;
449 case AREATYPE_CRITSECT:
450 pthread_mutex_destroy(&((struct CRITSECT*)memory)->mutex);
451 break;
452 default:
453 //memset(memory, 0xcc, header->size);
457 header->deadbeef = 0;
458 prevmem = header->prev;
459 nextmem = header->next;
461 if (prevmem)
462 prevmem->next = nextmem;
463 if (nextmem)
464 nextmem->prev = prevmem;
466 if (header == last_alloc)
467 last_alloc = prevmem;
469 alccnt--;
471 if (last_alloc)
472 pthread_mutex_unlock(&memmut);
473 else
474 pthread_mutex_destroy(&memmut);
476 //if (alccnt < 40000) printf("MY_RELEASE: %p\t%ld (%d)\n", header, header->size, alccnt);
477 #else
478 if (memory == 0)
479 return 0;
480 #endif
481 //memset(header + 1, 0xcc, header->size);
482 free(header);
483 return 0;
485 #endif
487 static inline void* my_mreq(int size, int to_zero)
489 return mreq_private(size, to_zero, AREATYPE_CLIENT);
492 static int my_size(void* memory)
494 if(!memory) return 0;
495 return ((alloc_header*)memory)[-1].size;
498 static void* my_realloc(void* memory, int size)
500 void *ans = memory;
501 int osize;
502 if (memory == NULL)
503 return my_mreq(size, 0);
504 osize = my_size(memory);
505 if (osize < size)
507 ans = my_mreq(size, 0);
508 memcpy(ans, memory, osize);
509 my_release(memory);
511 return ans;
516 * WINE API - native implementation for several win32 libraries
520 static int WINAPI ext_unknown()
522 printf("Unknown func called\n");
523 return 0;
526 static int WINAPI expGetVolumeInformationA( const char *root, char *label,
527 unsigned int label_len, unsigned int *serial,
528 unsigned int *filename_len,unsigned int *flags,
529 char *fsname, unsigned int fsname_len )
531 dbgprintf("GetVolumeInformationA( %s, 0x%x, %ld, 0x%x, 0x%x, 0x%x, 0x%x, %ld) => 1\n",
532 root,label,label_len,serial,filename_len,flags,fsname,fsname_len);
533 //hack Do not return any real data - do nothing
534 return 1;
537 static unsigned int WINAPI expGetDriveTypeA( const char *root )
539 dbgprintf("GetDriveTypeA( %s ) => %d\n",root,DRIVE_FIXED);
540 // hack return as Fixed Drive Type
541 return DRIVE_FIXED;
544 static unsigned int WINAPI expGetLogicalDriveStringsA( unsigned int len, char *buffer )
546 dbgprintf("GetLogicalDriveStringsA(%d, 0x%x) => 4\n",len,buffer);
547 // hack only have one drive c:\ in this hack
548 *buffer++='c';
549 *buffer++=':';
550 *buffer++='\\';
551 *buffer++='\0';
552 *buffer= '\0';
553 return 4; // 1 drive * 4 bytes (includes null)
557 static int WINAPI expIsBadWritePtr(void* ptr, unsigned int count)
559 int result = (count == 0 || ptr != 0) ? 0 : 1;
560 dbgprintf("IsBadWritePtr(0x%x, 0x%x) => %d\n", ptr, count, result);
561 return result;
563 static int WINAPI expIsBadReadPtr(void* ptr, unsigned int count)
565 int result = (count == 0 || ptr != 0) ? 0 : 1;
566 dbgprintf("IsBadReadPtr(0x%x, 0x%x) => %d\n", ptr, count, result);
567 return result;
569 static int WINAPI expDisableThreadLibraryCalls(int module)
571 dbgprintf("DisableThreadLibraryCalls(0x%x) => 0\n", module);
572 return 0;
575 static HMODULE WINAPI expGetDriverModuleHandle(DRVR* pdrv)
577 HMODULE result;
578 if (pdrv==NULL)
579 result=0;
580 else
581 result=pdrv->hDriverModule;
582 dbgprintf("GetDriverModuleHandle(%p) => %p\n", pdrv, result);
583 return result;
586 #define MODULE_HANDLE_kernel32 ((HMODULE)0x120)
587 #define MODULE_HANDLE_user32 ((HMODULE)0x121)
588 #ifdef QTX
589 #define MODULE_HANDLE_wininet ((HMODULE)0x122)
590 #define MODULE_HANDLE_ddraw ((HMODULE)0x123)
591 #define MODULE_HANDLE_advapi32 ((HMODULE)0x124)
592 #endif
593 #define MODULE_HANDLE_comdlg32 ((HMODULE)0x125)
594 #define MODULE_HANDLE_msvcrt ((HMODULE)0x126)
595 #define MODULE_HANDLE_ole32 ((HMODULE)0x127)
596 #define MODULE_HANDLE_winmm ((HMODULE)0x128)
598 static HMODULE WINAPI expGetModuleHandleA(const char* name)
600 WINE_MODREF* wm;
601 HMODULE result;
602 if(!name)
603 #ifdef QTX
604 result=1;
605 #else
606 result=0;
607 #endif
608 else
610 wm=MODULE_FindModule(name);
611 if(wm==0)result=0;
612 else
613 result=(HMODULE)(wm->module);
615 if(!result)
617 if(name && (strcasecmp(name, "kernel32")==0 || !strcasecmp(name, "kernel32.dll")))
618 result=MODULE_HANDLE_kernel32;
619 #ifdef QTX
620 if(name && strcasecmp(name, "user32")==0)
621 result=MODULE_HANDLE_user32;
622 #endif
624 dbgprintf("GetModuleHandleA('%s') => 0x%x\n", name, result);
625 return result;
628 static void* WINAPI expCreateThread(void* pSecAttr, long dwStackSize,
629 void* lpStartAddress, void* lpParameter,
630 long dwFlags, long* dwThreadId)
632 pthread_t *pth;
633 // printf("CreateThread:");
634 pth = (pthread_t*) my_mreq(sizeof(pthread_t), 0);
635 pthread_create(pth, NULL, (void*(*)(void*))lpStartAddress, lpParameter);
636 if(dwFlags)
637 printf( "WARNING: CreateThread flags not supported\n");
638 if(dwThreadId)
639 *dwThreadId=(long)pth;
640 if(list==NULL)
642 list=my_mreq(sizeof(th_list), 1);
643 list->next=list->prev=NULL;
645 else
647 list->next=my_mreq(sizeof(th_list), 0);
648 list->next->prev=list;
649 list->next->next=NULL;
650 list=list->next;
652 list->thread=pth;
653 dbgprintf("CreateThread(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x) => 0x%x\n",
654 pSecAttr, dwStackSize, lpStartAddress, lpParameter, dwFlags, dwThreadId, pth);
655 return pth;
658 struct mutex_list_t;
660 struct mutex_list_t
662 char type;
663 pthread_mutex_t *pm;
664 pthread_cond_t *pc;
665 char state;
666 char reset;
667 char name[128];
668 int semaphore;
669 struct mutex_list_t* next;
670 struct mutex_list_t* prev;
672 typedef struct mutex_list_t mutex_list;
673 static mutex_list* mlist=NULL;
675 void destroy_event(void* event)
677 mutex_list* pp=mlist;
678 // printf("garbage collector: destroy_event(%x)\n", event);
679 while(pp)
681 if(pp==(mutex_list*)event)
683 if(pp->next)
684 pp->next->prev=pp->prev;
685 if(pp->prev)
686 pp->prev->next=pp->next;
687 if(mlist==(mutex_list*)event)
688 mlist=mlist->prev;
690 pp=mlist;
691 while(pp)
693 printf("%x => ", pp);
694 pp=pp->prev;
696 printf("0\n");
698 return;
700 pp=pp->prev;
704 static void* WINAPI expCreateEventA(void* pSecAttr, char bManualReset,
705 char bInitialState, const char* name)
707 pthread_mutex_t *pm;
708 pthread_cond_t *pc;
710 mutex_list* pp;
711 pp=mlist;
712 while(pp)
714 printf("%x => ", pp);
715 pp=pp->prev;
717 printf("0\n");
719 if(mlist!=NULL)
721 mutex_list* pp=mlist;
722 if(name!=NULL)
725 if((strcmp(pp->name, name)==0) && (pp->type==0))
727 dbgprintf("CreateEventA(0x%x, 0x%x, 0x%x, 0x%x='%s') => 0x%x\n",
728 pSecAttr, bManualReset, bInitialState, name, name, pp->pm);
729 return pp->pm;
731 }while((pp=pp->prev) != NULL);
733 pm=mreq_private(sizeof(pthread_mutex_t), 0, AREATYPE_MUTEX);
734 pthread_mutex_init(pm, NULL);
735 pc=mreq_private(sizeof(pthread_cond_t), 0, AREATYPE_COND);
736 pthread_cond_init(pc, NULL);
737 if(mlist==NULL)
739 mlist=mreq_private(sizeof(mutex_list), 00, AREATYPE_EVENT);
740 mlist->next=mlist->prev=NULL;
742 else
744 mlist->next=mreq_private(sizeof(mutex_list), 00, AREATYPE_EVENT);
745 mlist->next->prev=mlist;
746 mlist->next->next=NULL;
747 mlist=mlist->next;
749 mlist->type=0; /* Type Event */
750 mlist->pm=pm;
751 mlist->pc=pc;
752 mlist->state=bInitialState;
753 mlist->reset=bManualReset;
754 if(name)
755 strncpy(mlist->name, name, 127);
756 else
757 mlist->name[0]=0;
758 if(pm==NULL)
759 dbgprintf("ERROR::: CreateEventA failure\n");
761 if(bInitialState)
762 pthread_mutex_lock(pm);
764 if(name)
765 dbgprintf("CreateEventA(0x%x, 0x%x, 0x%x, 0x%x='%s') => 0x%x\n",
766 pSecAttr, bManualReset, bInitialState, name, name, mlist);
767 else
768 dbgprintf("CreateEventA(0x%x, 0x%x, 0x%x, NULL) => 0x%x\n",
769 pSecAttr, bManualReset, bInitialState, mlist);
770 return mlist;
773 static void* WINAPI expSetEvent(void* event)
775 mutex_list *ml = (mutex_list *)event;
776 dbgprintf("SetEvent(%x) => 0x1\n", event);
777 pthread_mutex_lock(ml->pm);
778 if (ml->state == 0) {
779 ml->state = 1;
780 pthread_cond_signal(ml->pc);
782 pthread_mutex_unlock(ml->pm);
784 return (void *)1;
786 static void* WINAPI expResetEvent(void* event)
788 mutex_list *ml = (mutex_list *)event;
789 dbgprintf("ResetEvent(0x%x) => 0x1\n", event);
790 pthread_mutex_lock(ml->pm);
791 ml->state = 0;
792 pthread_mutex_unlock(ml->pm);
794 return (void *)1;
797 static void* WINAPI expWaitForSingleObject(void* object, int duration)
799 mutex_list *ml = (mutex_list *)object;
800 // FIXME FIXME FIXME - this value is sometime unititialize !!!
801 int ret = WAIT_FAILED;
802 mutex_list* pp=mlist;
803 if(object == (void*)0xcfcf9898)
806 From GetCurrentThread() documentation:
807 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.
809 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.
811 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.
813 dbgprintf("WaitForSingleObject(thread_handle) called\n");
814 return (void*)WAIT_FAILED;
816 dbgprintf("WaitForSingleObject(0x%x, duration %d) =>\n",object, duration);
818 // loop below was slightly fixed - its used just for checking if
819 // this object really exists in our list
820 if (!ml)
821 return (void*) ret;
822 while (pp && (pp->pm != ml->pm))
823 pp = pp->prev;
824 if (!pp) {
825 dbgprintf("WaitForSingleObject: NotFound\n");
826 return (void*)ret;
829 pthread_mutex_lock(ml->pm);
831 switch(ml->type) {
832 case 0: /* Event */
833 if (duration == 0) { /* Check Only */
834 if (ml->state == 1) ret = WAIT_FAILED;
835 else ret = WAIT_OBJECT_0;
837 if (duration == -1) { /* INFINITE */
838 if (ml->state == 0)
839 pthread_cond_wait(ml->pc,ml->pm);
840 if (ml->reset)
841 ml->state = 0;
842 ret = WAIT_OBJECT_0;
844 if (duration > 0) { /* Timed Wait */
845 struct timespec abstime;
846 struct timeval now;
847 gettimeofday(&now, 0);
848 abstime.tv_sec = now.tv_sec + (now.tv_usec+duration)/1000000;
849 abstime.tv_nsec = ((now.tv_usec+duration)%1000000)*1000;
850 if (ml->state == 0)
851 ret=pthread_cond_timedwait(ml->pc,ml->pm,&abstime);
852 if (ret == ETIMEDOUT) ret = WAIT_TIMEOUT;
853 else ret = WAIT_OBJECT_0;
854 if (ml->reset)
855 ml->state = 0;
857 break;
858 case 1: /* Semaphore */
859 if (duration == 0) {
860 if(ml->semaphore==0) ret = WAIT_FAILED;
861 else {
862 ml->semaphore++;
863 ret = WAIT_OBJECT_0;
866 if (duration == -1) {
867 if (ml->semaphore==0)
868 pthread_cond_wait(ml->pc,ml->pm);
869 ml->semaphore--;
871 break;
873 pthread_mutex_unlock(ml->pm);
875 dbgprintf("WaitForSingleObject(0x%x, %d): 0x%x => 0x%x \n",object,duration,ml,ret);
876 return (void *)ret;
879 #ifdef QTX
880 static void* WINAPI expWaitForMultipleObjects(int count, const void** objects,
881 int WaitAll, int duration)
883 int i;
884 void *object;
885 void *ret;
887 dbgprintf("WaitForMultipleObjects(%d, 0x%x, %d, duration %d) =>\n",
888 count, objects, WaitAll, duration);
890 for (i = 0; i < count; i++)
892 object = (void *)objects[i];
893 ret = expWaitForSingleObject(object, duration);
894 if (WaitAll)
895 dbgprintf("WaitAll flag not yet supported...\n");
896 else
897 return ret;
899 return NULL;
902 static void WINAPI expExitThread(int retcode)
904 dbgprintf("ExitThread(%d)\n", retcode);
905 pthread_exit(&retcode);
908 static HANDLE WINAPI expCreateMutexA(void *pSecAttr,
909 char bInitialOwner, const char *name)
911 HANDLE mlist = (HANDLE)expCreateEventA(pSecAttr, 0, 0, name);
913 if (name)
914 dbgprintf("CreateMutexA(0x%x, %d, '%s') => 0x%x\n",
915 pSecAttr, bInitialOwner, name, mlist);
916 else
917 dbgprintf("CreateMutexA(0x%x, %d, NULL) => 0x%x\n",
918 pSecAttr, bInitialOwner, mlist);
919 #ifndef QTX
920 /* 10l to QTX, if CreateMutex returns a real mutex, WaitForSingleObject
921 waits for ever, else it works ;) */
922 return mlist;
923 #endif
926 static int WINAPI expReleaseMutex(HANDLE hMutex)
928 dbgprintf("ReleaseMutex(%x) => 1\n", hMutex);
929 /* FIXME:XXX !! not yet implemented */
930 return 1;
932 #endif
934 static int pf_set = 0;
935 static BYTE PF[64] = {0,};
937 static void DumpSystemInfo(const SYSTEM_INFO* si)
939 dbgprintf(" Processor architecture %d\n", si->u.s.wProcessorArchitecture);
940 dbgprintf(" Page size: %d\n", si->dwPageSize);
941 dbgprintf(" Minimum app address: %d\n", si->lpMinimumApplicationAddress);
942 dbgprintf(" Maximum app address: %d\n", si->lpMaximumApplicationAddress);
943 dbgprintf(" Active processor mask: 0x%x\n", si->dwActiveProcessorMask);
944 dbgprintf(" Number of processors: %d\n", si->dwNumberOfProcessors);
945 dbgprintf(" Processor type: 0x%x\n", si->dwProcessorType);
946 dbgprintf(" Allocation granularity: 0x%x\n", si->dwAllocationGranularity);
947 dbgprintf(" Processor level: 0x%x\n", si->wProcessorLevel);
948 dbgprintf(" Processor revision: 0x%x\n", si->wProcessorRevision);
951 static void WINAPI expGetSystemInfo(SYSTEM_INFO* si)
953 /* FIXME: better values for the two entries below... */
954 static int cache = 0;
955 static SYSTEM_INFO cachedsi;
956 unsigned int regs[4];
957 dbgprintf("GetSystemInfo(%p) =>\n", si);
959 if (cache) {
960 memcpy(si,&cachedsi,sizeof(*si));
961 DumpSystemInfo(si);
962 return;
964 memset(PF,0,sizeof(PF));
965 pf_set = 1;
967 cachedsi.u.s.wProcessorArchitecture = PROCESSOR_ARCHITECTURE_INTEL;
968 cachedsi.dwPageSize = getpagesize();
970 /* FIXME: better values for the two entries below... */
971 cachedsi.lpMinimumApplicationAddress = (void *)0x00000000;
972 cachedsi.lpMaximumApplicationAddress = (void *)0x7FFFFFFF;
973 cachedsi.dwActiveProcessorMask = 1;
974 cachedsi.dwNumberOfProcessors = 1;
975 cachedsi.dwProcessorType = PROCESSOR_INTEL_386;
976 cachedsi.dwAllocationGranularity = 0x10000;
977 cachedsi.wProcessorLevel = 5; /* pentium */
978 cachedsi.wProcessorRevision = 0x0101;
980 #ifdef MPLAYER
981 /* mplayer's way to detect PF's */
983 #include "../cpudetect.h"
984 extern CpuCaps gCpuCaps;
986 if (gCpuCaps.hasMMX)
987 PF[PF_MMX_INSTRUCTIONS_AVAILABLE] = TRUE;
988 if (gCpuCaps.hasSSE)
989 PF[PF_XMMI_INSTRUCTIONS_AVAILABLE] = TRUE;
990 if (gCpuCaps.has3DNow)
991 PF[PF_AMD3D_INSTRUCTIONS_AVAILABLE] = TRUE;
993 if (gCpuCaps.cpuType == 4)
995 cachedsi.dwProcessorType = PROCESSOR_INTEL_486;
996 cachedsi.wProcessorLevel = 4;
998 else if (gCpuCaps.cpuType >= 5)
1000 cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
1001 cachedsi.wProcessorLevel = 5;
1003 else
1005 cachedsi.dwProcessorType = PROCESSOR_INTEL_386;
1006 cachedsi.wProcessorLevel = 3;
1008 cachedsi.wProcessorRevision = gCpuCaps.cpuStepping;
1009 cachedsi.dwNumberOfProcessors = 1; /* hardcoded */
1011 #endif
1013 /* disable cpuid based detection (mplayer's cpudetect.c does this - see above) */
1014 #ifndef MPLAYER
1015 #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__svr4__) || defined(__DragonFly__)
1016 do_cpuid(1, regs);
1017 switch ((regs[0] >> 8) & 0xf) { // cpu family
1018 case 3: cachedsi.dwProcessorType = PROCESSOR_INTEL_386;
1019 cachedsi.wProcessorLevel= 3;
1020 break;
1021 case 4: cachedsi.dwProcessorType = PROCESSOR_INTEL_486;
1022 cachedsi.wProcessorLevel= 4;
1023 break;
1024 case 5: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
1025 cachedsi.wProcessorLevel= 5;
1026 break;
1027 case 6: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
1028 cachedsi.wProcessorLevel= 5;
1029 break;
1030 default:cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
1031 cachedsi.wProcessorLevel= 5;
1032 break;
1034 cachedsi.wProcessorRevision = regs[0] & 0xf; // stepping
1035 if (regs[3] & (1 << 8))
1036 PF[PF_COMPARE_EXCHANGE_DOUBLE] = TRUE;
1037 if (regs[3] & (1 << 23))
1038 PF[PF_MMX_INSTRUCTIONS_AVAILABLE] = TRUE;
1039 if (regs[3] & (1 << 25))
1040 PF[PF_XMMI_INSTRUCTIONS_AVAILABLE] = TRUE;
1041 if (regs[3] & (1 << 31))
1042 PF[PF_AMD3D_INSTRUCTIONS_AVAILABLE] = TRUE;
1043 cachedsi.dwNumberOfProcessors=1;
1044 #endif
1045 #endif /* MPLAYER */
1047 /* MPlayer: linux detection enabled (based on proc/cpuinfo) for checking
1048 fdiv_bug and fpu emulation flags -- alex/MPlayer */
1049 #ifdef __linux__
1051 char buf[20];
1052 char line[200];
1053 FILE *f = fopen ("/proc/cpuinfo", "r");
1055 if (!f)
1056 return;
1057 while (fgets(line,200,f)!=NULL) {
1058 char *s,*value;
1060 /* NOTE: the ':' is the only character we can rely on */
1061 if (!(value = strchr(line,':')))
1062 continue;
1063 /* terminate the valuename */
1064 *value++ = '\0';
1065 /* skip any leading spaces */
1066 while (*value==' ') value++;
1067 if ((s=strchr(value,'\n')))
1068 *s='\0';
1070 /* 2.1 method */
1071 if (!lstrncmpiA(line, "cpu family",strlen("cpu family"))) {
1072 if (isdigit (value[0])) {
1073 switch (value[0] - '0') {
1074 case 3: cachedsi.dwProcessorType = PROCESSOR_INTEL_386;
1075 cachedsi.wProcessorLevel= 3;
1076 break;
1077 case 4: cachedsi.dwProcessorType = PROCESSOR_INTEL_486;
1078 cachedsi.wProcessorLevel= 4;
1079 break;
1080 case 5: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
1081 cachedsi.wProcessorLevel= 5;
1082 break;
1083 case 6: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
1084 cachedsi.wProcessorLevel= 5;
1085 break;
1086 default:cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
1087 cachedsi.wProcessorLevel= 5;
1088 break;
1091 /* set the CPU type of the current processor */
1092 sprintf(buf,"CPU %ld",cachedsi.dwProcessorType);
1093 continue;
1095 /* old 2.0 method */
1096 if (!lstrncmpiA(line, "cpu",strlen("cpu"))) {
1097 if ( isdigit (value[0]) && value[1] == '8' &&
1098 value[2] == '6' && value[3] == 0
1100 switch (value[0] - '0') {
1101 case 3: cachedsi.dwProcessorType = PROCESSOR_INTEL_386;
1102 cachedsi.wProcessorLevel= 3;
1103 break;
1104 case 4: cachedsi.dwProcessorType = PROCESSOR_INTEL_486;
1105 cachedsi.wProcessorLevel= 4;
1106 break;
1107 case 5: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
1108 cachedsi.wProcessorLevel= 5;
1109 break;
1110 case 6: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
1111 cachedsi.wProcessorLevel= 5;
1112 break;
1113 default:cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
1114 cachedsi.wProcessorLevel= 5;
1115 break;
1118 /* set the CPU type of the current processor */
1119 sprintf(buf,"CPU %ld",cachedsi.dwProcessorType);
1120 continue;
1122 if (!lstrncmpiA(line,"fdiv_bug",strlen("fdiv_bug"))) {
1123 if (!lstrncmpiA(value,"yes",3))
1124 PF[PF_FLOATING_POINT_PRECISION_ERRATA] = TRUE;
1126 continue;
1128 if (!lstrncmpiA(line,"fpu",strlen("fpu"))) {
1129 if (!lstrncmpiA(value,"no",2))
1130 PF[PF_FLOATING_POINT_EMULATED] = TRUE;
1132 continue;
1134 if (!lstrncmpiA(line,"processor",strlen("processor"))) {
1135 /* processor number counts up...*/
1136 unsigned int x;
1138 if (sscanf(value,"%d",&x))
1139 if (x+1>cachedsi.dwNumberOfProcessors)
1140 cachedsi.dwNumberOfProcessors=x+1;
1142 /* Create a new processor subkey on a multiprocessor
1143 * system
1145 sprintf(buf,"%d",x);
1147 if (!lstrncmpiA(line,"stepping",strlen("stepping"))) {
1148 int x;
1150 if (sscanf(value,"%d",&x))
1151 cachedsi.wProcessorRevision = x;
1154 ( (!lstrncmpiA(line,"flags",strlen("flags")))
1155 || (!lstrncmpiA(line,"features",strlen("features"))) )
1157 if (strstr(value,"cx8"))
1158 PF[PF_COMPARE_EXCHANGE_DOUBLE] = TRUE;
1159 if (strstr(value,"mmx"))
1160 PF[PF_MMX_INSTRUCTIONS_AVAILABLE] = TRUE;
1161 if (strstr(value,"tsc"))
1162 PF[PF_RDTSC_INSTRUCTION_AVAILABLE] = TRUE;
1163 if (strstr(value,"xmm"))
1164 PF[PF_XMMI_INSTRUCTIONS_AVAILABLE] = TRUE;
1165 if (strstr(value,"3dnow"))
1166 PF[PF_AMD3D_INSTRUCTIONS_AVAILABLE] = TRUE;
1169 fclose (f);
1171 * ad hoc fix for smp machines.
1172 * some problems on WaitForSingleObject,CreateEvent,SetEvent
1173 * CreateThread ...etc..
1176 cachedsi.dwNumberOfProcessors=1;
1178 #endif /* __linux__ */
1179 cache = 1;
1180 memcpy(si,&cachedsi,sizeof(*si));
1181 DumpSystemInfo(si);
1184 // avoid undefined expGetSystemInfo
1185 static WIN_BOOL WINAPI expIsProcessorFeaturePresent(DWORD v)
1187 WIN_BOOL result = 0;
1188 if (!pf_set)
1190 SYSTEM_INFO si;
1191 expGetSystemInfo(&si);
1193 if(v<64) result=PF[v];
1194 dbgprintf("IsProcessorFeaturePresent(0x%x) => 0x%x\n", v, result);
1195 return result;
1199 static long WINAPI expGetVersion()
1201 dbgprintf("GetVersion() => 0xC0000004\n");
1202 return 0xC0000004;//Windows 95
1205 static HANDLE WINAPI expHeapCreate(long flags, long init_size, long max_size)
1207 // printf("HeapCreate:");
1208 HANDLE result;
1209 if(init_size==0)
1210 result=(HANDLE)my_mreq(0x110000, 0);
1211 else
1212 result=(HANDLE)my_mreq((init_size + 0xfff) & 0x7ffff000 , 0);
1213 dbgprintf("HeapCreate(flags 0x%x, initial size %d, maximum size %d) => 0x%x\n", flags, init_size, max_size, result);
1214 return result;
1217 // this is another dirty hack
1218 // VP31 is releasing one allocated Heap chunk twice
1219 // we will silently ignore this second call...
1220 static void* heapfreehack = 0;
1221 static int heapfreehackshown = 0;
1222 //extern void trapbug(void);
1223 static void* WINAPI expHeapAlloc(HANDLE heap, int flags, int size)
1225 void* z;
1227 Morgan's m3jpeg32.dll v. 2.0 encoder expects that request for
1228 HeapAlloc returns area larger than size argument :-/
1230 actually according to M$ Doc HeapCreate size should be rounded
1231 to page boundaries thus we should simulate this
1233 //if (size == 22276) trapbug();
1234 z=my_mreq((size + 0xfff) & 0x7ffff000, (flags & HEAP_ZERO_MEMORY));
1235 if(z==0)
1236 printf("HeapAlloc failure\n");
1237 dbgprintf("HeapAlloc(heap 0x%x, flags 0x%x, size %d) => 0x%x\n", heap, flags, size, z);
1238 heapfreehack = 0; // reset
1239 return z;
1241 static long WINAPI expHeapDestroy(void* heap)
1243 dbgprintf("HeapDestroy(heap 0x%x) => 1\n", heap);
1244 my_release(heap);
1245 return 1;
1248 static long WINAPI expHeapFree(HANDLE heap, DWORD dwFlags, LPVOID lpMem)
1250 dbgprintf("HeapFree(0x%x, 0x%x, pointer 0x%x) => 1\n", heap, dwFlags, lpMem);
1251 if (heapfreehack != lpMem && lpMem != (void*)0xffffffff
1252 && lpMem != (void*)0xbdbdbdbd)
1253 // 0xbdbdbdbd is for i263_drv.drv && libefence
1254 // it seems to be reading from relased memory
1255 // EF_PROTECT_FREE doens't show any probleme
1256 my_release(lpMem);
1257 else
1259 if (!heapfreehackshown++)
1260 printf("Info: HeapFree deallocating same memory twice! (%p)\n", lpMem);
1262 heapfreehack = lpMem;
1263 return 1;
1265 static long WINAPI expHeapSize(int heap, int flags, void* pointer)
1267 long result=my_size(pointer);
1268 dbgprintf("HeapSize(heap 0x%x, flags 0x%x, pointer 0x%x) => %d\n", heap, flags, pointer, result);
1269 return result;
1271 static void* WINAPI expHeapReAlloc(HANDLE heap,int flags,void *lpMem,int size)
1273 long orgsize = my_size(lpMem);
1274 dbgprintf("HeapReAlloc() Size %ld org %d\n",orgsize,size);
1275 return my_realloc(lpMem, size);
1277 static long WINAPI expGetProcessHeap(void)
1279 dbgprintf("GetProcessHeap() => 1\n");
1280 return 1;
1282 static void* WINAPI expVirtualAlloc(void* v1, long v2, long v3, long v4)
1284 void* z = VirtualAlloc(v1, v2, v3, v4);
1285 if(z==0)
1286 printf("VirtualAlloc failure\n");
1287 dbgprintf("VirtualAlloc(0x%x, %d, %d, %d) => 0x%x \n",v1,v2,v3,v4, z);
1288 return z;
1290 static int WINAPI expVirtualFree(void* v1, int v2, int v3)
1292 int result = VirtualFree(v1,v2,v3);
1293 dbgprintf("VirtualFree(0x%x, %d, %d) => %d\n",v1,v2,v3, result);
1294 return result;
1297 /* we're building a table of critical sections. cs_win pointer uses the DLL
1298 cs_unix is the real structure, we're using cs_win only to identifying cs_unix */
1299 struct critsecs_list_t
1301 CRITICAL_SECTION *cs_win;
1302 struct CRITSECT *cs_unix;
1305 /* 'NEWTYPE' is working with VIVO, 3ivX and QTX dll (no more segfaults) -- alex */
1306 #undef CRITSECS_NEWTYPE
1307 //#define CRITSECS_NEWTYPE 1
1309 #ifdef CRITSECS_NEWTYPE
1310 /* increased due to ucod needs more than 32 entries */
1311 /* and 64 should be enough for everything */
1312 #define CRITSECS_LIST_MAX 64
1313 static struct critsecs_list_t critsecs_list[CRITSECS_LIST_MAX];
1315 static int critsecs_get_pos(CRITICAL_SECTION *cs_win)
1317 int i;
1319 for (i=0; i < CRITSECS_LIST_MAX; i++)
1320 if (critsecs_list[i].cs_win == cs_win)
1321 return(i);
1322 return(-1);
1325 static int critsecs_get_unused(void)
1327 int i;
1329 for (i=0; i < CRITSECS_LIST_MAX; i++)
1330 if (critsecs_list[i].cs_win == NULL)
1331 return(i);
1332 return(-1);
1335 struct CRITSECT *critsecs_get_unix(CRITICAL_SECTION *cs_win)
1337 int i;
1339 for (i=0; i < CRITSECS_LIST_MAX; i++)
1340 if (critsecs_list[i].cs_win == cs_win && critsecs_list[i].cs_unix)
1341 return(critsecs_list[i].cs_unix);
1342 return(NULL);
1344 #endif
1346 static void WINAPI expInitializeCriticalSection(CRITICAL_SECTION* c)
1348 dbgprintf("InitializeCriticalSection(0x%x)\n", c);
1349 /* if(sizeof(pthread_mutex_t)>sizeof(CRITICAL_SECTION))
1351 printf(" ERROR:::: sizeof(pthread_mutex_t) is %d, expected <=%d!\n",
1352 sizeof(pthread_mutex_t), sizeof(CRITICAL_SECTION));
1353 return;
1355 /* pthread_mutex_init((pthread_mutex_t*)c, NULL); */
1356 #ifdef CRITSECS_NEWTYPE
1358 struct CRITSECT *cs;
1359 int i = critsecs_get_unused();
1361 if (i < 0)
1363 printf("InitializeCriticalSection(%p) - no more space in list\n", c);
1364 return;
1366 dbgprintf("got unused space at %d\n", i);
1367 cs = malloc(sizeof(struct CRITSECT));
1368 if (!cs)
1370 printf("InitializeCriticalSection(%p) - out of memory\n", c);
1371 return;
1373 pthread_mutex_init(&cs->mutex, NULL);
1374 cs->locked = 0;
1375 critsecs_list[i].cs_win = c;
1376 critsecs_list[i].cs_unix = cs;
1377 dbgprintf("InitializeCriticalSection -> itemno=%d, cs_win=%p, cs_unix=%p\n",
1378 i, c, cs);
1380 #else
1382 struct CRITSECT* cs = mreq_private(sizeof(struct CRITSECT) + sizeof(CRITICAL_SECTION),
1383 0, AREATYPE_CRITSECT);
1384 pthread_mutex_init(&cs->mutex, NULL);
1385 cs->locked=0;
1386 cs->deadbeef = 0xdeadbeef;
1387 *(void**)c = cs;
1389 #endif
1390 return;
1393 static void WINAPI expEnterCriticalSection(CRITICAL_SECTION* c)
1395 #ifdef CRITSECS_NEWTYPE
1396 struct CRITSECT* cs = critsecs_get_unix(c);
1397 #else
1398 struct CRITSECT* cs = (*(struct CRITSECT**)c);
1399 #endif
1400 dbgprintf("EnterCriticalSection(0x%x) %p\n",c, cs);
1401 if (!cs)
1403 dbgprintf("entered uninitialized critisec!\n");
1404 expInitializeCriticalSection(c);
1405 #ifdef CRITSECS_NEWTYPE
1406 cs=critsecs_get_unix(c);
1407 #else
1408 cs = (*(struct CRITSECT**)c);
1409 #endif
1410 dbgprintf("Win32 Warning: Accessed uninitialized Critical Section (%p)!\n", c);
1412 if(cs->locked)
1413 if(cs->id==pthread_self())
1414 return;
1415 pthread_mutex_lock(&(cs->mutex));
1416 cs->locked=1;
1417 cs->id=pthread_self();
1418 return;
1420 static void WINAPI expLeaveCriticalSection(CRITICAL_SECTION* c)
1422 #ifdef CRITSECS_NEWTYPE
1423 struct CRITSECT* cs = critsecs_get_unix(c);
1424 #else
1425 struct CRITSECT* cs = (*(struct CRITSECT**)c);
1426 #endif
1427 // struct CRITSECT* cs=(struct CRITSECT*)c;
1428 dbgprintf("LeaveCriticalSection(0x%x) 0x%x\n",c, cs);
1429 if (!cs)
1431 dbgprintf("Win32 Warning: Leaving uninitialized Critical Section %p!!\n", c);
1432 return;
1434 if (cs->locked)
1436 cs->locked=0;
1437 pthread_mutex_unlock(&(cs->mutex));
1439 else
1440 dbgprintf("Win32 Warning: Unlocking unlocked Critical Section %p!!\n", c);
1441 return;
1444 static void expfree(void* mem); /* forward declaration */
1446 static void WINAPI expDeleteCriticalSection(CRITICAL_SECTION *c)
1448 #ifdef CRITSECS_NEWTYPE
1449 struct CRITSECT* cs = critsecs_get_unix(c);
1450 #else
1451 struct CRITSECT* cs= (*(struct CRITSECT**)c);
1452 #endif
1453 // struct CRITSECT* cs=(struct CRITSECT*)c;
1454 dbgprintf("DeleteCriticalSection(0x%x)\n",c);
1456 if (!cs)
1458 dbgprintf("Win32 Warning: Deleting uninitialized Critical Section %p!!\n", c);
1459 return;
1462 if (cs->locked)
1464 dbgprintf("Win32 Warning: Deleting unlocked Critical Section %p!!\n", c);
1465 pthread_mutex_unlock(&(cs->mutex));
1468 #ifndef GARBAGE
1469 pthread_mutex_destroy(&(cs->mutex));
1470 // released by GarbageCollector in my_relase otherwise
1471 #endif
1472 my_release(cs);
1473 #ifdef CRITSECS_NEWTYPE
1475 int i = critsecs_get_pos(c);
1477 if (i < 0)
1479 printf("DeleteCriticalSection(%p) error (critsec not found)\n", c);
1480 return;
1483 critsecs_list[i].cs_win = NULL;
1484 expfree(critsecs_list[i].cs_unix);
1485 critsecs_list[i].cs_unix = NULL;
1486 dbgprintf("DeleteCriticalSection -> itemno=%d\n", i);
1488 #endif
1489 return;
1491 static int WINAPI expGetCurrentThreadId()
1493 dbgprintf("GetCurrentThreadId() => %d\n", pthread_self());
1494 return pthread_self();
1496 static int WINAPI expGetCurrentProcess()
1498 dbgprintf("GetCurrentProcess() => %d\n", getpid());
1499 return getpid();
1502 #ifdef QTX
1503 // this version is required for Quicktime codecs (.qtx/.qts) to work.
1504 // (they assume some pointers at FS: segment)
1506 extern void* fs_seg;
1508 //static int tls_count;
1509 static int tls_use_map[64];
1510 static int WINAPI expTlsAlloc()
1512 int i;
1513 for(i=0; i<64; i++)
1514 if(tls_use_map[i]==0)
1516 tls_use_map[i]=1;
1517 dbgprintf("TlsAlloc() => %d\n",i);
1518 return i;
1520 dbgprintf("TlsAlloc() => -1 (ERROR)\n");
1521 return -1;
1524 //static int WINAPI expTlsSetValue(DWORD index, void* value)
1525 static int WINAPI expTlsSetValue(int index, void* value)
1527 dbgprintf("TlsSetValue(%d,0x%x) => 1\n",index,value);
1528 // if((index<0) || (index>64))
1529 if((index>=64))
1530 return 0;
1531 *(void**)((char*)fs_seg+0x88+4*index) = value;
1532 return 1;
1535 static void* WINAPI expTlsGetValue(DWORD index)
1537 dbgprintf("TlsGetValue(%d)\n",index);
1538 // if((index<0) || (index>64))
1539 if((index>=64)) return NULL;
1540 return *(void**)((char*)fs_seg+0x88+4*index);
1543 static int WINAPI expTlsFree(int idx)
1545 int index = (int) idx;
1546 dbgprintf("TlsFree(%d)\n",index);
1547 if((index<0) || (index>64))
1548 return 0;
1549 tls_use_map[index]=0;
1550 return 1;
1553 #else
1554 struct tls_s {
1555 void* value;
1556 int used;
1557 struct tls_s* prev;
1558 struct tls_s* next;
1561 static void* WINAPI expTlsAlloc()
1563 if (g_tls == NULL)
1565 g_tls=my_mreq(sizeof(tls_t), 0);
1566 g_tls->next=g_tls->prev=NULL;
1568 else
1570 g_tls->next=my_mreq(sizeof(tls_t), 0);
1571 g_tls->next->prev=g_tls;
1572 g_tls->next->next=NULL;
1573 g_tls=g_tls->next;
1575 dbgprintf("TlsAlloc() => 0x%x\n", g_tls);
1576 if (g_tls)
1577 g_tls->value=0; /* XXX For Divx.dll */
1578 return g_tls;
1581 static int WINAPI expTlsSetValue(void* idx, void* value)
1583 tls_t* index = (tls_t*) idx;
1584 int result;
1585 if(index==0)
1586 result=0;
1587 else
1589 index->value=value;
1590 result=1;
1592 dbgprintf("TlsSetValue(index 0x%x, value 0x%x) => %d \n", index, value, result );
1593 return result;
1595 static void* WINAPI expTlsGetValue(void* idx)
1597 tls_t* index = (tls_t*) idx;
1598 void* result;
1599 if(index==0)
1600 result=0;
1601 else
1602 result=index->value;
1603 dbgprintf("TlsGetValue(index 0x%x) => 0x%x\n", index, result);
1604 return result;
1606 static int WINAPI expTlsFree(void* idx)
1608 tls_t* index = (tls_t*) idx;
1609 int result;
1610 if(index==0)
1611 result=0;
1612 else
1614 if(index->next)
1615 index->next->prev=index->prev;
1616 if(index->prev)
1617 index->prev->next=index->next;
1618 if (g_tls == index)
1619 g_tls = index->prev;
1620 my_release((void*)index);
1621 result=1;
1623 dbgprintf("TlsFree(index 0x%x) => %d\n", index, result);
1624 return result;
1626 #endif
1628 static void* WINAPI expLocalAlloc(int flags, int size)
1630 void* z = my_mreq(size, (flags & GMEM_ZEROINIT));
1631 if (z == 0)
1632 printf("LocalAlloc() failed\n");
1633 dbgprintf("LocalAlloc(%d, flags 0x%x) => 0x%x\n", size, flags, z);
1634 return z;
1637 static void* WINAPI expLocalReAlloc(int handle,int size, int flags)
1639 void *newpointer;
1640 int oldsize;
1642 newpointer=NULL;
1643 if (flags & LMEM_MODIFY) {
1644 dbgprintf("LocalReAlloc MODIFY\n");
1645 return (void *)handle;
1647 oldsize = my_size((void *)handle);
1648 newpointer = my_realloc((void *)handle,size);
1649 dbgprintf("LocalReAlloc(%x %d(old %d), flags 0x%x) => 0x%x\n", handle,size,oldsize, flags,newpointer);
1651 return newpointer;
1654 static void* WINAPI expLocalLock(void* z)
1656 dbgprintf("LocalLock(0x%x) => 0x%x\n", z, z);
1657 return z;
1660 static void* WINAPI expGlobalAlloc(int flags, int size)
1662 void* z;
1663 dbgprintf("GlobalAlloc(%d, flags 0x%X)\n", size, flags);
1665 z=my_mreq(size, (flags & GMEM_ZEROINIT));
1666 //z=calloc(size, 1);
1667 //z=malloc(size);
1668 if(z==0)
1669 printf("GlobalAlloc() failed\n");
1670 dbgprintf("GlobalAlloc(%d, flags 0x%x) => 0x%x\n", size, flags, z);
1671 return z;
1673 static void* WINAPI expGlobalLock(void* z)
1675 dbgprintf("GlobalLock(0x%x) => 0x%x\n", z, z);
1676 return z;
1678 // pvmjpg20 - but doesn't work anyway
1679 static int WINAPI expGlobalSize(void* amem)
1681 int size = 100000;
1682 #ifdef GARBAGE
1683 alloc_header* header = last_alloc;
1684 alloc_header* mem = (alloc_header*) amem - 1;
1685 if (amem == 0)
1686 return 0;
1687 pthread_mutex_lock(&memmut);
1688 while (header)
1690 if (header->deadbeef != 0xdeadbeef)
1692 dbgprintf("FATAL found corrupted memory! %p 0x%lx (%d)\n", header, header->deadbeef, alccnt);
1693 break;
1696 if (header == mem)
1698 size = header->size;
1699 break;
1702 header = header->prev;
1704 pthread_mutex_unlock(&memmut);
1705 #endif
1707 dbgprintf("GlobalSize(0x%x)\n", amem);
1708 return size;
1711 static int WINAPI expLoadIconA( long hinstance, char *name )
1713 dbgprintf("LoadIconA( %ld, 0x%x ) => 1\n",hinstance,name);
1714 return 1;
1717 static int WINAPI expLoadStringA(long instance, long id, void* buf, long size)
1719 int result=LoadStringA(instance, id, buf, size);
1720 // if(buf)
1721 dbgprintf("LoadStringA(instance 0x%x, id 0x%x, buffer 0x%x, size %d) => %d ( %s )\n",
1722 instance, id, buf, size, result, buf);
1723 // else
1724 // dbgprintf("LoadStringA(instance 0x%x, id 0x%x, buffer 0x%x, size %d) => %d\n",
1725 // instance, id, buf, size, result);
1726 return result;
1729 static long WINAPI expMultiByteToWideChar(long v1, long v2, char* s1, long siz1, short* s2, int siz2)
1731 #warning FIXME
1732 int i;
1733 int result;
1734 if(s2==0)
1735 result=1;
1736 else
1738 if(siz1>siz2/2)siz1=siz2/2;
1739 for(i=1; i<=siz1; i++)
1741 *s2=*s1;
1742 if(!*s1)break;
1743 s2++;
1744 s1++;
1746 result=i;
1748 if(s1)
1749 dbgprintf("MultiByteToWideChar(codepage %d, flags 0x%x, string 0x%x='%s',"
1750 "size %d, dest buffer 0x%x, dest size %d) => %d\n",
1751 v1, v2, s1, s1, siz1, s2, siz2, result);
1752 else
1753 dbgprintf("MultiByteToWideChar(codepage %d, flags 0x%x, string NULL,"
1754 "size %d, dest buffer 0x%x, dest size %d) =>\n",
1755 v1, v2, siz1, s2, siz2, result);
1756 return result;
1758 static void wch_print(const short* str)
1760 dbgprintf(" src: ");
1761 while(*str)dbgprintf("%c", *str++);
1762 dbgprintf("\n");
1764 static long WINAPI expWideCharToMultiByte(long v1, long v2, short* s1, long siz1,
1765 char* s2, int siz2, char* c3, int* siz3)
1767 int result;
1768 dbgprintf("WideCharToMultiByte(codepage %d, flags 0x%x, src 0x%x, src size %d, "
1769 "dest 0x%x, dest size %d, defch 0x%x, used_defch 0x%x)", v1, v2, s1, siz1, s2, siz2, c3, siz3);
1770 result=WideCharToMultiByte(v1, v2, s1, siz1, s2, siz2, c3, siz3);
1771 dbgprintf("=> %d\n", result);
1772 //if(s1)wch_print(s1);
1773 if(s2)dbgprintf(" dest: %s\n", s2);
1774 return result;
1776 static long WINAPI expGetVersionExA(OSVERSIONINFOA* c)
1778 dbgprintf("GetVersionExA(0x%x) => 1\n");
1779 c->dwOSVersionInfoSize=sizeof(*c);
1780 c->dwMajorVersion=4;
1781 c->dwMinorVersion=0;
1782 c->dwBuildNumber=0x4000457;
1783 #if 1
1784 // leave it here for testing win9x-only codecs
1785 c->dwPlatformId=VER_PLATFORM_WIN32_WINDOWS;
1786 strcpy(c->szCSDVersion, " B");
1787 #else
1788 c->dwPlatformId=VER_PLATFORM_WIN32_NT; // let's not make DLL assume that it can read CR* registers
1789 strcpy(c->szCSDVersion, "Service Pack 3");
1790 #endif
1791 dbgprintf(" Major version: 4\n Minor version: 0\n Build number: 0x4000457\n"
1792 " Platform Id: VER_PLATFORM_WIN32_NT\n Version string: 'Service Pack 3'\n");
1793 return 1;
1795 static HANDLE WINAPI expCreateSemaphoreA(char* v1, long init_count,
1796 long max_count, char* name)
1798 pthread_mutex_t *pm;
1799 pthread_cond_t *pc;
1800 mutex_list* pp;
1802 printf("CreateSemaphoreA(%p = %s)\n", name, (name ? name : "<null>"));
1803 pp=mlist;
1804 while(pp)
1806 printf("%p => ", pp);
1807 pp=pp->prev;
1809 printf("0\n");
1811 if(mlist!=NULL)
1813 mutex_list* pp=mlist;
1814 if(name!=NULL)
1817 if((strcmp(pp->name, name)==0) && (pp->type==1))
1819 dbgprintf("CreateSemaphoreA(0x%x, init_count %d, max_count %d, name 0x%x='%s') => 0x%x\n",
1820 v1, init_count, max_count, name, name, mlist);
1821 return (HANDLE)mlist;
1823 }while((pp=pp->prev) != NULL);
1825 pm=mreq_private(sizeof(pthread_mutex_t), 0, AREATYPE_MUTEX);
1826 pthread_mutex_init(pm, NULL);
1827 pc=mreq_private(sizeof(pthread_cond_t), 0, AREATYPE_COND);
1828 pthread_cond_init(pc, NULL);
1829 if(mlist==NULL)
1831 mlist=mreq_private(sizeof(mutex_list), 00, AREATYPE_EVENT);
1832 mlist->next=mlist->prev=NULL;
1834 else
1836 mlist->next=mreq_private(sizeof(mutex_list), 00, AREATYPE_EVENT);
1837 mlist->next->prev=mlist;
1838 mlist->next->next=NULL;
1839 mlist=mlist->next;
1840 // printf("new semaphore %p\n", mlist);
1842 mlist->type=1; /* Type Semaphore */
1843 mlist->pm=pm;
1844 mlist->pc=pc;
1845 mlist->state=0;
1846 mlist->reset=0;
1847 mlist->semaphore=init_count;
1848 if(name!=NULL)
1849 strncpy(mlist->name, name, 64);
1850 else
1851 mlist->name[0]=0;
1852 if(pm==NULL)
1853 dbgprintf("ERROR::: CreateSemaphoreA failure\n");
1854 if(name)
1855 dbgprintf("CreateSemaphoreA(0x%x, init_count %d, max_count %d, name 0x%x='%s') => 0x%x\n",
1856 v1, init_count, max_count, name, name, mlist);
1857 else
1858 dbgprintf("CreateSemaphoreA(0x%x, init_count %d, max_count %d, name 0) => 0x%x\n",
1859 v1, init_count, max_count, mlist);
1860 return (HANDLE)mlist;
1863 static long WINAPI expReleaseSemaphore(long hsem, long increment, long* prev_count)
1865 // The state of a semaphore object is signaled when its count
1866 // is greater than zero and nonsignaled when its count is equal to zero
1867 // Each time a waiting thread is released because of the semaphore's signaled
1868 // state, the count of the semaphore is decreased by one.
1869 mutex_list *ml = (mutex_list *)hsem;
1871 pthread_mutex_lock(ml->pm);
1872 if (prev_count != 0) *prev_count = ml->semaphore;
1873 if (ml->semaphore == 0) pthread_cond_signal(ml->pc);
1874 ml->semaphore += increment;
1875 pthread_mutex_unlock(ml->pm);
1876 dbgprintf("ReleaseSemaphore(semaphore 0x%x, increment %d, prev_count 0x%x) => 1\n",
1877 hsem, increment, prev_count);
1878 return 1;
1882 static long WINAPI expRegOpenKeyExA(long key, const char* subkey, long reserved, long access, int* newkey)
1884 long result=RegOpenKeyExA(key, subkey, reserved, access, newkey);
1885 dbgprintf("RegOpenKeyExA(key 0x%x, subkey %s, reserved %d, access 0x%x, pnewkey 0x%x) => %d\n",
1886 key, subkey, reserved, access, newkey, result);
1887 if(newkey)dbgprintf(" New key: 0x%x\n", *newkey);
1888 return result;
1890 static long WINAPI expRegCloseKey(long key)
1892 long result=RegCloseKey(key);
1893 dbgprintf("RegCloseKey(0x%x) => %d\n", key, result);
1894 return result;
1896 static long WINAPI expRegQueryValueExA(long key, const char* value, int* reserved, int* type, int* data, int* count)
1898 long result=RegQueryValueExA(key, value, reserved, type, data, count);
1899 dbgprintf("RegQueryValueExA(key 0x%x, value %s, reserved 0x%x, data 0x%x, count 0x%x)"
1900 " => 0x%x\n", key, value, reserved, data, count, result);
1901 if(data && count)dbgprintf(" read %d bytes: '%s'\n", *count, data);
1902 return result;
1905 //from wine source dlls/advapi32/registry.c
1906 static long WINAPI expRegCreateKeyA(long hkey, const char* name, int *retkey)
1908 dbgprintf("RegCreateKeyA(key 0x%x, name 0x%x='%s',newkey=0x%x)\n",hkey,name,retkey);
1909 return RegCreateKeyExA( hkey, name, 0, NULL,REG_OPTION_NON_VOLATILE,
1910 KEY_ALL_ACCESS , NULL, retkey, NULL );
1913 static long WINAPI expRegCreateKeyExA(long key, const char* name, long reserved,
1914 void* classs, long options, long security,
1915 void* sec_attr, int* newkey, int* status)
1917 long result=RegCreateKeyExA(key, name, reserved, classs, options, security, sec_attr, newkey, status);
1918 dbgprintf("RegCreateKeyExA(key 0x%x, name 0x%x='%s', reserved=0x%x,"
1919 " 0x%x, 0x%x, 0x%x, newkey=0x%x, status=0x%x) => %d\n",
1920 key, name, name, reserved, classs, options, security, sec_attr, newkey, status, result);
1921 if(!result && newkey) dbgprintf(" New key: 0x%x\n", *newkey);
1922 if(!result && status) dbgprintf(" New key status: 0x%x\n", *status);
1923 return result;
1925 static long WINAPI expRegSetValueExA(long key, const char* name, long v1, long v2, void* data, long size)
1927 long result=RegSetValueExA(key, name, v1, v2, data, size);
1928 dbgprintf("RegSetValueExA(key 0x%x, name '%s', 0x%x, 0x%x, data 0x%x -> 0x%x '%s', size=%d) => %d",
1929 key, name, v1, v2, data, *(int*)data, data, size, result);
1930 return result;
1933 static long WINAPI expRegOpenKeyA (long hKey, LPCSTR lpSubKey, int* phkResult)
1935 long result=RegOpenKeyExA(hKey, lpSubKey, 0, 0, phkResult);
1936 dbgprintf("RegOpenKeyExA(key 0x%x, subkey '%s', 0x%x) => %d\n",
1937 hKey, lpSubKey, phkResult, result);
1938 if(!result && phkResult) dbgprintf(" New key: 0x%x\n", *phkResult);
1939 return result;
1942 static DWORD WINAPI expRegEnumValueA(HKEY hkey, DWORD index, LPSTR value, LPDWORD val_count,
1943 LPDWORD reserved, LPDWORD type, LPBYTE data, LPDWORD count)
1945 return RegEnumValueA(hkey, index, value, val_count,
1946 reserved, type, data, count);
1949 static DWORD WINAPI expRegEnumKeyExA(HKEY hKey, DWORD dwIndex, LPSTR lpName, LPDWORD lpcbName,
1950 LPDWORD lpReserved, LPSTR lpClass, LPDWORD lpcbClass,
1951 LPFILETIME lpftLastWriteTime)
1953 return RegEnumKeyExA(hKey, dwIndex, lpName, lpcbName, lpReserved, lpClass,
1954 lpcbClass, lpftLastWriteTime);
1957 static long WINAPI expQueryPerformanceCounter(long long* z)
1959 longcount(z);
1960 dbgprintf("QueryPerformanceCounter(0x%x) => 1 ( %Ld )\n", z, *z);
1961 return 1;
1965 * dummy function RegQueryInfoKeyA(), required by vss codecs
1967 static DWORD WINAPI expRegQueryInfoKeyA( HKEY hkey, LPSTR class, LPDWORD class_len, LPDWORD reserved,
1968 LPDWORD subkeys, LPDWORD max_subkey, LPDWORD max_class,
1969 LPDWORD values, LPDWORD max_value, LPDWORD max_data,
1970 LPDWORD security, FILETIME *modif )
1972 return ERROR_SUCCESS;
1976 * return CPU clock (in kHz), using linux's /proc filesystem (/proc/cpuinfo)
1978 static double linux_cpuinfo_freq()
1980 double freq=-1;
1981 FILE *f;
1982 char line[200];
1983 char *s,*value;
1985 f = fopen ("/proc/cpuinfo", "r");
1986 if (f != NULL) {
1987 while (fgets(line,sizeof(line),f)!=NULL) {
1988 /* NOTE: the ':' is the only character we can rely on */
1989 if (!(value = strchr(line,':')))
1990 continue;
1991 /* terminate the valuename */
1992 *value++ = '\0';
1993 /* skip any leading spaces */
1994 while (*value==' ') value++;
1995 if ((s=strchr(value,'\n')))
1996 *s='\0';
1998 if (!strncasecmp(line, "cpu MHz",strlen("cpu MHz"))
1999 && sscanf(value, "%lf", &freq) == 1) {
2000 freq*=1000;
2001 break;
2004 fclose(f);
2006 return freq;
2010 static double solaris_kstat_freq()
2012 #if defined(HAVE_LIBKSTAT) && defined(KSTAT_DATA_INT32)
2014 * try to extract the CPU speed from the solaris kernel's kstat data
2016 kstat_ctl_t *kc;
2017 kstat_t *ksp;
2018 kstat_named_t *kdata;
2019 int mhz = 0;
2021 kc = kstat_open();
2022 if (kc != NULL)
2024 ksp = kstat_lookup(kc, "cpu_info", 0, "cpu_info0");
2026 /* kstat found and name/value pairs? */
2027 if (ksp != NULL && ksp->ks_type == KSTAT_TYPE_NAMED)
2029 /* read the kstat data from the kernel */
2030 if (kstat_read(kc, ksp, NULL) != -1)
2033 * lookup desired "clock_MHz" entry, check the expected
2034 * data type
2036 kdata = (kstat_named_t *)kstat_data_lookup(ksp, "clock_MHz");
2037 if (kdata != NULL && kdata->data_type == KSTAT_DATA_INT32)
2038 mhz = kdata->value.i32;
2041 kstat_close(kc);
2044 if (mhz > 0)
2045 return mhz * 1000.;
2046 #endif /* HAVE_LIBKSTAT */
2047 return -1; // kstat stuff is not available, CPU freq is unknown
2051 * Measure CPU freq using the pentium's time stamp counter register (TSC)
2053 static double tsc_freq()
2055 static double ofreq=0.0;
2056 int i;
2057 int x,y;
2058 i=time(NULL);
2059 if (ofreq != 0.0) return ofreq;
2060 while(i==time(NULL));
2061 x=localcount();
2062 i++;
2063 while(i==time(NULL));
2064 y=localcount();
2065 ofreq = (double)(y-x)/1000.;
2066 return ofreq;
2069 static double CPU_Freq()
2071 double freq;
2073 if ((freq = linux_cpuinfo_freq()) > 0)
2074 return freq;
2076 if ((freq = solaris_kstat_freq()) > 0)
2077 return freq;
2079 return tsc_freq();
2082 static long WINAPI expQueryPerformanceFrequency(long long* z)
2084 *z=(long long)CPU_Freq();
2085 dbgprintf("QueryPerformanceFrequency(0x%x) => 1 ( %Ld )\n", z, *z);
2086 return 1;
2088 static long WINAPI exptimeGetTime()
2090 struct timeval t;
2091 long result;
2092 gettimeofday(&t, 0);
2093 result=1000*t.tv_sec+t.tv_usec/1000;
2094 dbgprintf("timeGetTime() => %d\n", result);
2095 return result;
2097 static void* WINAPI expLocalHandle(void* v)
2099 dbgprintf("LocalHandle(0x%x) => 0x%x\n", v, v);
2100 return v;
2103 static void* WINAPI expGlobalHandle(void* v)
2105 dbgprintf("GlobalHandle(0x%x) => 0x%x\n", v, v);
2106 return v;
2108 static int WINAPI expGlobalUnlock(void* v)
2110 dbgprintf("GlobalUnlock(0x%x) => 1\n", v);
2111 return 1;
2113 static void* WINAPI expGlobalFree(void* v)
2115 dbgprintf("GlobalFree(0x%x) => 0\n", v);
2116 my_release(v);
2117 //free(v);
2118 return 0;
2121 static void* WINAPI expGlobalReAlloc(void* v, int size, int flags)
2123 void* result=my_realloc(v, size);
2124 //void* result=realloc(v, size);
2125 dbgprintf("GlobalReAlloc(0x%x, size %d, flags 0x%x) => 0x%x\n", v,size,flags,result);
2126 return result;
2129 static int WINAPI expLocalUnlock(void* v)
2131 dbgprintf("LocalUnlock(0x%x) => 1\n", v);
2132 return 1;
2135 static void* WINAPI expLocalFree(void* v)
2137 dbgprintf("LocalFree(0x%x) => 0\n", v);
2138 my_release(v);
2139 return 0;
2141 static HRSRC WINAPI expFindResourceA(HMODULE module, char* name, char* type)
2143 HRSRC result;
2145 result=FindResourceA(module, name, type);
2146 dbgprintf("FindResourceA(module 0x%x, name 0x%x(%s), type 0x%x(%s)) => 0x%x\n",
2147 module, name, HIWORD(name) ? name : "UNICODE", type, HIWORD(type) ? type : "UNICODE", result);
2148 return result;
2151 extern HRSRC WINAPI LoadResource(HMODULE, HRSRC);
2152 static HGLOBAL WINAPI expLoadResource(HMODULE module, HRSRC res)
2154 HGLOBAL result=LoadResource(module, res);
2155 dbgprintf("LoadResource(module 0x%x, resource 0x%x) => 0x%x\n", module, res, result);
2156 return result;
2158 static void* WINAPI expLockResource(long res)
2160 void* result=LockResource(res);
2161 dbgprintf("LockResource(0x%x) => 0x%x\n", res, result);
2162 return result;
2164 static int WINAPI expFreeResource(long res)
2166 int result=FreeResource(res);
2167 dbgprintf("FreeResource(0x%x) => %d\n", res, result);
2168 return result;
2170 //bool fun(HANDLE)
2171 //!0 on success
2172 static int WINAPI expCloseHandle(long v1)
2174 dbgprintf("CloseHandle(0x%x) => 1\n", v1);
2175 /* do not close stdin,stdout and stderr */
2176 if (v1 > 2)
2177 if (!close(v1))
2178 return 0;
2179 return 1;
2182 static const char* WINAPI expGetCommandLineA()
2184 dbgprintf("GetCommandLineA() => \"c:\\aviplay.exe\"\n");
2185 return "c:\\aviplay.exe";
2187 static short envs[]={'p', 'a', 't', 'h', ' ', 'c', ':', '\\', 0, 0};
2188 static LPWSTR WINAPI expGetEnvironmentStringsW()
2190 dbgprintf("GetEnvironmentStringsW() => 0\n", envs);
2191 return 0;
2193 static void * WINAPI expRtlZeroMemory(void *p, size_t len)
2195 void* result=memset(p,0,len);
2196 dbgprintf("RtlZeroMemory(0x%x, len %d) => 0x%x\n",p,len,result);
2197 return result;
2199 static void * WINAPI expRtlMoveMemory(void *dst, void *src, size_t len)
2201 void* result=memmove(dst,src,len);
2202 dbgprintf("RtlMoveMemory (dest 0x%x, src 0x%x, len %d) => 0x%x\n",dst,src,len,result);
2203 return result;
2206 static void * WINAPI expRtlFillMemory(void *p, int ch, size_t len)
2208 void* result=memset(p,ch,len);
2209 dbgprintf("RtlFillMemory(0x%x, char 0x%x, len %d) => 0x%x\n",p,ch,len,result);
2210 return result;
2212 static int WINAPI expFreeEnvironmentStringsW(short* strings)
2214 dbgprintf("FreeEnvironmentStringsW(0x%x) => 1\n", strings);
2215 return 1;
2217 static int WINAPI expFreeEnvironmentStringsA(char* strings)
2219 dbgprintf("FreeEnvironmentStringsA(0x%x) => 1\n", strings);
2220 return 1;
2223 static const char ch_envs[]=
2224 "__MSVCRT_HEAP_SELECT=__GLOBAL_HEAP_SELECTED,1\r\n"
2225 "PATH=C:\\;C:\\windows\\;C:\\windows\\system\r\n";
2226 static LPCSTR WINAPI expGetEnvironmentStrings()
2228 dbgprintf("GetEnvironmentStrings() => 0x%x\n", ch_envs);
2229 return (LPCSTR)ch_envs;
2230 // dbgprintf("GetEnvironmentStrings() => 0\n");
2231 // return 0;
2234 static int WINAPI expGetStartupInfoA(STARTUPINFOA *s)
2236 int i;
2237 dbgprintf("GetStartupInfoA(0x%x) => 1\n");
2238 memset(s, 0, sizeof(*s));
2239 s->cb=sizeof(*s);
2240 // s->lpReserved="Reserved";
2241 // s->lpDesktop="Desktop";
2242 // s->lpTitle="Title";
2243 // s->dwX=s->dwY=0;
2244 // s->dwXSize=s->dwYSize=200;
2245 s->dwFlags=s->wShowWindow=1;
2246 // s->hStdInput=s->hStdOutput=s->hStdError=0x1234;
2247 dbgprintf(" cb=%d\n", s->cb);
2248 dbgprintf(" lpReserved='%s'\n", s->lpReserved);
2249 dbgprintf(" lpDesktop='%s'\n", s->lpDesktop);
2250 dbgprintf(" lpTitle='%s'\n", s->lpTitle);
2251 dbgprintf(" dwX=%d dwY=%d dwXSize=%d dwYSize=%d\n",
2252 s->dwX, s->dwY, s->dwXSize, s->dwYSize);
2253 dbgprintf(" dwXCountChars=%d dwYCountChars=%d dwFillAttribute=%d\n",
2254 s->dwXCountChars, s->dwYCountChars, s->dwFillAttribute);
2255 dbgprintf(" dwFlags=0x%x wShowWindow=0x%x cbReserved2=0x%x\n",
2256 s->dwFlags, s->wShowWindow, s->cbReserved2);
2257 dbgprintf(" lpReserved2=0x%x hStdInput=0x%x hStdOutput=0x%x hStdError=0x%x\n",
2258 s->lpReserved2, s->hStdInput, s->hStdOutput, s->hStdError);
2259 return 1;
2262 static int WINAPI expGetStdHandle(int z)
2264 dbgprintf("GetStdHandle(0x%x) => 0x%x\n", z+0x1234);
2265 return z+0x1234;
2268 #ifdef QTX
2269 #define FILE_HANDLE_quicktimeqts ((HANDLE)0x444)
2270 #define FILE_HANDLE_quicktimeqtx ((HANDLE)0x445)
2271 #endif
2273 static int WINAPI expGetFileType(int handle)
2275 dbgprintf("GetFileType(0x%x) => 0x3 = pipe\n", handle);
2276 return 0x3;
2278 #ifdef QTX
2279 static int WINAPI expGetFileAttributesA(char *filename)
2281 dbgprintf("GetFileAttributesA(%s) => FILE_ATTR_NORMAL\n", filename);
2282 if (strstr(filename, "QuickTime.qts"))
2283 return FILE_ATTRIBUTE_SYSTEM;
2284 return FILE_ATTRIBUTE_NORMAL;
2286 #endif
2287 static int WINAPI expSetHandleCount(int count)
2289 dbgprintf("SetHandleCount(0x%x) => 1\n", count);
2290 return 1;
2292 static int WINAPI expGetACP(void)
2294 dbgprintf("GetACP() => 0\n");
2295 return 0;
2297 extern WINE_MODREF *MODULE32_LookupHMODULE(HMODULE m);
2298 static int WINAPI expGetModuleFileNameA(int module, char* s, int len)
2300 WINE_MODREF *mr;
2301 int result;
2302 //printf("File name of module %X (%s) requested\n", module, s);
2304 if (module == 0 && len >= 12)
2306 /* return caller program name */
2307 strcpy(s, "aviplay.dll");
2308 result=1;
2310 else if(s==0)
2311 result=0;
2312 else
2313 if(len<35)
2314 result=0;
2315 else
2317 result=1;
2318 strcpy(s, "c:\\windows\\system\\");
2319 mr=MODULE32_LookupHMODULE(module);
2320 if(mr==0)//oops
2321 strcat(s, "aviplay.dll");
2322 else
2323 if(strrchr(mr->filename, '/')==NULL)
2324 strcat(s, mr->filename);
2325 else
2326 strcat(s, strrchr(mr->filename, '/')+1);
2328 if(!s)
2329 dbgprintf("GetModuleFileNameA(0x%x, 0x%x, %d) => %d\n",
2330 module, s, len, result);
2331 else
2332 dbgprintf("GetModuleFileNameA(0x%x, 0x%x, %d) => %d ( '%s' )\n",
2333 module, s, len, result, s);
2334 return result;
2337 static int WINAPI expSetUnhandledExceptionFilter(void* filter)
2339 dbgprintf("SetUnhandledExceptionFilter(0x%x) => 1\n", filter);
2340 return 1;//unsupported and probably won't ever be supported
2343 static int WINAPI expLoadLibraryA(char* name)
2345 int result = 0;
2346 char* lastbc;
2347 int i;
2348 if (!name)
2349 return -1;
2350 // we skip to the last backslash
2351 // this is effectively eliminating weird characters in
2352 // the text output windows
2354 lastbc = strrchr(name, '\\');
2355 if (lastbc)
2357 int i;
2358 lastbc++;
2359 for (i = 0; 1 ;i++)
2361 name[i] = *lastbc++;
2362 if (!name[i])
2363 break;
2366 if(strncmp(name, "c:\\windows\\", 11)==0) name += 11;
2367 if(strncmp(name, ".\\", 2)==0) name += 2;
2369 dbgprintf("Entering LoadLibraryA(%s)\n", name);
2371 // PIMJ and VIVO audio are loading kernel32.dll
2372 if (strcasecmp(name, "kernel32.dll") == 0 || strcasecmp(name, "kernel32") == 0)
2373 return MODULE_HANDLE_kernel32;
2374 // return ERROR_SUCCESS; /* yeah, we have also the kernel32 calls */
2375 /* exported -> do not return failed! */
2377 if (strcasecmp(name, "user32.dll") == 0 || strcasecmp(name, "user32") == 0)
2378 // return MODULE_HANDLE_kernel32;
2379 return MODULE_HANDLE_user32;
2381 #ifdef QTX
2382 if (strcasecmp(name, "wininet.dll") == 0 || strcasecmp(name, "wininet") == 0)
2383 return MODULE_HANDLE_wininet;
2384 if (strcasecmp(name, "ddraw.dll") == 0 || strcasecmp(name, "ddraw") == 0)
2385 return MODULE_HANDLE_ddraw;
2386 if (strcasecmp(name, "advapi32.dll") == 0 || strcasecmp(name, "advapi32") == 0)
2387 return MODULE_HANDLE_advapi32;
2388 #endif
2390 if (strcasecmp(name, "comdlg32.dll") == 0 || strcasecmp(name, "comdlg32") == 0)
2391 return MODULE_HANDLE_comdlg32;
2392 if (strcasecmp(name, "msvcrt.dll") == 0 || strcasecmp(name, "msvcrt") == 0)
2393 return MODULE_HANDLE_msvcrt;
2394 if (strcasecmp(name, "ole32.dll") == 0 || strcasecmp(name, "ole32") == 0)
2395 return MODULE_HANDLE_ole32;
2396 if (strcasecmp(name, "winmm.dll") == 0 || strcasecmp(name, "winmm") == 0)
2397 return MODULE_HANDLE_winmm;
2399 result=LoadLibraryA(name);
2400 dbgprintf("Returned LoadLibraryA(0x%x='%s'), def_path=%s => 0x%x\n", name, name, def_path, result);
2402 return result;
2405 static int WINAPI expFreeLibrary(int module)
2407 #ifdef QTX
2408 int result=0; /* FIXME:XXX: qtx svq3 frees up qt.qts */
2409 #else
2410 int result=FreeLibrary(module);
2411 #endif
2412 dbgprintf("FreeLibrary(0x%x) => %d\n", module, result);
2413 return result;
2416 static void* WINAPI expGetProcAddress(HMODULE mod, char* name)
2418 void* result;
2419 switch(mod){
2420 case MODULE_HANDLE_kernel32:
2421 result=LookupExternalByName("kernel32.dll", name); break;
2422 case MODULE_HANDLE_user32:
2423 result=LookupExternalByName("user32.dll", name); break;
2424 #ifdef QTX
2425 case MODULE_HANDLE_wininet:
2426 result=LookupExternalByName("wininet.dll", name); break;
2427 case MODULE_HANDLE_ddraw:
2428 result=LookupExternalByName("ddraw.dll", name); break;
2429 case MODULE_HANDLE_advapi32:
2430 result=LookupExternalByName("advapi32.dll", name); break;
2431 #endif
2432 case MODULE_HANDLE_comdlg32:
2433 result=LookupExternalByName("comdlg32.dll", name); break;
2434 case MODULE_HANDLE_msvcrt:
2435 result=LookupExternalByName("msvcrt.dll", name); break;
2436 case MODULE_HANDLE_ole32:
2437 result=LookupExternalByName("ole32.dll", name); break;
2438 case MODULE_HANDLE_winmm:
2439 result=LookupExternalByName("winmm.dll", name); break;
2440 default:
2441 result=GetProcAddress(mod, name);
2443 dbgprintf("GetProcAddress(0x%x, '%s') => 0x%x\n", mod, name, result);
2444 return result;
2447 static long WINAPI expCreateFileMappingA(int hFile, void* lpAttr,
2448 long flProtect, long dwMaxHigh,
2449 long dwMaxLow, const char* name)
2451 long result=CreateFileMappingA(hFile, lpAttr, flProtect, dwMaxHigh, dwMaxLow, name);
2452 if(!name)
2453 dbgprintf("CreateFileMappingA(file 0x%x, lpAttr 0x%x,"
2454 "flProtect 0x%x, dwMaxHigh 0x%x, dwMaxLow 0x%x, name 0) => %d\n",
2455 hFile, lpAttr, flProtect, dwMaxHigh, dwMaxLow, result);
2456 else
2457 dbgprintf("CreateFileMappingA(file 0x%x, lpAttr 0x%x,"
2458 "flProtect 0x%x, dwMaxHigh 0x%x, dwMaxLow 0x%x, name 0x%x='%s') => %d\n",
2459 hFile, lpAttr, flProtect, dwMaxHigh, dwMaxLow, name, name, result);
2460 return result;
2463 static long WINAPI expOpenFileMappingA(long hFile, long hz, const char* name)
2465 long result=OpenFileMappingA(hFile, hz, name);
2466 if(!name)
2467 dbgprintf("OpenFileMappingA(0x%x, 0x%x, 0) => %d\n",
2468 hFile, hz, result);
2469 else
2470 dbgprintf("OpenFileMappingA(0x%x, 0x%x, 0x%x='%s') => %d\n",
2471 hFile, hz, name, name, result);
2472 return result;
2475 static void* WINAPI expMapViewOfFile(HANDLE file, DWORD mode, DWORD offHigh,
2476 DWORD offLow, DWORD size)
2478 dbgprintf("MapViewOfFile(0x%x, 0x%x, 0x%x, 0x%x, size %d) => 0x%x\n",
2479 file,mode,offHigh,offLow,size,(char*)file+offLow);
2480 return (char*)file+offLow;
2483 static void* WINAPI expUnmapViewOfFile(void* view)
2485 dbgprintf("UnmapViewOfFile(0x%x) => 0\n", view);
2486 return 0;
2489 static void* WINAPI expSleep(int time)
2491 #if HAVE_NANOSLEEP
2492 /* solaris doesn't have thread safe usleep */
2493 struct timespec tsp;
2494 tsp.tv_sec = time / 1000000;
2495 tsp.tv_nsec = (time % 1000000) * 1000;
2496 nanosleep(&tsp, NULL);
2497 #else
2498 usleep(time);
2499 #endif
2500 dbgprintf("Sleep(%d) => 0\n", time);
2501 return 0;
2504 // why does IV32 codec want to call this? I don't know ...
2505 static int WINAPI expCreateCompatibleDC(int hdc)
2507 int dc = 0;//0x81;
2508 //dbgprintf("CreateCompatibleDC(%d) => 0x81\n", hdc);
2509 dbgprintf("CreateCompatibleDC(%d) => %d\n", hdc, dc);
2510 return dc;
2513 static int WINAPI expGetDeviceCaps(int hdc, int unk)
2515 dbgprintf("GetDeviceCaps(0x%x, %d) => 0\n", hdc, unk);
2516 #ifdef QTX
2517 #define BITSPIXEL 12
2518 #define PLANES 14
2519 if (unk == BITSPIXEL)
2520 return 24;
2521 if (unk == PLANES)
2522 return 1;
2523 #endif
2524 return 1;
2527 static WIN_BOOL WINAPI expDeleteDC(int hdc)
2529 dbgprintf("DeleteDC(0x%x) => 0\n", hdc);
2530 if (hdc == 0x81)
2531 return 1;
2532 return 0;
2535 static WIN_BOOL WINAPI expDeleteObject(int hdc)
2537 dbgprintf("DeleteObject(0x%x) => 1\n", hdc);
2538 /* FIXME - implement code here */
2539 return 1;
2542 /* btvvc32.drv wants this one */
2543 static void* WINAPI expGetWindowDC(int hdc)
2545 dbgprintf("GetWindowDC(%d) => 0x0\n", hdc);
2546 return 0;
2549 #ifdef QTX
2550 static int WINAPI expGetWindowRect(HWND win, RECT *r)
2552 dbgprintf("GetWindowRect(0x%x, 0x%x) => 1\n", win, r);
2553 /* (win == 0) => desktop */
2554 r->right = PSEUDO_SCREEN_WIDTH;
2555 r->left = 0;
2556 r->bottom = PSEUDO_SCREEN_HEIGHT;
2557 r->top = 0;
2558 return 1;
2561 static int WINAPI expMonitorFromWindow(HWND win, int flags)
2563 dbgprintf("MonitorFromWindow(0x%x, 0x%x) => 0\n", win, flags);
2564 return 0;
2567 static int WINAPI expMonitorFromRect(RECT *r, int flags)
2569 dbgprintf("MonitorFromRect(0x%x, 0x%x) => 0\n", r, flags);
2570 return 0;
2573 static int WINAPI expMonitorFromPoint(void *p, int flags)
2575 dbgprintf("MonitorFromPoint(0x%x, 0x%x) => 0\n", p, flags);
2576 return 0;
2579 static int WINAPI expEnumDisplayMonitors(void *dc, RECT *r,
2580 int WINAPI (*callback_proc)(), void *callback_param)
2582 dbgprintf("EnumDisplayMonitors(0x%x, 0x%x, 0x%x, 0x%x) => ?\n",
2583 dc, r, callback_proc, callback_param);
2584 return callback_proc(0, dc, r, callback_param);
2587 #if 0
2588 typedef struct tagMONITORINFO {
2589 DWORD cbSize;
2590 RECT rcMonitor;
2591 RECT rcWork;
2592 DWORD dwFlags;
2593 } MONITORINFO, *LPMONITORINFO;
2594 #endif
2596 #define CCHDEVICENAME 8
2597 typedef struct tagMONITORINFOEX {
2598 DWORD cbSize;
2599 RECT rcMonitor;
2600 RECT rcWork;
2601 DWORD dwFlags;
2602 TCHAR szDevice[CCHDEVICENAME];
2603 } MONITORINFOEX, *LPMONITORINFOEX;
2605 static int WINAPI expGetMonitorInfoA(void *mon, LPMONITORINFO lpmi)
2607 dbgprintf("GetMonitorInfoA(0x%x, 0x%x) => 1\n", mon, lpmi);
2609 lpmi->rcMonitor.right = lpmi->rcWork.right = PSEUDO_SCREEN_WIDTH;
2610 lpmi->rcMonitor.left = lpmi->rcWork.left = 0;
2611 lpmi->rcMonitor.bottom = lpmi->rcWork.bottom = PSEUDO_SCREEN_HEIGHT;
2612 lpmi->rcMonitor.top = lpmi->rcWork.top = 0;
2614 lpmi->dwFlags = 1; /* primary monitor */
2616 if (lpmi->cbSize == sizeof(MONITORINFOEX))
2618 LPMONITORINFOEX lpmiex = (LPMONITORINFOEX)lpmi;
2619 dbgprintf("MONITORINFOEX!\n");
2620 strncpy(lpmiex->szDevice, "Monitor1", CCHDEVICENAME);
2623 return 1;
2626 static int WINAPI expEnumDisplayDevicesA(const char *device, int devnum,
2627 void *dispdev, int flags)
2629 dbgprintf("EnumDisplayDevicesA(0x%x = %s, %d, 0x%x, %x) => 1\n",
2630 device, device, devnum, dispdev, flags);
2631 return 1;
2634 static int WINAPI expIsWindowVisible(HWND win)
2636 dbgprintf("IsWindowVisible(0x%x) => 1\n", win);
2637 return 1;
2640 static HWND WINAPI expGetActiveWindow(void)
2642 dbgprintf("GetActiveWindow() => 0\n");
2643 return (HWND)0;
2646 static int WINAPI expGetClassNameA(HWND win, LPTSTR classname, int maxcount)
2648 strncat(classname, "QuickTime", maxcount);
2649 dbgprintf("GetClassNameA(0x%x, 0x%x, %d) => %d\n",
2650 win, classname, maxcount, strlen(classname));
2651 return strlen(classname);
2654 #define LPWNDCLASS void *
2655 static int WINAPI expGetClassInfoA(HINSTANCE inst, LPCSTR classname, LPWNDCLASS wndclass)
2657 dbgprintf("GetClassInfoA(0x%x, 0x%x = %s, 0x%x) => 1\n", inst,
2658 classname, classname, wndclass);
2659 return 1;
2662 static int WINAPI expGetWindowLongA(HWND win, int index)
2664 dbgprintf("GetWindowLongA(0x%x, %d) => 0\n", win, index);
2665 return 1;
2668 static int WINAPI expGetObjectA(HGDIOBJ hobj, int objsize, LPVOID obj)
2670 dbgprintf("GetObjectA(0x%x, %d, 0x%x) => %d\n", hobj, objsize, obj, objsize);
2671 return objsize;
2674 static int WINAPI expCreateRectRgn(int x, int y, int width, int height)
2676 dbgprintf("CreateRectRgn(%d, %d, %d, %d) => 0\n", x, y, width, height);
2677 return 0;
2680 static int WINAPI expEnumWindows(int (*callback_func)(), void *callback_param)
2682 int i, i2;
2683 dbgprintf("EnumWindows(0x%x, 0x%x) => 1\n", callback_func, callback_param);
2684 i = callback_func(0, callback_param);
2685 i2 = callback_func(1, callback_param);
2686 return i && i2;
2689 static int WINAPI expGetWindowThreadProcessId(HWND win, int *pid_data)
2691 int tid = pthread_self();
2692 dbgprintf("GetWindowThreadProcessId(0x%x, 0x%x) => %d\n",
2693 win, pid_data, tid);
2694 if (pid_data)
2695 *(int*)pid_data = tid;
2696 return tid;
2699 //HWND WINAPI CreateWindowExA(DWORD,LPCSTR,LPCSTR,DWORD,INT,INT,
2700 // INT,INT,HWND,HMENU,HINSTANCE,LPVOID);
2702 static HWND WINAPI expCreateWindowExA(int exstyle, const char *classname,
2703 const char *winname, int style, int x, int y, int w, int h,
2704 HWND parent, HMENU menu, HINSTANCE inst, LPVOID param)
2706 printf("CreateWindowEx() called\n");
2707 dbgprintf("CreateWindowEx(%d, 0x%x = %s, 0x%x = %s, %d, %d, %d, %d, %d, 0x%x, 0x%x, 0x%x, 0x%x) => 1\n",
2708 exstyle, classname, classname, winname, winname, style, x, y, w, h,
2709 parent, menu, inst, param);
2710 printf("CreateWindowEx() called okey\n");
2711 return 1;
2714 static int WINAPI expwaveOutGetNumDevs(void)
2716 dbgprintf("waveOutGetNumDevs() => 0\n");
2717 return 0;
2719 #endif
2722 * Returns the number of milliseconds, modulo 2^32, since the start
2723 * of the wineserver.
2725 static int WINAPI expGetTickCount(void)
2727 static int tcstart = 0;
2728 struct timeval t;
2729 int tc;
2730 gettimeofday( &t, NULL );
2731 tc = ((t.tv_sec * 1000) + (t.tv_usec / 1000)) - tcstart;
2732 if (tcstart == 0)
2734 tcstart = 0;
2735 tc = 0;
2737 dbgprintf("GetTickCount() => %d\n", tc);
2738 return tc;
2741 static int WINAPI expCreateFontA(void)
2743 dbgprintf("CreateFontA() => 0x0\n");
2744 return 1;
2747 /* tried to get pvmjpg work in a different way - no success */
2748 static int WINAPI expDrawTextA(int hDC, char* lpString, int nCount,
2749 LPRECT lpRect, unsigned int uFormat)
2751 dbgprintf("expDrawTextA(%p,...) => 8\n", hDC);
2752 return 8;
2755 static int WINAPI expGetPrivateProfileIntA(const char* appname,
2756 const char* keyname,
2757 int default_value,
2758 const char* filename)
2760 int size=255;
2761 char buffer[256];
2762 char* fullname;
2763 int result;
2765 buffer[255]=0;
2766 if(!(appname && keyname && filename) )
2768 dbgprintf("GetPrivateProfileIntA('%s', '%s', %d, '%s') => %d\n", appname, keyname, default_value, filename, default_value );
2769 return default_value;
2771 fullname=(char*)malloc(50+strlen(appname)+strlen(keyname)+strlen(filename));
2772 strcpy(fullname, "Software\\IniFileMapping\\");
2773 strcat(fullname, appname);
2774 strcat(fullname, "\\");
2775 strcat(fullname, keyname);
2776 strcat(fullname, "\\");
2777 strcat(fullname, filename);
2778 result=RegQueryValueExA(HKEY_LOCAL_MACHINE, fullname, NULL, NULL, (int*)buffer, &size);
2779 if((size>=0)&&(size<256))
2780 buffer[size]=0;
2781 // printf("GetPrivateProfileIntA(%s, %s, %s) -> %s\n", appname, keyname, filename, buffer);
2782 free(fullname);
2783 if(result)
2784 result=default_value;
2785 else
2786 result=atoi(buffer);
2787 dbgprintf("GetPrivateProfileIntA('%s', '%s', %d, '%s') => %d\n", appname, keyname, default_value, filename, result);
2788 return result;
2790 static int WINAPI expGetProfileIntA(const char* appname,
2791 const char* keyname,
2792 int default_value)
2794 dbgprintf("GetProfileIntA -> ");
2795 return expGetPrivateProfileIntA(appname, keyname, default_value, "default");
2798 static int WINAPI expGetPrivateProfileStringA(const char* appname,
2799 const char* keyname,
2800 const char* def_val,
2801 char* dest, unsigned int len,
2802 const char* filename)
2804 int result;
2805 int size;
2806 char* fullname;
2807 dbgprintf("GetPrivateProfileStringA('%s', '%s', def_val '%s', 0x%x, 0x%x, '%s')", appname, keyname, def_val, dest, len, filename );
2808 if(!(appname && keyname && filename) ) return 0;
2809 fullname=(char*)malloc(50+strlen(appname)+strlen(keyname)+strlen(filename));
2810 strcpy(fullname, "Software\\IniFileMapping\\");
2811 strcat(fullname, appname);
2812 strcat(fullname, "\\");
2813 strcat(fullname, keyname);
2814 strcat(fullname, "\\");
2815 strcat(fullname, filename);
2816 size=len;
2817 result=RegQueryValueExA(HKEY_LOCAL_MACHINE, fullname, NULL, NULL, (int*)dest, &size);
2818 free(fullname);
2819 if(result)
2821 strncpy(dest, def_val, size);
2822 if (strlen(def_val)< size) size = strlen(def_val);
2824 dbgprintf(" => %d ( '%s' )\n", size, dest);
2825 return size;
2827 static int WINAPI expWritePrivateProfileStringA(const char* appname,
2828 const char* keyname,
2829 const char* string,
2830 const char* filename)
2832 int size=256;
2833 char* fullname;
2834 dbgprintf("WritePrivateProfileStringA('%s', '%s', '%s', '%s')", appname, keyname, string, filename );
2835 if(!(appname && keyname && filename) )
2837 dbgprintf(" => -1\n");
2838 return -1;
2840 fullname=(char*)malloc(50+strlen(appname)+strlen(keyname)+strlen(filename));
2841 strcpy(fullname, "Software\\IniFileMapping\\");
2842 strcat(fullname, appname);
2843 strcat(fullname, "\\");
2844 strcat(fullname, keyname);
2845 strcat(fullname, "\\");
2846 strcat(fullname, filename);
2847 RegSetValueExA(HKEY_LOCAL_MACHINE, fullname, 0, REG_SZ, (int*)string, strlen(string));
2848 // printf("RegSetValueExA(%s,%d)\n", string, strlen(string));
2849 // printf("WritePrivateProfileStringA(%s, %s, %s, %s)\n", appname, keyname, string, filename );
2850 free(fullname);
2851 dbgprintf(" => 0\n");
2852 return 0;
2855 unsigned int _GetPrivateProfileIntA(const char* appname, const char* keyname, INT default_value, const char* filename)
2857 return expGetPrivateProfileIntA(appname, keyname, default_value, filename);
2859 int _GetPrivateProfileStringA(const char* appname, const char* keyname,
2860 const char* def_val, char* dest, unsigned int len, const char* filename)
2862 return expGetPrivateProfileStringA(appname, keyname, def_val, dest, len, filename);
2864 int _WritePrivateProfileStringA(const char* appname, const char* keyname,
2865 const char* string, const char* filename)
2867 return expWritePrivateProfileStringA(appname, keyname, string, filename);
2872 static int WINAPI expDefDriverProc(int _private, int id, int msg, int arg1, int arg2)
2874 dbgprintf("DefDriverProc(0x%x, 0x%x, 0x%x, 0x%x, 0x%x) => 0\n", _private, id, msg, arg1, arg2);
2875 return 0;
2878 static int WINAPI expSizeofResource(int v1, int v2)
2880 int result=SizeofResource(v1, v2);
2881 dbgprintf("SizeofResource(0x%x, 0x%x) => %d\n", v1, v2, result);
2882 return result;
2885 static int WINAPI expGetLastError()
2887 int result=GetLastError();
2888 dbgprintf("GetLastError() => 0x%x\n", result);
2889 return result;
2892 static void WINAPI expSetLastError(int error)
2894 dbgprintf("SetLastError(0x%x)\n", error);
2895 SetLastError(error);
2898 static int WINAPI expStringFromGUID2(GUID* guid, char* str, int cbMax)
2900 int result=snprintf(str, cbMax, "%.8x-%.4x-%.4x-%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x",
2901 guid->f1, guid->f2, guid->f3,
2902 (unsigned char)guid->f4[0], (unsigned char)guid->f4[1],
2903 (unsigned char)guid->f4[2], (unsigned char)guid->f4[3],
2904 (unsigned char)guid->f4[4], (unsigned char)guid->f4[5],
2905 (unsigned char)guid->f4[6], (unsigned char)guid->f4[7]);
2906 dbgprintf("StringFromGUID2(0x%x, 0x%x='%s', %d) => %d\n", guid, str, str, cbMax, result);
2907 return result;
2911 static int WINAPI expGetFileVersionInfoSizeA(const char* name, int* lpHandle)
2913 dbgprintf("GetFileVersionInfoSizeA(0x%x='%s', 0x%X) => 0\n", name, name, lpHandle);
2914 return 0;
2917 static int WINAPI expIsBadStringPtrW(const short* string, int nchars)
2919 int result;
2920 if(string==0)result=1; else result=0;
2921 dbgprintf("IsBadStringPtrW(0x%x, %d) => %d", string, nchars, result);
2922 if(string)wch_print(string);
2923 return result;
2925 static int WINAPI expIsBadStringPtrA(const char* string, int nchars)
2927 return expIsBadStringPtrW((const short*)string, nchars);
2929 static long WINAPI expInterlockedExchangeAdd( long* dest, long incr )
2931 long ret;
2932 __asm__ __volatile__
2934 "lock; xaddl %0,(%1)"
2935 : "=r" (ret)
2936 : "r" (dest), "0" (incr)
2937 : "memory"
2939 return ret;
2942 static long WINAPI expInterlockedCompareExchange( unsigned long* dest, unsigned long exchange, unsigned long comperand)
2944 unsigned long retval = *dest;
2945 if(*dest == comperand)
2946 *dest = exchange;
2947 return retval;
2950 static long WINAPI expInterlockedIncrement( long* dest )
2952 long result=expInterlockedExchangeAdd( dest, 1 ) + 1;
2953 dbgprintf("InterlockedIncrement(0x%x => %d) => %d\n", dest, *dest, result);
2954 return result;
2956 static long WINAPI expInterlockedDecrement( long* dest )
2958 long result=expInterlockedExchangeAdd( dest, -1 ) - 1;
2959 dbgprintf("InterlockedDecrement(0x%x => %d) => %d\n", dest, *dest, result);
2960 return result;
2963 static void WINAPI expOutputDebugStringA( const char* string )
2965 dbgprintf("OutputDebugStringA(0x%x='%s')\n", string);
2966 fprintf(stderr, "DEBUG: %s\n", string);
2969 static int WINAPI expGetDC(int hwnd)
2971 dbgprintf("GetDC(0x%x) => 1\n", hwnd);
2972 return 1;
2975 static int WINAPI expReleaseDC(int hwnd, int hdc)
2977 dbgprintf("ReleaseDC(0x%x, 0x%x) => 1\n", hwnd, hdc);
2978 return 1;
2981 static int WINAPI expGetDesktopWindow()
2983 dbgprintf("GetDesktopWindow() => 0\n");
2984 return 0;
2987 static int cursor[100];
2989 static int WINAPI expLoadCursorA(int handle,LPCSTR name)
2991 dbgprintf("LoadCursorA(%d, 0x%x='%s') => 0x%x\n", handle, name, (int)&cursor[0]);
2992 return (int)&cursor[0];
2994 static int WINAPI expSetCursor(void *cursor)
2996 dbgprintf("SetCursor(0x%x) => 0x%x\n", cursor, cursor);
2997 return (int)cursor;
2999 static int WINAPI expGetCursorPos(void *cursor)
3001 dbgprintf("GetCursorPos(0x%x) => 0x%x\n", cursor, cursor);
3002 return 1;
3004 #ifdef QTX
3005 static int show_cursor = 0;
3006 static int WINAPI expShowCursor(int show)
3008 dbgprintf("ShowCursor(%d) => %d\n", show, show);
3009 if (show)
3010 show_cursor++;
3011 else
3012 show_cursor--;
3013 return show_cursor;
3015 #endif
3016 static int WINAPI expRegisterWindowMessageA(char *message)
3018 dbgprintf("RegisterWindowMessageA(%s)\n", message);
3019 return 1;
3021 static int WINAPI expGetProcessVersion(int pid)
3023 dbgprintf("GetProcessVersion(%d)\n", pid);
3024 return 1;
3026 static int WINAPI expGetCurrentThread(void)
3028 #warning FIXME!
3029 dbgprintf("GetCurrentThread() => %x\n", 0xcfcf9898);
3030 return 0xcfcf9898;
3032 static int WINAPI expGetOEMCP(void)
3034 dbgprintf("GetOEMCP()\n");
3035 return 1;
3037 static int WINAPI expGetCPInfo(int cp,void *info)
3039 dbgprintf("GetCPInfo()\n");
3040 return 0;
3042 #ifdef QTX
3043 #define SM_CXSCREEN 0
3044 #define SM_CYSCREEN 1
3045 #define SM_XVIRTUALSCREEN 76
3046 #define SM_YVIRTUALSCREEN 77
3047 #define SM_CXVIRTUALSCREEN 78
3048 #define SM_CYVIRTUALSCREEN 79
3049 #define SM_CMONITORS 80
3050 #endif
3051 static int WINAPI expGetSystemMetrics(int index)
3053 dbgprintf("GetSystemMetrics(%d)\n", index);
3054 #ifdef QTX
3055 switch(index)
3057 case SM_XVIRTUALSCREEN:
3058 case SM_YVIRTUALSCREEN:
3059 return 0;
3060 case SM_CXSCREEN:
3061 case SM_CXVIRTUALSCREEN:
3062 return PSEUDO_SCREEN_WIDTH;
3063 case SM_CYSCREEN:
3064 case SM_CYVIRTUALSCREEN:
3065 return PSEUDO_SCREEN_HEIGHT;
3066 case SM_CMONITORS:
3067 return 1;
3069 #endif
3070 return 1;
3072 static int WINAPI expGetSysColor(int index)
3074 dbgprintf("GetSysColor(%d) => 1\n", index);
3075 return 1;
3077 static int WINAPI expGetSysColorBrush(int index)
3079 dbgprintf("GetSysColorBrush(%d)\n", index);
3080 return 1;
3085 static int WINAPI expGetSystemPaletteEntries(int hdc, int iStartIndex, int nEntries, void* lppe)
3087 dbgprintf("GetSystemPaletteEntries(0x%x, 0x%x, 0x%x, 0x%x) => 0\n",
3088 hdc, iStartIndex, nEntries, lppe);
3089 return 0;
3093 typedef struct _TIME_ZONE_INFORMATION {
3094 long Bias;
3095 char StandardName[32];
3096 SYSTEMTIME StandardDate;
3097 long StandardBias;
3098 char DaylightName[32];
3099 SYSTEMTIME DaylightDate;
3100 long DaylightBias;
3101 } TIME_ZONE_INFORMATION, *LPTIME_ZONE_INFORMATION;
3104 static int WINAPI expGetTimeZoneInformation(LPTIME_ZONE_INFORMATION lpTimeZoneInformation)
3106 const short name[]={'C', 'e', 'n', 't', 'r', 'a', 'l', ' ', 'S', 't', 'a',
3107 'n', 'd', 'a', 'r', 'd', ' ', 'T', 'i', 'm', 'e', 0};
3108 const short pname[]={'C', 'e', 'n', 't', 'r', 'a', 'l', ' ', 'D', 'a', 'y',
3109 'l', 'i', 'g', 'h', 't', ' ', 'T', 'i', 'm', 'e', 0};
3110 dbgprintf("GetTimeZoneInformation(0x%x) => TIME_ZONE_ID_STANDARD\n");
3111 memset(lpTimeZoneInformation, 0, sizeof(TIME_ZONE_INFORMATION));
3112 lpTimeZoneInformation->Bias=360;//GMT-6
3113 memcpy(lpTimeZoneInformation->StandardName, name, sizeof(name));
3114 lpTimeZoneInformation->StandardDate.wMonth=10;
3115 lpTimeZoneInformation->StandardDate.wDay=5;
3116 lpTimeZoneInformation->StandardDate.wHour=2;
3117 lpTimeZoneInformation->StandardBias=0;
3118 memcpy(lpTimeZoneInformation->DaylightName, pname, sizeof(pname));
3119 lpTimeZoneInformation->DaylightDate.wMonth=4;
3120 lpTimeZoneInformation->DaylightDate.wDay=1;
3121 lpTimeZoneInformation->DaylightDate.wHour=2;
3122 lpTimeZoneInformation->DaylightBias=-60;
3123 return TIME_ZONE_ID_STANDARD;
3126 static void WINAPI expGetLocalTime(SYSTEMTIME* systime)
3128 time_t local_time;
3129 struct tm *local_tm;
3130 struct timeval tv;
3132 dbgprintf("GetLocalTime(0x%x)\n");
3133 gettimeofday(&tv, NULL);
3134 local_time=tv.tv_sec;
3135 local_tm=localtime(&local_time);
3137 systime->wYear = local_tm->tm_year + 1900;
3138 systime->wMonth = local_tm->tm_mon + 1;
3139 systime->wDayOfWeek = local_tm->tm_wday;
3140 systime->wDay = local_tm->tm_mday;
3141 systime->wHour = local_tm->tm_hour;
3142 systime->wMinute = local_tm->tm_min;
3143 systime->wSecond = local_tm->tm_sec;
3144 systime->wMilliseconds = (tv.tv_usec / 1000) % 1000;
3145 dbgprintf(" Year: %d\n Month: %d\n Day of week: %d\n"
3146 " Day: %d\n Hour: %d\n Minute: %d\n Second: %d\n"
3147 " Milliseconds: %d\n",
3148 systime->wYear, systime->wMonth, systime->wDayOfWeek, systime->wDay,
3149 systime->wHour, systime->wMinute, systime->wSecond, systime->wMilliseconds);
3152 static int WINAPI expGetSystemTime(SYSTEMTIME* systime)
3154 time_t local_time;
3155 struct tm *local_tm;
3156 struct timeval tv;
3158 dbgprintf("GetSystemTime(0x%x)\n", systime);
3159 gettimeofday(&tv, NULL);
3160 local_time=tv.tv_sec;
3161 local_tm=gmtime(&local_time);
3163 systime->wYear = local_tm->tm_year + 1900;
3164 systime->wMonth = local_tm->tm_mon + 1;
3165 systime->wDayOfWeek = local_tm->tm_wday;
3166 systime->wDay = local_tm->tm_mday;
3167 systime->wHour = local_tm->tm_hour;
3168 systime->wMinute = local_tm->tm_min;
3169 systime->wSecond = local_tm->tm_sec;
3170 systime->wMilliseconds = (tv.tv_usec / 1000) % 1000;
3171 dbgprintf(" Year: %d\n Month: %d\n Day of week: %d\n"
3172 " Day: %d\n Hour: %d\n Minute: %d\n Second: %d\n"
3173 " Milliseconds: %d\n",
3174 systime->wYear, systime->wMonth, systime->wDayOfWeek, systime->wDay,
3175 systime->wHour, systime->wMinute, systime->wSecond, systime->wMilliseconds);
3176 return 0;
3179 #define SECS_1601_TO_1970 ((369 * 365 + 89) * 86400ULL)
3180 static void WINAPI expGetSystemTimeAsFileTime(FILETIME* systime)
3182 struct tm *local_tm;
3183 struct timeval tv;
3184 unsigned long long secs;
3186 dbgprintf("GetSystemTime(0x%x)\n", systime);
3187 gettimeofday(&tv, NULL);
3188 secs = (tv.tv_sec + SECS_1601_TO_1970) * 10000000;
3189 secs += tv.tv_usec * 10;
3190 systime->dwLowDateTime = secs & 0xffffffff;
3191 systime->dwHighDateTime = (secs >> 32);
3194 static int WINAPI expGetEnvironmentVariableA(const char* name, char* field, int size)
3196 char *p;
3197 // printf("%s %x %x\n", name, field, size);
3198 if(field)field[0]=0;
3200 p = getenv(name);
3201 if (p) strncpy(field,p,size);
3203 if (strcmp(name,"__MSVCRT_HEAP_SELECT")==0)
3204 strcpy(field,"__GLOBAL_HEAP_SELECTED,1");
3205 dbgprintf("GetEnvironmentVariableA(0x%x='%s', 0x%x, %d) => %d\n", name, name, field, size, strlen(field));
3206 return strlen(field);
3209 static int WINAPI expSetEnvironmentVariableA(const char *name, const char *value)
3211 dbgprintf("SetEnvironmentVariableA(%s, %s)\n", name, value);
3212 return 0;
3215 static void* WINAPI expCoTaskMemAlloc(ULONG cb)
3217 return my_mreq(cb, 0);
3219 static void WINAPI expCoTaskMemFree(void* cb)
3221 my_release(cb);
3227 void* CoTaskMemAlloc(unsigned long cb)
3229 return expCoTaskMemAlloc(cb);
3231 void CoTaskMemFree(void* cb)
3233 expCoTaskMemFree(cb);
3236 struct COM_OBJECT_INFO
3238 GUID clsid;
3239 long (*GetClassObject) (GUID* clsid, const GUID* iid, void** ppv);
3242 static struct COM_OBJECT_INFO* com_object_table=0;
3243 static int com_object_size=0;
3244 int RegisterComClass(const GUID* clsid, GETCLASSOBJECT gcs)
3246 if(!clsid || !gcs)
3247 return -1;
3248 com_object_table=realloc(com_object_table, sizeof(struct COM_OBJECT_INFO)*(++com_object_size));
3249 com_object_table[com_object_size-1].clsid=*clsid;
3250 com_object_table[com_object_size-1].GetClassObject=gcs;
3251 return 0;
3254 int UnregisterComClass(const GUID* clsid, GETCLASSOBJECT gcs)
3256 int found = 0;
3257 int i = 0;
3258 if(!clsid || !gcs)
3259 return -1;
3261 if (com_object_table == 0)
3262 printf("Warning: UnregisterComClass() called without any registered class\n");
3263 while (i < com_object_size)
3265 if (found && i > 0)
3267 memcpy(&com_object_table[i - 1].clsid,
3268 &com_object_table[i].clsid, sizeof(GUID));
3269 com_object_table[i - 1].GetClassObject =
3270 com_object_table[i].GetClassObject;
3272 else if (memcmp(&com_object_table[i].clsid, clsid, sizeof(GUID)) == 0
3273 && com_object_table[i].GetClassObject == gcs)
3275 found++;
3277 i++;
3279 if (found)
3281 if (--com_object_size == 0)
3283 free(com_object_table);
3284 com_object_table = 0;
3287 return 0;
3291 const GUID IID_IUnknown =
3293 0x00000000, 0x0000, 0x0000,
3294 {0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}
3296 const GUID IID_IClassFactory =
3298 0x00000001, 0x0000, 0x0000,
3299 {0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}
3302 static long WINAPI expCoCreateInstance(GUID* rclsid, struct IUnknown* pUnkOuter,
3303 long dwClsContext, const GUID* riid, void** ppv)
3305 int i;
3306 struct COM_OBJECT_INFO* ci=0;
3307 for(i=0; i<com_object_size; i++)
3308 if(!memcmp(rclsid, &com_object_table[i].clsid, sizeof(GUID)))
3309 ci=&com_object_table[i];
3310 if(!ci)return REGDB_E_CLASSNOTREG;
3311 // in 'real' world we should mess with IClassFactory here
3312 i=ci->GetClassObject(rclsid, riid, ppv);
3313 return i;
3316 long CoCreateInstance(GUID* rclsid, struct IUnknown* pUnkOuter,
3317 long dwClsContext, const GUID* riid, void** ppv)
3319 return expCoCreateInstance(rclsid, pUnkOuter, dwClsContext, riid, ppv);
3322 static int WINAPI expIsRectEmpty(CONST RECT *lprc)
3324 int r = 0;
3325 int w,h;
3326 //trapbug();
3327 if (lprc)
3329 w = lprc->right - lprc->left;
3330 h = lprc->bottom - lprc->top;
3331 if (w <= 0 || h <= 0)
3332 r = 1;
3334 else
3335 r = 1;
3337 dbgprintf("IsRectEmpty(%p) => %s\n", lprc, (r) ? "TRUE" : "FALSE");
3338 //printf("Rect: left: %d, top: %d, right: %d, bottom: %d\n", lprc->left, lprc->top, lprc->right, lprc->bottom);
3339 // return 0; // wmv9?
3340 return r; // TM20
3343 static int _adjust_fdiv=0; //what's this? - used to adjust division
3348 static unsigned int WINAPI expGetTempPathA(unsigned int len, char* path)
3350 dbgprintf("GetTempPathA(%d, 0x%x)", len, path);
3351 if(len<5)
3353 dbgprintf(" => 0\n");
3354 return 0;
3356 strcpy(path, "/tmp");
3357 dbgprintf(" => 5 ( '/tmp' )\n");
3358 return 5;
3361 FYI:
3362 typedef struct
3364 DWORD dwFileAttributes;
3365 FILETIME ftCreationTime;
3366 FILETIME ftLastAccessTime;
3367 FILETIME ftLastWriteTime;
3368 DWORD nFileSizeHigh;
3369 DWORD nFileSizeLow;
3370 DWORD dwReserved0;
3371 DWORD dwReserved1;
3372 CHAR cFileName[260];
3373 CHAR cAlternateFileName[14];
3374 } WIN32_FIND_DATAA, *LPWIN32_FIND_DATAA;
3377 static DIR* qtx_dir=NULL;
3379 static WIN_BOOL WINAPI expFindNextFileA(HANDLE h,LPWIN32_FIND_DATAA lpfd)
3381 #ifdef QTX
3382 dbgprintf("FindNextFileA(0x%x, 0x%x) => 0\n", h, lpfd);
3383 if(h==FILE_HANDLE_quicktimeqtx){
3384 struct dirent* d;
3385 if(!qtx_dir) return 0;
3386 while((d=readdir(qtx_dir))){
3387 char* x=strrchr(d->d_name,'.');
3388 if(!x) continue;
3389 if(strcmp(x,".qtx")) continue;
3390 strcpy(lpfd->cFileName,d->d_name);
3391 // sprintf(lpfd->cAlternateFileName,"%-8s.qtx",d->d_name);
3392 strcpy(lpfd->cAlternateFileName,"foobar.qtx");
3393 printf("### FindNext: %s\n",lpfd->cFileName);
3394 return 1;
3396 closedir(qtx_dir); qtx_dir=NULL;
3397 return 0;
3399 #endif
3400 return 0;
3403 static HANDLE WINAPI expFindFirstFileA(LPCSTR s, LPWIN32_FIND_DATAA lpfd)
3405 dbgprintf("FindFirstFileA(0x%x='%s', 0x%x) => 0\n", s, s, lpfd);
3406 // printf("\n### FindFirstFileA('%s')...\n",s);
3407 #ifdef QTX
3408 if(strstr(s, "quicktime\\*.QTX")){
3409 dbgprintf("FindFirstFileA(0x%x='%s', 0x%x) => QTX\n", s, s, lpfd);
3410 printf("\n### Searching for QuickTime plugins (*.qtx) at %s...\n",def_path);
3411 qtx_dir=opendir(def_path);
3412 if(!qtx_dir) return (HANDLE)-1;
3413 memset(lpfd,0,sizeof(*lpfd));
3414 if(expFindNextFileA(FILE_HANDLE_quicktimeqtx,lpfd))
3415 return FILE_HANDLE_quicktimeqtx;
3416 printf("loader: Couldn't find the QuickTime plugins (.qtx files) at %s\n",def_path);
3417 return (HANDLE)-1;
3419 #if 0
3420 if(strstr(s, "QuickTime.qts")){
3421 dbgprintf("FindFirstFileA(0x%x='%s', 0x%x) => QTS\n", s, s, lpfd);
3422 // if(!strcmp(s,"C:\\windows\\QuickTime.qts\\QuickTime.qts\\*.QTX"))
3423 // return (HANDLE)-1;
3424 strcpy(lpfd->cFileName, "QuickTime.qts");
3425 strcpy(lpfd->cAlternateFileName, "QuickT~1.qts");
3426 return FILE_HANDLE_quicktimeqts;
3428 #endif
3429 #endif
3430 if(strstr(s, "*.vwp")){
3431 // hack for VoxWare codec plugins:
3432 strcpy(lpfd->cFileName, "msms001.vwp");
3433 strcpy(lpfd->cAlternateFileName, "msms001.vwp");
3434 return (HANDLE)0;
3436 // return 'file not found'
3437 return (HANDLE)-1;
3440 static WIN_BOOL WINAPI expFindClose(HANDLE h)
3442 dbgprintf("FindClose(0x%x) => 0\n", h);
3443 #ifdef QTX
3444 // if(h==FILE_HANDLE_quicktimeqtx && qtx_dir){
3445 // closedir(qtx_dir);
3446 // qtx_dir=NULL;
3447 // }
3448 #endif
3449 return 0;
3451 static UINT WINAPI expSetErrorMode(UINT i)
3453 dbgprintf("SetErrorMode(%d) => 0\n", i);
3454 return 0;
3456 static UINT WINAPI expGetWindowsDirectoryA(LPSTR s,UINT c)
3458 char windir[]="c:\\windows";
3459 int result;
3460 strncpy(s, windir, c);
3461 result=1+((c<strlen(windir))?c:strlen(windir));
3462 dbgprintf("GetWindowsDirectoryA(0x%x, %d) => %d\n", s, c, result);
3463 return result;
3465 #ifdef QTX
3466 static UINT WINAPI expGetCurrentDirectoryA(UINT c, LPSTR s)
3468 char curdir[]="c:\\";
3469 int result;
3470 strncpy(s, curdir, c);
3471 result=1+((c<strlen(curdir))?c:strlen(curdir));
3472 dbgprintf("GetCurrentDirectoryA(0x%x, %d) => %d\n", s, c, result);
3473 return result;
3476 static int WINAPI expSetCurrentDirectoryA(const char *pathname)
3478 dbgprintf("SetCurrentDirectoryA(0x%x = %s) => 1\n", pathname, pathname);
3479 #if 0
3480 if (strrchr(pathname, '\\'))
3481 chdir(strcat(strrchr(pathname, '\\')+1, '/'));
3482 else
3483 chdir(pathname);
3484 #endif
3485 return 1;
3488 static int WINAPI expCreateDirectoryA(const char *pathname, void *sa)
3490 dbgprintf("CreateDirectory(0x%x = %s, 0x%x) => 1\n",
3491 pathname, pathname, sa);
3492 #if 0
3493 p = strrchr(pathname, '\\')+1;
3494 strcpy(&buf[0], p); /* should be strncpy */
3495 if (!strlen(p))
3497 buf[0] = '.';
3498 buf[1] = 0;
3500 #if 0
3501 if (strrchr(pathname, '\\'))
3502 mkdir(strcat(strrchr(pathname, '\\')+1, '/'), 666);
3503 else
3504 mkdir(pathname, 666);
3505 #endif
3506 mkdir(&buf);
3507 #endif
3508 return 1;
3510 #endif
3511 static WIN_BOOL WINAPI expDeleteFileA(LPCSTR s)
3513 dbgprintf("DeleteFileA(0x%x='%s') => 0\n", s, s);
3514 return 0;
3516 static WIN_BOOL WINAPI expFileTimeToLocalFileTime(const FILETIME* cpf, LPFILETIME pf)
3518 dbgprintf("FileTimeToLocalFileTime(0x%x, 0x%x) => 0\n", cpf, pf);
3519 return 0;
3522 static UINT WINAPI expGetTempFileNameA(LPCSTR cs1,LPCSTR cs2,UINT i,LPSTR ps)
3524 char mask[16]="/tmp/AP_XXXXXX";
3525 int result;
3526 dbgprintf("GetTempFileNameA(0x%x='%s', 0x%x='%s', %d, 0x%x)", cs1, cs1, cs2, cs2, i, ps);
3527 if(i && i<10)
3529 dbgprintf(" => -1\n");
3530 return -1;
3532 result=mkstemp(mask);
3533 sprintf(ps, "AP%d", result);
3534 dbgprintf(" => %d\n", strlen(ps));
3535 return strlen(ps);
3538 // This func might need proper implementation if we want AngelPotion codec.
3539 // They try to open APmpeg4v1.apl with it.
3540 // DLL will close opened file with CloseHandle().
3542 static HANDLE WINAPI expCreateFileA(LPCSTR cs1,DWORD i1,DWORD i2,
3543 LPSECURITY_ATTRIBUTES p1, DWORD i3,DWORD i4,HANDLE i5)
3545 dbgprintf("CreateFileA(0x%x='%s', %d, %d, 0x%x, %d, %d, 0x%x)\n", cs1, cs1, i1,
3546 i2, p1, i3, i4, i5);
3547 if((!cs1) || (strlen(cs1)<2))return -1;
3549 #ifdef QTX
3550 if(strstr(cs1, "QuickTime.qts"))
3552 int result;
3553 char* tmp=(char*)malloc(strlen(def_path)+50);
3554 strcpy(tmp, def_path);
3555 strcat(tmp, "/");
3556 strcat(tmp, "QuickTime.qts");
3557 result=open(tmp, O_RDONLY);
3558 free(tmp);
3559 return result;
3561 if(strstr(cs1, ".qtx"))
3563 int result;
3564 char* tmp=(char*)malloc(strlen(def_path)+250);
3565 char* x=strrchr(cs1,'\\');
3566 sprintf(tmp,"%s/%s",def_path,x?(x+1):cs1);
3567 // printf("### Open: %s -> %s\n",cs1,tmp);
3568 result=open(tmp, O_RDONLY);
3569 free(tmp);
3570 return result;
3572 #endif
3574 if(strncmp(cs1, "AP", 2) == 0)
3576 int result;
3577 char* tmp=(char*)malloc(strlen(def_path)+50);
3578 strcpy(tmp, def_path);
3579 strcat(tmp, "/");
3580 strcat(tmp, "APmpg4v1.apl");
3581 result=open(tmp, O_RDONLY);
3582 free(tmp);
3583 return result;
3585 if (strstr(cs1, "vp3"))
3587 int r;
3588 int flg = 0;
3589 char* tmp=(char*)malloc(20 + strlen(cs1));
3590 strcpy(tmp, "/tmp/");
3591 strcat(tmp, cs1);
3592 r = 4;
3593 while (tmp[r])
3595 if (tmp[r] == ':' || tmp[r] == '\\')
3596 tmp[r] = '_';
3597 r++;
3599 if (GENERIC_READ & i1)
3600 flg |= O_RDONLY;
3601 else if (GENERIC_WRITE & i1)
3603 flg |= O_WRONLY;
3604 printf("Warning: openning filename %s %d (flags; 0x%x) for write\n", tmp, r, flg);
3606 r=open(tmp, flg);
3607 free(tmp);
3608 return r;
3611 // Needed by wnvplay1.dll
3612 if (strstr(cs1, "WINNOV.bmp"))
3614 int r;
3615 r=open("/dev/null", 0);
3616 return r;
3619 #if 0
3620 /* we need this for some virtualdub filters */
3622 int r;
3623 int flg = 0;
3624 if (GENERIC_READ & i1)
3625 flg |= O_RDONLY;
3626 else if (GENERIC_WRITE & i1)
3628 flg |= O_WRONLY;
3629 printf("Warning: openning filename %s %d (flags; 0x%x) for write\n", cs1, r, flg);
3631 r=open(cs1, flg);
3632 return r;
3634 #endif
3636 return atoi(cs1+2);
3638 static UINT WINAPI expGetSystemDirectoryA(
3639 char* lpBuffer, // address of buffer for system directory
3640 UINT uSize // size of directory buffer
3642 dbgprintf("GetSystemDirectoryA(%p,%d)\n", lpBuffer,uSize);
3643 if(!lpBuffer) strcpy(lpBuffer,".");
3644 return 1;
3647 static char sysdir[]=".";
3648 static LPCSTR WINAPI expGetSystemDirectoryA()
3650 dbgprintf("GetSystemDirectoryA() => 0x%x='%s'\n", sysdir, sysdir);
3651 return sysdir;
3654 static DWORD WINAPI expGetFullPathNameA
3656 LPCTSTR lpFileName,
3657 DWORD nBufferLength,
3658 LPTSTR lpBuffer,
3659 LPTSTR lpFilePart
3661 if(!lpFileName) return 0;
3662 dbgprintf("GetFullPathNameA('%s',%d,%p,%p)\n",lpFileName,nBufferLength,
3663 lpBuffer, lpFilePart);
3664 #if 0
3665 #ifdef QTX
3666 strcpy(lpFilePart, "Quick123.qts");
3667 #else
3668 strcpy(lpFilePart, lpFileName);
3669 #endif
3670 #else
3671 if (strrchr(lpFileName, '\\'))
3672 lpFilePart = strrchr(lpFileName, '\\');
3673 else
3674 lpFilePart = (LPTSTR)lpFileName;
3675 #endif
3676 strcpy(lpBuffer, lpFileName);
3677 // strncpy(lpBuffer, lpFileName, rindex(lpFileName, '\\')-lpFileName);
3678 return strlen(lpBuffer);
3681 static DWORD WINAPI expGetShortPathNameA
3683 LPCSTR longpath,
3684 LPSTR shortpath,
3685 DWORD shortlen
3687 if(!longpath) return 0;
3688 dbgprintf("GetShortPathNameA('%s',%p,%d)\n",longpath,shortpath,shortlen);
3689 strcpy(shortpath,longpath);
3690 return strlen(shortpath);
3693 static WIN_BOOL WINAPI expReadFile(HANDLE h,LPVOID pv,DWORD size,LPDWORD rd,LPOVERLAPPED unused)
3695 int result;
3696 dbgprintf("ReadFile(%d, 0x%x, %d -> 0x%x)\n", h, pv, size, rd);
3697 result=read(h, pv, size);
3698 if(rd)*rd=result;
3699 if(!result)return 0;
3700 return 1;
3703 static WIN_BOOL WINAPI expWriteFile(HANDLE h,LPCVOID pv,DWORD size,LPDWORD wr,LPOVERLAPPED unused)
3705 int result;
3706 dbgprintf("WriteFile(%d, 0x%x, %d -> 0x%x)\n", h, pv, size, wr);
3707 if(h==1234)h=1;
3708 result=write(h, pv, size);
3709 if(wr)*wr=result;
3710 if(!result)return 0;
3711 return 1;
3713 static DWORD WINAPI expSetFilePointer(HANDLE h, LONG val, LPLONG ext, DWORD whence)
3715 int wh;
3716 dbgprintf("SetFilePointer(%d, 0x%x, 0x%x = %d, %d)\n", h, val, ext, *ext, whence);
3717 //why would DLL want temporary file with >2Gb size?
3718 switch(whence)
3720 case FILE_BEGIN:
3721 wh=SEEK_SET;break;
3722 case FILE_END:
3723 wh=SEEK_END;break;
3724 case FILE_CURRENT:
3725 wh=SEEK_CUR;break;
3726 default:
3727 return -1;
3729 #ifdef QTX
3730 if (val == 0 && ext != 0)
3731 val = val&(*ext);
3732 #endif
3733 return lseek(h, val, wh);
3736 static HDRVR WINAPI expOpenDriverA(LPCSTR szDriverName, LPCSTR szSectionName,
3737 LPARAM lParam2)
3739 dbgprintf("OpenDriverA(0x%x='%s', 0x%x='%s', 0x%x) => -1\n", szDriverName, szDriverName, szSectionName, szSectionName, lParam2);
3740 return -1;
3742 static HDRVR WINAPI expOpenDriver(LPCSTR szDriverName, LPCSTR szSectionName,
3743 LPARAM lParam2)
3745 dbgprintf("OpenDriver(0x%x='%s', 0x%x='%s', 0x%x) => -1\n", szDriverName, szDriverName, szSectionName, szSectionName, lParam2);
3746 return -1;
3750 static WIN_BOOL WINAPI expGetProcessAffinityMask(HANDLE hProcess,
3751 LPDWORD lpProcessAffinityMask,
3752 LPDWORD lpSystemAffinityMask)
3754 dbgprintf("GetProcessAffinityMask(0x%x, 0x%x, 0x%x) => 1\n",
3755 hProcess, lpProcessAffinityMask, lpSystemAffinityMask);
3756 if(lpProcessAffinityMask)*lpProcessAffinityMask=1;
3757 if(lpSystemAffinityMask)*lpSystemAffinityMask=1;
3758 return 1;
3761 static int WINAPI expMulDiv(int nNumber, int nNumerator, int nDenominator)
3763 static const long long max_int=0x7FFFFFFFLL;
3764 static const long long min_int=-0x80000000LL;
3765 long long tmp=(long long)nNumber*(long long)nNumerator;
3766 dbgprintf("expMulDiv %d * %d / %d\n", nNumber, nNumerator, nDenominator);
3767 if(!nDenominator)return 1;
3768 tmp/=nDenominator;
3769 if(tmp<min_int) return 1;
3770 if(tmp>max_int) return 1;
3771 return (int)tmp;
3774 static LONG WINAPI explstrcmpiA(const char* str1, const char* str2)
3776 LONG result=strcasecmp(str1, str2);
3777 dbgprintf("strcmpi(0x%x='%s', 0x%x='%s') => %d\n", str1, str1, str2, str2, result);
3778 return result;
3781 static LONG WINAPI explstrlenA(const char* str1)
3783 LONG result=strlen(str1);
3784 dbgprintf("strlen(0x%x='%.50s') => %d\n", str1, str1, result);
3785 return result;
3788 static LONG WINAPI explstrcpyA(char* str1, const char* str2)
3790 int result= (int) strcpy(str1, str2);
3791 dbgprintf("strcpy(0x%.50x, 0x%.50x='%.50s') => %d\n", str1, str2, str2, result);
3792 return result;
3794 static LONG WINAPI explstrcpynA(char* str1, const char* str2,int len)
3796 int result;
3797 if (strlen(str2)>len)
3798 result = (int) strncpy(str1, str2,len);
3799 else
3800 result = (int) strcpy(str1,str2);
3801 dbgprintf("strncpy(0x%x, 0x%x='%s' len %d strlen %d) => %x\n", str1, str2, str2,len, strlen(str2),result);
3802 return result;
3804 static LONG WINAPI explstrcatA(char* str1, const char* str2)
3806 int result= (int) strcat(str1, str2);
3807 dbgprintf("strcat(0x%x, 0x%x='%s') => %d\n", str1, str2, str2, result);
3808 return result;
3812 static LONG WINAPI expInterlockedExchange(long *dest, long l)
3814 long retval = *dest;
3815 *dest = l;
3816 return retval;
3819 static void WINAPI expInitCommonControls(void)
3821 dbgprintf("InitCommonControls called!\n");
3822 return;
3825 #ifdef QTX
3826 /* needed by QuickTime.qts */
3827 static HWND WINAPI expCreateUpDownControl (DWORD style, INT x, INT y, INT cx, INT cy,
3828 HWND parent, INT id, HINSTANCE inst,
3829 HWND buddy, INT maxVal, INT minVal, INT curVal)
3831 dbgprintf("CreateUpDownControl(...)\n");
3832 return 0;
3834 #endif
3836 /* alex: implement this call! needed for 3ivx */
3837 static HRESULT WINAPI expCoCreateFreeThreadedMarshaler(void *pUnkOuter, void **ppUnkInner)
3839 dbgprintf("CoCreateFreeThreadedMarshaler(%p, %p) called!\n",
3840 pUnkOuter, ppUnkInner);
3841 // return 0;
3842 return ERROR_CALL_NOT_IMPLEMENTED;
3846 static int WINAPI expDuplicateHandle(HANDLE hSourceProcessHandle, // handle to source process
3847 HANDLE hSourceHandle, // handle to duplicate
3848 HANDLE hTargetProcessHandle, // handle to target process
3849 HANDLE* lpTargetHandle, // duplicate handle
3850 DWORD dwDesiredAccess, // requested access
3851 int bInheritHandle, // handle inheritance option
3852 DWORD dwOptions // optional actions
3855 dbgprintf("DuplicateHandle(%p, %p, %p, %p, 0x%x, %d, %d) called\n",
3856 hSourceProcessHandle, hSourceHandle, hTargetProcessHandle,
3857 lpTargetHandle, dwDesiredAccess, bInheritHandle, dwOptions);
3858 *lpTargetHandle = hSourceHandle;
3859 return 1;
3862 // required by PIM1 codec (used by win98 PCTV Studio capture sw)
3863 static HRESULT WINAPI expCoInitialize(
3864 LPVOID lpReserved /* [in] pointer to win32 malloc interface
3865 (obsolete, should be NULL) */
3869 * Just delegate to the newer method.
3871 return 0; //CoInitializeEx(lpReserved, COINIT_APARTMENTTHREADED);
3874 static DWORD WINAPI expSetThreadAffinityMask
3876 HANDLE hThread,
3877 DWORD dwThreadAffinityMask
3879 return 0;
3883 * no WINAPI functions - CDECL
3885 static void* expmalloc(int size)
3887 //printf("malloc");
3888 // return malloc(size);
3889 void* result=my_mreq(size,0);
3890 dbgprintf("malloc(0x%x) => 0x%x\n", size,result);
3891 if(result==0)
3892 printf("WARNING: malloc() failed\n");
3893 return result;
3895 static void expfree(void* mem)
3897 // return free(mem);
3898 dbgprintf("free(%p)\n", mem);
3899 my_release(mem);
3901 /* needed by atrac3.acm */
3902 static void *expcalloc(int num, int size)
3904 void* result=my_mreq(num*size,1);
3905 dbgprintf("calloc(%d,%d) => %p\n", num,size,result);
3906 if(result==0)
3907 printf("WARNING: calloc() failed\n");
3908 return result;
3910 static void* expnew(int size)
3912 // printf("NEW:: Call from address %08x\n STACK DUMP:\n", *(-1+(int*)&size));
3913 // printf("%08x %08x %08x %08x\n",
3914 // size, *(1+(int*)&size),
3915 // *(2+(int*)&size),*(3+(int*)&size));
3916 void* result;
3917 assert(size >= 0);
3919 result=my_mreq(size,0);
3920 dbgprintf("new(%d) => %p\n", size, result);
3921 if (result==0)
3922 printf("WARNING: new() failed\n");
3923 return result;
3926 static int expdelete(void* memory)
3928 dbgprintf("delete(%p)\n", memory);
3929 my_release(memory);
3930 return 0;
3934 * local definition - we need only the last two members at this point
3935 * otherwice we would have to introduce here GUIDs and some more types..
3937 typedef struct __attribute__((__packed__))
3939 char hay[0x3C];
3940 void* pbUnknown; //0x3C
3941 unsigned long cbFormat; //0x40
3942 char* pbFormat; //0x44
3943 } MY_MEDIA_TYPE;
3944 static HRESULT WINAPI expMoCopyMediaType(MY_MEDIA_TYPE* dest, const MY_MEDIA_TYPE* src)
3946 if (!dest || !src)
3947 return E_POINTER;
3948 memcpy(dest, src, sizeof(MY_MEDIA_TYPE));
3949 if (dest->cbFormat)
3951 dest->pbFormat = (char*) my_mreq(dest->cbFormat, 0);
3952 if (!dest->pbFormat)
3953 return E_OUTOFMEMORY;
3954 memcpy(dest->pbFormat, src->pbFormat, dest->cbFormat);
3956 return S_OK;
3958 static HRESULT WINAPI expMoInitMediaType(MY_MEDIA_TYPE* dest, DWORD cbFormat)
3960 if (!dest)
3961 return E_POINTER;
3963 dest->pbUnknown = NULL;
3964 dest->cbFormat = cbFormat;
3965 if (cbFormat)
3967 dest->pbFormat = (char*) my_mreq(cbFormat, 0);
3968 if (!dest->pbFormat)
3969 return E_OUTOFMEMORY;
3971 else
3973 dest->pbFormat=NULL;
3975 return S_OK;
3977 static HRESULT WINAPI expMoCreateMediaType(MY_MEDIA_TYPE** dest, DWORD cbFormat)
3979 if (!dest)
3980 return E_POINTER;
3981 *dest = my_mreq(sizeof(MY_MEDIA_TYPE), 0);
3982 return expMoInitMediaType(*dest, cbFormat);
3984 static HRESULT WINAPI expMoDuplicateMediaType(MY_MEDIA_TYPE** dest, const void* src)
3986 if (!dest)
3987 return E_POINTER;
3988 *dest = my_mreq(sizeof(MY_MEDIA_TYPE), 0);
3989 return expMoCopyMediaType(*dest, src);
3991 static HRESULT WINAPI expMoFreeMediaType(MY_MEDIA_TYPE* dest)
3993 if (!dest)
3994 return E_POINTER;
3995 if (dest->pbFormat)
3997 my_release(dest->pbFormat);
3998 dest->pbFormat = 0;
3999 dest->cbFormat = 0;
4001 return S_OK;
4003 static HRESULT WINAPI expMoDeleteMediaType(MY_MEDIA_TYPE* dest)
4005 if (!dest)
4006 return E_POINTER;
4007 expMoFreeMediaType(dest);
4008 my_release(dest);
4009 return S_OK;
4012 static int exp_snprintf( char *str, int size, const char *format, ... )
4014 int x;
4015 va_list va;
4016 va_start(va, format);
4017 x=snprintf(str,size,format,va);
4018 dbgprintf("_snprintf( 0x%x, %d, %s, ... ) => %d\n",str,size,format,x);
4019 va_end(va);
4020 return x;
4023 #if 0
4024 static int exp_initterm(int v1, int v2)
4026 dbgprintf("_initterm(0x%x, 0x%x) => 0\n", v1, v2);
4027 return 0;
4029 #else
4030 /* merged from wine - 2002.04.21 */
4031 typedef void (*_INITTERMFUNC)();
4032 static int exp_initterm(_INITTERMFUNC *start, _INITTERMFUNC *end)
4034 dbgprintf("_initterm(0x%x, 0x%x) %p\n", start, end, *start);
4035 while (start < end)
4037 if (*start)
4039 //printf("call _initfunc: from: %p %d\n", *start);
4040 // ok this trick with push/pop is necessary as otherwice
4041 // edi/esi registers are being trashed
4042 void* p = *start;
4043 __asm__ __volatile__
4045 "pushl %%ebx \n\t"
4046 "pushl %%ecx \n\t"
4047 "pushl %%edx \n\t"
4048 "pushl %%edi \n\t"
4049 "pushl %%esi \n\t"
4050 "call *%%eax \n\t"
4051 "popl %%esi \n\t"
4052 "popl %%edi \n\t"
4053 "popl %%edx \n\t"
4054 "popl %%ecx \n\t"
4055 "popl %%ebx \n\t"
4057 : "a"(p)
4058 : "memory"
4060 //printf("done %p %d:%d\n", end);
4062 start++;
4064 return 0;
4066 #endif
4068 static void* exp__dllonexit()
4070 // FIXME extract from WINE
4071 return NULL;
4074 static int expwsprintfA(char* string, const char* format, ...)
4076 va_list va;
4077 int result;
4078 va_start(va, format);
4079 result = vsprintf(string, format, va);
4080 dbgprintf("wsprintfA(0x%x, '%s', ...) => %d\n", string, format, result);
4081 va_end(va);
4082 return result;
4085 static int expsprintf(char* str, const char* format, ...)
4087 va_list args;
4088 int r;
4089 dbgprintf("sprintf(0x%x, %s)\n", str, format);
4090 va_start(args, format);
4091 r = vsprintf(str, format, args);
4092 va_end(args);
4093 return r;
4095 static int expsscanf(const char* str, const char* format, ...)
4097 va_list args;
4098 int r;
4099 dbgprintf("sscanf(%s, %s)\n", str, format);
4100 va_start(args, format);
4101 r = vsscanf(str, format, args);
4102 va_end(args);
4103 return r;
4105 static void* expfopen(const char* path, const char* mode)
4107 printf("fopen: \"%s\" mode:%s\n", path, mode);
4108 //return fopen(path, mode);
4109 return fdopen(0, mode); // everything on screen
4111 static int expfprintf(void* stream, const char* format, ...)
4113 va_list args;
4114 int r = 0;
4115 dbgprintf("fprintf(%p, %s, ...)\n", stream, format);
4116 #if 1
4117 va_start(args, format);
4118 r = vfprintf((FILE*) stream, format, args);
4119 va_end(args);
4120 #endif
4121 return r;
4124 static int expprintf(const char* format, ...)
4126 va_list args;
4127 int r;
4128 dbgprintf("printf(%s, ...)\n", format);
4129 va_start(args, format);
4130 r = vprintf(format, args);
4131 va_end(args);
4132 return r;
4135 static char* expgetenv(const char* varname)
4137 char* v = getenv(varname);
4138 dbgprintf("getenv(%s) => %s\n", varname, v);
4139 return v;
4142 static void* expwcscpy(WCHAR* dst, const WCHAR* src)
4144 WCHAR* p = dst;
4145 while ((*p++ = *src++))
4147 return dst;
4150 static char* expstrrchr(char* string, int value)
4152 char* result=strrchr(string, value);
4153 if(result)
4154 dbgprintf("strrchr(0x%x='%s', %d) => 0x%x='%s'", string, string, value, result, result);
4155 else
4156 dbgprintf("strrchr(0x%x='%s', %d) => 0", string, string, value);
4157 return result;
4160 static char* expstrchr(char* string, int value)
4162 char* result=strchr(string, value);
4163 if(result)
4164 dbgprintf("strchr(0x%x='%s', %d) => 0x%x='%s'", string, string, value, result, result);
4165 else
4166 dbgprintf("strchr(0x%x='%s', %d) => 0", string, string, value);
4167 return result;
4169 static int expstrlen(char* str)
4171 int result=strlen(str);
4172 dbgprintf("strlen(0x%x='%s') => %d\n", str, str, result);
4173 return result;
4175 static char* expstrcpy(char* str1, const char* str2)
4177 char* result= strcpy(str1, str2);
4178 dbgprintf("strcpy(0x%x, 0x%x='%s') => %p\n", str1, str2, str2, result);
4179 return result;
4181 static char* expstrncpy(char* str1, const char* str2, size_t count)
4183 char* result= strncpy(str1, str2, count);
4184 dbgprintf("strncpy(0x%x, 0x%x='%s', %d) => %p\n", str1, str2, str2, count, result);
4185 return result;
4187 static int expstrcmp(const char* str1, const char* str2)
4189 int result=strcmp(str1, str2);
4190 dbgprintf("strcmp(0x%x='%s', 0x%x='%s') => %d\n", str1, str1, str2, str2, result);
4191 return result;
4193 static int expstrncmp(const char* str1, const char* str2,int x)
4195 int result=strncmp(str1, str2,x);
4196 dbgprintf("strcmp(0x%x='%s', 0x%x='%s') => %d\n", str1, str1, str2, str2, result);
4197 return result;
4199 static char* expstrcat(char* str1, const char* str2)
4201 char* result = strcat(str1, str2);
4202 dbgprintf("strcat(0x%x='%s', 0x%x='%s') => %p\n", str1, str1, str2, str2, result);
4203 return result;
4205 static char* exp_strdup(const char* str1)
4207 int l = strlen(str1);
4208 char* result = (char*) my_mreq(l + 1,0);
4209 if (result)
4210 strcpy(result, str1);
4211 dbgprintf("_strdup(0x%x='%s') => %p\n", str1, str1, result);
4212 return result;
4214 static int expisalnum(int c)
4216 int result= (int) isalnum(c);
4217 dbgprintf("isalnum(0x%x='%c' => %d\n", c, c, result);
4218 return result;
4220 static int expisspace(int c)
4222 int result= (int) isspace(c);
4223 dbgprintf("isspace(0x%x='%c' => %d\n", c, c, result);
4224 return result;
4226 static int expisalpha(int c)
4228 int result= (int) isalpha(c);
4229 dbgprintf("isalpha(0x%x='%c' => %d\n", c, c, result);
4230 return result;
4232 static int expisdigit(int c)
4234 int result= (int) isdigit(c);
4235 dbgprintf("isdigit(0x%x='%c' => %d\n", c, c, result);
4236 return result;
4238 static void* expmemmove(void* dest, void* src, int n)
4240 void* result = memmove(dest, src, n);
4241 dbgprintf("memmove(0x%x, 0x%x, %d) => %p\n", dest, src, n, result);
4242 return result;
4244 static int expmemcmp(void* dest, void* src, int n)
4246 int result = memcmp(dest, src, n);
4247 dbgprintf("memcmp(0x%x, 0x%x, %d) => %d\n", dest, src, n, result);
4248 return result;
4250 static void* expmemcpy(void* dest, void* src, int n)
4252 void *result = memcpy(dest, src, n);
4253 dbgprintf("memcpy(0x%x, 0x%x, %d) => %p\n", dest, src, n, result);
4254 return result;
4256 static void* expmemset(void* dest, int c, size_t n)
4258 void *result = memset(dest, c, n);
4259 dbgprintf("memset(0x%x, %d, %d) => %p\n", dest, c, n, result);
4260 return result;
4262 static time_t exptime(time_t* t)
4264 time_t result = time(t);
4265 dbgprintf("time(0x%x) => %d\n", t, result);
4266 return result;
4269 static int exprand(void)
4271 return rand();
4274 static void expsrand(int seed)
4276 srand(seed);
4279 #if 1
4281 // preferred compilation with -O2 -ffast-math !
4283 static double explog10(double x)
4285 /*printf("Log10 %f => %f 0x%Lx\n", x, log10(x), *((int64_t*)&x));*/
4286 return log10(x);
4289 static double expcos(double x)
4291 /*printf("Cos %f => %f 0x%Lx\n", x, cos(x), *((int64_t*)&x));*/
4292 return cos(x);
4295 /* doens't work */
4296 static long exp_ftol_wrong(double x)
4298 return (long) x;
4301 #else
4303 static void explog10(void)
4305 __asm__ __volatile__
4307 "fldl 8(%esp) \n\t"
4308 "fldln2 \n\t"
4309 "fxch %st(1) \n\t"
4310 "fyl2x \n\t"
4314 static void expcos(void)
4316 __asm__ __volatile__
4318 "fldl 8(%esp) \n\t"
4319 "fcos \n\t"
4323 #endif
4325 // this seem to be the only how to make this function working properly
4326 // ok - I've spent tremendous amount of time (many many many hours
4327 // of debuging fixing & testing - it's almost unimaginable - kabi
4329 // _ftol - operated on the float value which is already on the FPU stack
4331 static void exp_ftol(void)
4333 __asm__ __volatile__
4335 "sub $12, %esp \n\t"
4336 "fstcw -2(%ebp) \n\t"
4337 "wait \n\t"
4338 "movw -2(%ebp), %ax \n\t"
4339 "orb $0x0C, %ah \n\t"
4340 "movw %ax, -4(%ebp) \n\t"
4341 "fldcw -4(%ebp) \n\t"
4342 "fistpl -12(%ebp) \n\t"
4343 "fldcw -2(%ebp) \n\t"
4344 "movl -12(%ebp), %eax \n\t"
4345 //Note: gcc 3.03 does not do the following op if it
4346 // knows that ebp=esp
4347 "movl %ebp, %esp \n\t"
4351 #define FPU_DOUBLES(var1,var2) double var1,var2; \
4352 __asm__ __volatile__( "fstpl %0;fwait" : "=m" (var2) : ); \
4353 __asm__ __volatile__( "fstpl %0;fwait" : "=m" (var1) : )
4355 static double exp_CIpow(void)
4357 FPU_DOUBLES(x,y);
4359 dbgprintf("_CIpow(%lf, %lf)\n", x, y);
4360 return pow(x, y);
4363 static double exppow(double x, double y)
4365 /*printf("Pow %f %f 0x%Lx 0x%Lx => %f\n", x, y, *((int64_t*)&x), *((int64_t*)&y), pow(x, y));*/
4366 return pow(x, y);
4369 static double expldexp(double x, int expo)
4371 /*printf("Cos %f => %f 0x%Lx\n", x, cos(x), *((int64_t*)&x));*/
4372 return ldexp(x, expo);
4375 static double expfrexp(double x, int* expo)
4377 /*printf("Cos %f => %f 0x%Lx\n", x, cos(x), *((int64_t*)&x));*/
4378 return frexp(x, expo);
4383 static int exp_stricmp(const char* s1, const char* s2)
4385 return strcasecmp(s1, s2);
4388 /* from declaration taken from Wine sources - this fountion seems to be
4389 * undocumented in any M$ doc */
4390 static int exp_setjmp3(void* jmpbuf, int x)
4392 //dbgprintf("!!!!UNIMPLEMENTED: setjmp3(%p, %d) => 0\n", jmpbuf, x);
4393 //return 0;
4394 __asm__ __volatile__
4396 //"mov 4(%%esp), %%edx \n\t"
4397 "mov (%%esp), %%eax \n\t"
4398 "mov %%eax, (%%edx) \n\t" // store ebp
4400 //"mov %%ebp, (%%edx) \n\t"
4401 "mov %%ebx, 4(%%edx) \n\t"
4402 "mov %%edi, 8(%%edx) \n\t"
4403 "mov %%esi, 12(%%edx) \n\t"
4404 "mov %%esp, 16(%%edx) \n\t"
4406 "mov 4(%%esp), %%eax \n\t"
4407 "mov %%eax, 20(%%edx) \n\t"
4409 "movl $0x56433230, 32(%%edx) \n\t" // VC20 ??
4410 "movl $0, 36(%%edx) \n\t"
4411 : // output
4412 : "d"(jmpbuf) // input
4413 : "eax"
4415 #if 1
4416 __asm__ __volatile__
4418 "mov %%fs:0, %%eax \n\t" // unsure
4419 "mov %%eax, 24(%%edx) \n\t"
4420 "cmp $0xffffffff, %%eax \n\t"
4421 "jnz l1 \n\t"
4422 "mov %%eax, 28(%%edx) \n\t"
4423 "l1: \n\t"
4426 : "eax"
4428 #endif
4430 return 0;
4433 static DWORD WINAPI expGetCurrentProcessId(void)
4435 dbgprintf("GetCurrentProcessId(void) => %d\n", getpid());
4436 return getpid(); //(DWORD)NtCurrentTeb()->pid;
4440 typedef struct {
4441 UINT wPeriodMin;
4442 UINT wPeriodMax;
4443 } TIMECAPS, *LPTIMECAPS;
4445 static MMRESULT WINAPI exptimeGetDevCaps(LPTIMECAPS lpCaps, UINT wSize)
4447 dbgprintf("timeGetDevCaps(%p, %u) !\n", lpCaps, wSize);
4449 lpCaps->wPeriodMin = 1;
4450 lpCaps->wPeriodMax = 65535;
4451 return 0;
4454 static MMRESULT WINAPI exptimeBeginPeriod(UINT wPeriod)
4456 dbgprintf("timeBeginPeriod(%u) !\n", wPeriod);
4458 if (wPeriod < 1 || wPeriod > 65535) return 96+1; //TIMERR_NOCANDO;
4459 return 0;
4462 #ifdef QTX
4463 static MMRESULT WINAPI exptimeEndPeriod(UINT wPeriod)
4465 dbgprintf("timeEndPeriod(%u) !\n", wPeriod);
4467 if (wPeriod < 1 || wPeriod > 65535) return 96+1; //TIMERR_NOCANDO;
4468 return 0;
4470 #endif
4472 static void WINAPI expGlobalMemoryStatus(
4473 LPMEMORYSTATUS lpmem
4475 static MEMORYSTATUS cached_memstatus;
4476 static int cache_lastchecked = 0;
4477 SYSTEM_INFO si;
4478 FILE *f;
4480 if (time(NULL)==cache_lastchecked) {
4481 memcpy(lpmem,&cached_memstatus,sizeof(MEMORYSTATUS));
4482 return;
4485 #if 1
4486 f = fopen( "/proc/meminfo", "r" );
4487 if (f)
4489 char buffer[256];
4490 int total, used, free, shared, buffers, cached;
4492 lpmem->dwLength = sizeof(MEMORYSTATUS);
4493 lpmem->dwTotalPhys = lpmem->dwAvailPhys = 0;
4494 lpmem->dwTotalPageFile = lpmem->dwAvailPageFile = 0;
4495 while (fgets( buffer, sizeof(buffer), f ))
4497 /* old style /proc/meminfo ... */
4498 if (sscanf( buffer, "Mem: %d %d %d %d %d %d", &total, &used, &free, &shared, &buffers, &cached ))
4500 lpmem->dwTotalPhys += total;
4501 lpmem->dwAvailPhys += free + buffers + cached;
4503 if (sscanf( buffer, "Swap: %d %d %d", &total, &used, &free ))
4505 lpmem->dwTotalPageFile += total;
4506 lpmem->dwAvailPageFile += free;
4509 /* new style /proc/meminfo ... */
4510 if (sscanf(buffer, "MemTotal: %d", &total))
4511 lpmem->dwTotalPhys = total*1024;
4512 if (sscanf(buffer, "MemFree: %d", &free))
4513 lpmem->dwAvailPhys = free*1024;
4514 if (sscanf(buffer, "SwapTotal: %d", &total))
4515 lpmem->dwTotalPageFile = total*1024;
4516 if (sscanf(buffer, "SwapFree: %d", &free))
4517 lpmem->dwAvailPageFile = free*1024;
4518 if (sscanf(buffer, "Buffers: %d", &buffers))
4519 lpmem->dwAvailPhys += buffers*1024;
4520 if (sscanf(buffer, "Cached: %d", &cached))
4521 lpmem->dwAvailPhys += cached*1024;
4523 fclose( f );
4525 if (lpmem->dwTotalPhys)
4527 DWORD TotalPhysical = lpmem->dwTotalPhys+lpmem->dwTotalPageFile;
4528 DWORD AvailPhysical = lpmem->dwAvailPhys+lpmem->dwAvailPageFile;
4529 lpmem->dwMemoryLoad = (TotalPhysical-AvailPhysical)
4530 / (TotalPhysical / 100);
4532 } else
4533 #endif
4535 /* FIXME: should do something for other systems */
4536 lpmem->dwMemoryLoad = 0;
4537 lpmem->dwTotalPhys = 16*1024*1024;
4538 lpmem->dwAvailPhys = 16*1024*1024;
4539 lpmem->dwTotalPageFile = 16*1024*1024;
4540 lpmem->dwAvailPageFile = 16*1024*1024;
4542 expGetSystemInfo(&si);
4543 lpmem->dwTotalVirtual = si.lpMaximumApplicationAddress-si.lpMinimumApplicationAddress;
4544 /* FIXME: we should track down all the already allocated VM pages and substract them, for now arbitrarily remove 64KB so that it matches NT */
4545 lpmem->dwAvailVirtual = lpmem->dwTotalVirtual-64*1024;
4546 memcpy(&cached_memstatus,lpmem,sizeof(MEMORYSTATUS));
4547 cache_lastchecked = time(NULL);
4549 /* it appears some memory display programs want to divide by these values */
4550 if(lpmem->dwTotalPageFile==0)
4551 lpmem->dwTotalPageFile++;
4553 if(lpmem->dwAvailPageFile==0)
4554 lpmem->dwAvailPageFile++;
4557 /**********************************************************************
4558 * SetThreadPriority [KERNEL32.@] Sets priority for thread.
4560 * RETURNS
4561 * Success: TRUE
4562 * Failure: FALSE
4564 static WIN_BOOL WINAPI expSetThreadPriority(
4565 HANDLE hthread, /* [in] Handle to thread */
4566 INT priority) /* [in] Thread priority level */
4568 dbgprintf("SetThreadPriority(%p,%d)\n",hthread,priority);
4569 return TRUE;
4572 static void WINAPI expExitProcess( DWORD status )
4574 printf("EXIT - code %ld\n",status);
4575 exit(status);
4578 static INT WINAPI expMessageBoxA(HWND hWnd, LPCSTR text, LPCSTR title, UINT type){
4579 printf("MSGBOX '%s' '%s' (%d)\n",text,title,type);
4580 #ifdef QTX
4581 if (type == MB_ICONHAND && !strlen(text) && !strlen(title))
4582 return IDIGNORE;
4583 #endif
4584 return IDOK;
4587 /* these are needed for mss1 */
4589 /* defined in stubs.s */
4590 void exp_EH_prolog(void);
4592 #include <netinet/in.h>
4593 static WINAPI inline unsigned long int exphtonl(unsigned long int hostlong)
4595 // dbgprintf("htonl(%x) => %x\n", hostlong, htonl(hostlong));
4596 return htonl(hostlong);
4599 static WINAPI inline unsigned long int expntohl(unsigned long int netlong)
4601 // dbgprintf("ntohl(%x) => %x\n", netlong, ntohl(netlong));
4602 return ntohl(netlong);
4604 static void WINAPI expVariantInit(void* p)
4606 printf("InitCommonControls called!\n");
4607 return;
4610 static int WINAPI expRegisterClassA(const void/*WNDCLASSA*/ *wc)
4612 dbgprintf("RegisterClassA(%p) => random id\n", wc);
4613 return time(NULL); /* be precise ! */
4616 static int WINAPI expUnregisterClassA(const char *className, HINSTANCE hInstance)
4618 dbgprintf("UnregisterClassA(%s, %p) => 0\n", className, hInstance);
4619 return 0;
4622 #ifdef QTX
4623 /* should be fixed bcs it's not fully strlen equivalent */
4624 static int expSysStringByteLen(void *str)
4626 dbgprintf("SysStringByteLen(%p) => %d\n", str, strlen(str));
4627 return strlen(str);
4630 static int expDirectDrawCreate(void)
4632 dbgprintf("DirectDrawCreate(...) => NULL\n");
4633 return 0;
4636 #if 1
4637 typedef struct tagPALETTEENTRY {
4638 BYTE peRed;
4639 BYTE peGreen;
4640 BYTE peBlue;
4641 BYTE peFlags;
4642 } PALETTEENTRY;
4644 /* reversed the first 2 entries */
4645 typedef struct tagLOGPALETTE {
4646 WORD palNumEntries;
4647 WORD palVersion;
4648 PALETTEENTRY palPalEntry[1];
4649 } LOGPALETTE;
4651 static HPALETTE WINAPI expCreatePalette(CONST LOGPALETTE *lpgpl)
4653 HPALETTE test;
4654 int i;
4656 dbgprintf("CreatePalette(%x) => NULL\n", lpgpl);
4658 i = sizeof(LOGPALETTE)+((lpgpl->palNumEntries-1)*sizeof(PALETTEENTRY));
4659 test = (HPALETTE)malloc(i);
4660 memcpy((void *)test, lpgpl, i);
4662 return test;
4664 #else
4665 static int expCreatePalette(void)
4667 dbgprintf("CreatePalette(...) => NULL\n");
4668 return NULL;
4670 #endif
4672 static int WINAPI expGetClientRect(HWND win, RECT *r)
4674 dbgprintf("GetClientRect(0x%x, 0x%x) => 1\n", win, r);
4675 r->right = PSEUDO_SCREEN_WIDTH;
4676 r->left = 0;
4677 r->bottom = PSEUDO_SCREEN_HEIGHT;
4678 r->top = 0;
4679 return 1;
4682 #if 0
4683 typedef struct tagPOINT {
4684 LONG x;
4685 LONG y;
4686 } POINT, *PPOINT;
4687 #endif
4689 static int WINAPI expClientToScreen(HWND win, POINT *p)
4691 dbgprintf("ClientToScreen(0x%x, 0x%x = %d,%d) => 1\n", win, p, p->x, p->y);
4692 p->x = 0;
4693 p->y = 0;
4694 return 1;
4696 #endif
4698 /* for m3jpeg */
4699 static int WINAPI expSetThreadIdealProcessor(HANDLE thread, int proc)
4701 dbgprintf("SetThreadIdealProcessor(0x%x, %x) => 0\n", thread, proc);
4702 return 0;
4705 static int WINAPI expMessageBeep(int type)
4707 dbgprintf("MessageBeep(%d) => 1\n", type);
4708 return 1;
4711 static int WINAPI expDialogBoxParamA(void *inst, const char *name,
4712 HWND parent, void *dialog_func, void *init_param)
4714 dbgprintf("DialogBoxParamA(0x%x, 0x%x = %s, 0x%x, 0x%x, 0x%x) => 0x42424242\n",
4715 inst, name, name, parent, dialog_func, init_param);
4716 return 0x42424242;
4719 /* needed by imagepower mjpeg2k */
4720 static void *exprealloc(void *ptr, size_t size)
4722 dbgprintf("realloc(0x%x, %x)\n", ptr, size);
4723 if (!ptr)
4724 return my_mreq(size,0);
4725 else
4726 return my_realloc(ptr, size);
4729 /* Fake GetOpenFileNameA from comdlg32.dll for ViVD codec */
4730 static WIN_BOOL WINAPI expGetOpenFileNameA(/*LPOPENFILENAMEA*/ void* lpfn)
4732 return 1;
4735 static double expfloor(double x)
4737 dbgprintf("floor(%lf)\n", x);
4738 return floor(x);
4741 #define FPU_DOUBLE(var) double var; \
4742 __asm__ __volatile__( "fstpl %0;fwait" : "=m" (var) : )
4744 static double exp_CIcos(void)
4746 FPU_DOUBLE(x);
4748 dbgprintf("_CIcos(%lf)\n", x);
4749 return cos(x);
4752 static double exp_CIsin(void)
4754 FPU_DOUBLE(x);
4756 dbgprintf("_CIsin(%lf)\n", x);
4757 return sin(x);
4760 struct exports
4762 char name[64];
4763 int id;
4764 void* func;
4766 struct libs
4768 char name[64];
4769 int length;
4770 struct exports* exps;
4773 #define FF(X,Y) \
4774 {#X, Y, (void*)exp##X},
4776 struct exports exp_kernel32[]=
4778 FF(GetVolumeInformationA,-1)
4779 FF(GetDriveTypeA,-1)
4780 FF(GetLogicalDriveStringsA,-1)
4781 FF(IsBadWritePtr, 357)
4782 FF(IsBadReadPtr, 354)
4783 FF(IsBadStringPtrW, -1)
4784 FF(IsBadStringPtrA, -1)
4785 FF(DisableThreadLibraryCalls, -1)
4786 FF(CreateThread, -1)
4787 FF(CreateEventA, -1)
4788 FF(SetEvent, -1)
4789 FF(ResetEvent, -1)
4790 FF(WaitForSingleObject, -1)
4791 #ifdef QTX
4792 FF(WaitForMultipleObjects, -1)
4793 FF(ExitThread, -1)
4794 FF(CreateMutexA,-1)
4795 FF(ReleaseMutex,-1)
4796 #endif
4797 FF(GetSystemInfo, -1)
4798 FF(GetVersion, 332)
4799 FF(HeapCreate, 461)
4800 FF(HeapAlloc, -1)
4801 FF(HeapDestroy, -1)
4802 FF(HeapFree, -1)
4803 FF(HeapSize, -1)
4804 FF(HeapReAlloc,-1)
4805 FF(GetProcessHeap, -1)
4806 FF(VirtualAlloc, -1)
4807 FF(VirtualFree, -1)
4808 FF(InitializeCriticalSection, -1)
4809 FF(EnterCriticalSection, -1)
4810 FF(LeaveCriticalSection, -1)
4811 FF(DeleteCriticalSection, -1)
4812 FF(TlsAlloc, -1)
4813 FF(TlsFree, -1)
4814 FF(TlsGetValue, -1)
4815 FF(TlsSetValue, -1)
4816 FF(GetCurrentThreadId, -1)
4817 FF(GetCurrentProcess, -1)
4818 FF(LocalAlloc, -1)
4819 FF(LocalReAlloc,-1)
4820 FF(LocalLock, -1)
4821 FF(GlobalAlloc, -1)
4822 FF(GlobalReAlloc, -1)
4823 FF(GlobalLock, -1)
4824 FF(GlobalSize, -1)
4825 FF(MultiByteToWideChar, 427)
4826 FF(WideCharToMultiByte, -1)
4827 FF(GetVersionExA, -1)
4828 FF(CreateSemaphoreA, -1)
4829 FF(QueryPerformanceCounter, -1)
4830 FF(QueryPerformanceFrequency, -1)
4831 FF(LocalHandle, -1)
4832 FF(LocalUnlock, -1)
4833 FF(LocalFree, -1)
4834 FF(GlobalHandle, -1)
4835 FF(GlobalUnlock, -1)
4836 FF(GlobalFree, -1)
4837 FF(LoadResource, -1)
4838 FF(ReleaseSemaphore, -1)
4839 FF(FindResourceA, -1)
4840 FF(LockResource, -1)
4841 FF(FreeResource, -1)
4842 FF(SizeofResource, -1)
4843 FF(CloseHandle, -1)
4844 FF(GetCommandLineA, -1)
4845 FF(GetEnvironmentStringsW, -1)
4846 FF(FreeEnvironmentStringsW, -1)
4847 FF(FreeEnvironmentStringsA, -1)
4848 FF(GetEnvironmentStrings, -1)
4849 FF(GetStartupInfoA, -1)
4850 FF(GetStdHandle, -1)
4851 FF(GetFileType, -1)
4852 #ifdef QTX
4853 FF(GetFileAttributesA, -1)
4854 #endif
4855 FF(SetHandleCount, -1)
4856 FF(GetACP, -1)
4857 FF(GetModuleFileNameA, -1)
4858 FF(SetUnhandledExceptionFilter, -1)
4859 FF(LoadLibraryA, -1)
4860 FF(GetProcAddress, -1)
4861 FF(FreeLibrary, -1)
4862 FF(CreateFileMappingA, -1)
4863 FF(OpenFileMappingA, -1)
4864 FF(MapViewOfFile, -1)
4865 FF(UnmapViewOfFile, -1)
4866 FF(Sleep, -1)
4867 FF(GetModuleHandleA, -1)
4868 FF(GetProfileIntA, -1)
4869 FF(GetPrivateProfileIntA, -1)
4870 FF(GetPrivateProfileStringA, -1)
4871 FF(WritePrivateProfileStringA, -1)
4872 FF(GetLastError, -1)
4873 FF(SetLastError, -1)
4874 FF(InterlockedIncrement, -1)
4875 FF(InterlockedDecrement, -1)
4876 FF(GetTimeZoneInformation, -1)
4877 FF(OutputDebugStringA, -1)
4878 FF(GetLocalTime, -1)
4879 FF(GetSystemTime, -1)
4880 FF(GetSystemTimeAsFileTime, -1)
4881 FF(GetEnvironmentVariableA, -1)
4882 FF(SetEnvironmentVariableA, -1)
4883 FF(RtlZeroMemory,-1)
4884 FF(RtlMoveMemory,-1)
4885 FF(RtlFillMemory,-1)
4886 FF(GetTempPathA,-1)
4887 FF(FindFirstFileA,-1)
4888 FF(FindNextFileA,-1)
4889 FF(FindClose,-1)
4890 FF(FileTimeToLocalFileTime,-1)
4891 FF(DeleteFileA,-1)
4892 FF(ReadFile,-1)
4893 FF(WriteFile,-1)
4894 FF(SetFilePointer,-1)
4895 FF(GetTempFileNameA,-1)
4896 FF(CreateFileA,-1)
4897 FF(GetSystemDirectoryA,-1)
4898 FF(GetWindowsDirectoryA,-1)
4899 #ifdef QTX
4900 FF(GetCurrentDirectoryA,-1)
4901 FF(SetCurrentDirectoryA,-1)
4902 FF(CreateDirectoryA,-1)
4903 #endif
4904 FF(GetShortPathNameA,-1)
4905 FF(GetFullPathNameA,-1)
4906 FF(SetErrorMode, -1)
4907 FF(IsProcessorFeaturePresent, -1)
4908 FF(GetProcessAffinityMask, -1)
4909 FF(InterlockedExchange, -1)
4910 FF(InterlockedCompareExchange, -1)
4911 FF(MulDiv, -1)
4912 FF(lstrcmpiA, -1)
4913 FF(lstrlenA, -1)
4914 FF(lstrcpyA, -1)
4915 FF(lstrcatA, -1)
4916 FF(lstrcpynA,-1)
4917 FF(GetProcessVersion,-1)
4918 FF(GetCurrentThread,-1)
4919 FF(GetOEMCP,-1)
4920 FF(GetCPInfo,-1)
4921 FF(DuplicateHandle,-1)
4922 FF(GetTickCount, -1)
4923 FF(SetThreadAffinityMask,-1)
4924 FF(GetCurrentProcessId,-1)
4925 FF(GlobalMemoryStatus,-1)
4926 FF(SetThreadPriority,-1)
4927 FF(ExitProcess,-1)
4928 {"LoadLibraryExA", -1, (void*)&LoadLibraryExA},
4929 FF(SetThreadIdealProcessor,-1)
4932 struct exports exp_msvcrt[]={
4933 FF(malloc, -1)
4934 FF(_initterm, -1)
4935 FF(__dllonexit, -1)
4936 FF(_snprintf,-1)
4937 FF(free, -1)
4938 {"??3@YAXPAX@Z", -1, expdelete},
4939 {"??2@YAPAXI@Z", -1, expnew},
4940 {"_adjust_fdiv", -1, (void*)&_adjust_fdiv},
4941 FF(strrchr, -1)
4942 FF(strchr, -1)
4943 FF(strlen, -1)
4944 FF(strcpy, -1)
4945 FF(strncpy, -1)
4946 FF(wcscpy, -1)
4947 FF(strcmp, -1)
4948 FF(strncmp, -1)
4949 FF(strcat, -1)
4950 FF(_stricmp,-1)
4951 FF(_strdup,-1)
4952 FF(_setjmp3,-1)
4953 FF(isalnum, -1)
4954 FF(isspace, -1)
4955 FF(isalpha, -1)
4956 FF(isdigit, -1)
4957 FF(memmove, -1)
4958 FF(memcmp, -1)
4959 FF(memset, -1)
4960 FF(memcpy, -1)
4961 FF(time, -1)
4962 FF(rand, -1)
4963 FF(srand, -1)
4964 FF(log10, -1)
4965 FF(pow, -1)
4966 FF(cos, -1)
4967 FF(_ftol,-1)
4968 FF(_CIpow,-1)
4969 FF(_CIcos,-1)
4970 FF(_CIsin,-1)
4971 FF(ldexp,-1)
4972 FF(frexp,-1)
4973 FF(sprintf,-1)
4974 FF(sscanf,-1)
4975 FF(fopen,-1)
4976 FF(fprintf,-1)
4977 FF(printf,-1)
4978 FF(getenv,-1)
4979 FF(floor,-1)
4980 /* needed by frapsvid.dll */
4981 {"strstr",-1,(char *)&strstr},
4982 {"qsort",-1,(void *)&qsort},
4983 #ifdef MPLAYER
4984 FF(_EH_prolog,-1)
4985 #endif
4986 FF(calloc,-1)
4987 {"ceil",-1,(void*)&ceil},
4988 /* needed by imagepower mjpeg2k */
4989 {"clock",-1,(void*)&clock},
4990 {"memchr",-1,(void*)&memchr},
4991 {"vfprintf",-1,(void*)&vfprintf},
4992 // {"realloc",-1,(void*)&realloc},
4993 FF(realloc,-1)
4994 {"puts",-1,(void*)&puts}
4996 struct exports exp_winmm[]={
4997 FF(GetDriverModuleHandle, -1)
4998 FF(timeGetTime, -1)
4999 FF(DefDriverProc, -1)
5000 FF(OpenDriverA, -1)
5001 FF(OpenDriver, -1)
5002 FF(timeGetDevCaps, -1)
5003 FF(timeBeginPeriod, -1)
5004 #ifdef QTX
5005 FF(timeEndPeriod, -1)
5006 FF(waveOutGetNumDevs, -1)
5007 #endif
5009 struct exports exp_user32[]={
5010 FF(LoadIconA,-1)
5011 FF(LoadStringA, -1)
5012 FF(wsprintfA, -1)
5013 FF(GetDC, -1)
5014 FF(GetDesktopWindow, -1)
5015 FF(ReleaseDC, -1)
5016 FF(IsRectEmpty, -1)
5017 FF(LoadCursorA,-1)
5018 FF(SetCursor,-1)
5019 FF(GetCursorPos,-1)
5020 #ifdef QTX
5021 FF(ShowCursor,-1)
5022 #endif
5023 FF(RegisterWindowMessageA,-1)
5024 FF(GetSystemMetrics,-1)
5025 FF(GetSysColor,-1)
5026 FF(GetSysColorBrush,-1)
5027 FF(GetWindowDC, -1)
5028 FF(DrawTextA, -1)
5029 FF(MessageBoxA, -1)
5030 FF(RegisterClassA, -1)
5031 FF(UnregisterClassA, -1)
5032 #ifdef QTX
5033 FF(GetWindowRect, -1)
5034 FF(MonitorFromWindow, -1)
5035 FF(MonitorFromRect, -1)
5036 FF(MonitorFromPoint, -1)
5037 FF(EnumDisplayMonitors, -1)
5038 FF(GetMonitorInfoA, -1)
5039 FF(EnumDisplayDevicesA, -1)
5040 FF(GetClientRect, -1)
5041 FF(ClientToScreen, -1)
5042 FF(IsWindowVisible, -1)
5043 FF(GetActiveWindow, -1)
5044 FF(GetClassNameA, -1)
5045 FF(GetClassInfoA, -1)
5046 FF(GetWindowLongA, -1)
5047 FF(EnumWindows, -1)
5048 FF(GetWindowThreadProcessId, -1)
5049 FF(CreateWindowExA, -1)
5050 #endif
5051 FF(MessageBeep, -1)
5052 FF(DialogBoxParamA, -1)
5054 struct exports exp_advapi32[]={
5055 FF(RegCloseKey, -1)
5056 FF(RegCreateKeyA, -1)
5057 FF(RegCreateKeyExA, -1)
5058 FF(RegEnumKeyExA, -1)
5059 FF(RegEnumValueA, -1)
5060 FF(RegOpenKeyA, -1)
5061 FF(RegOpenKeyExA, -1)
5062 FF(RegQueryValueExA, -1)
5063 FF(RegSetValueExA, -1)
5064 FF(RegQueryInfoKeyA, -1)
5066 struct exports exp_gdi32[]={
5067 FF(CreateCompatibleDC, -1)
5068 FF(CreateFontA, -1)
5069 FF(DeleteDC, -1)
5070 FF(DeleteObject, -1)
5071 FF(GetDeviceCaps, -1)
5072 FF(GetSystemPaletteEntries, -1)
5073 #ifdef QTX
5074 FF(CreatePalette, -1)
5075 FF(GetObjectA, -1)
5076 FF(CreateRectRgn, -1)
5077 #endif
5079 struct exports exp_version[]={
5080 FF(GetFileVersionInfoSizeA, -1)
5082 struct exports exp_ole32[]={
5083 FF(CoCreateFreeThreadedMarshaler,-1)
5084 FF(CoCreateInstance, -1)
5085 FF(CoInitialize, -1)
5086 FF(CoTaskMemAlloc, -1)
5087 FF(CoTaskMemFree, -1)
5088 FF(StringFromGUID2, -1)
5090 // do we really need crtdll ???
5091 // msvcrt is the correct place probably...
5092 struct exports exp_crtdll[]={
5093 FF(memcpy, -1)
5094 FF(wcscpy, -1)
5096 struct exports exp_comctl32[]={
5097 FF(StringFromGUID2, -1)
5098 FF(InitCommonControls, 17)
5099 #ifdef QTX
5100 FF(CreateUpDownControl, 16)
5101 #endif
5103 struct exports exp_wsock32[]={
5104 FF(htonl,8)
5105 FF(ntohl,14)
5107 struct exports exp_msdmo[]={
5108 FF(memcpy, -1) // just test
5109 FF(MoCopyMediaType, -1)
5110 FF(MoCreateMediaType, -1)
5111 FF(MoDeleteMediaType, -1)
5112 FF(MoDuplicateMediaType, -1)
5113 FF(MoFreeMediaType, -1)
5114 FF(MoInitMediaType, -1)
5116 struct exports exp_oleaut32[]={
5117 FF(VariantInit, 8)
5118 #ifdef QTX
5119 FF(SysStringByteLen, 149)
5120 #endif
5123 /* realplayer8:
5124 DLL Name: PNCRT.dll
5125 vma: Hint/Ord Member-Name
5126 22ff4 615 free
5127 2302e 250 _ftol
5128 22fea 666 malloc
5129 2303e 609 fprintf
5130 2305e 167 _adjust_fdiv
5131 23052 280 _initterm
5133 22ffc 176 _beginthreadex
5134 23036 284 _iob
5135 2300e 85 __CxxFrameHandler
5136 23022 411 _purecall
5138 #ifdef REALPLAYER
5139 struct exports exp_pncrt[]={
5140 FF(malloc, -1) // just test
5141 FF(free, -1) // just test
5142 FF(fprintf, -1) // just test
5143 {"_adjust_fdiv", -1, (void*)&_adjust_fdiv},
5144 FF(_ftol,-1)
5145 FF(_initterm, -1)
5146 {"??3@YAXPAX@Z", -1, expdelete},
5147 {"??2@YAPAXI@Z", -1, expnew},
5148 FF(__dllonexit, -1)
5149 FF(strncpy, -1)
5150 FF(_CIpow,-1)
5151 FF(calloc,-1)
5152 FF(memmove, -1)
5154 #endif
5156 #ifdef QTX
5157 struct exports exp_ddraw[]={
5158 FF(DirectDrawCreate, -1)
5160 #endif
5162 struct exports exp_comdlg32[]={
5163 FF(GetOpenFileNameA, -1)
5166 #define LL(X) \
5167 {#X".dll", sizeof(exp_##X)/sizeof(struct exports), exp_##X},
5169 struct libs libraries[]={
5170 LL(kernel32)
5171 LL(msvcrt)
5172 LL(winmm)
5173 LL(user32)
5174 LL(advapi32)
5175 LL(gdi32)
5176 LL(version)
5177 LL(ole32)
5178 LL(oleaut32)
5179 LL(crtdll)
5180 LL(comctl32)
5181 LL(wsock32)
5182 LL(msdmo)
5183 #ifdef REALPLAYER
5184 LL(pncrt)
5185 #endif
5186 #ifdef QTX
5187 LL(ddraw)
5188 #endif
5189 LL(comdlg32)
5192 static void ext_stubs(void)
5194 // expects:
5195 // ax position index
5196 // cx address of printf function
5197 #if 1
5198 __asm__ __volatile__
5200 "push %%edx \n\t"
5201 "movl $0xdeadbeef, %%eax \n\t"
5202 "movl $0xdeadbeef, %%edx \n\t"
5203 "shl $5, %%eax \n\t" // ax * 32
5204 "addl $0xdeadbeef, %%eax \n\t" // overwrite export_names
5205 "pushl %%eax \n\t"
5206 "pushl $0xdeadbeef \n\t" // overwrite called_unk
5207 "call *%%edx \n\t" // printf (via dx)
5208 "addl $8, %%esp \n\t"
5209 "xorl %%eax, %%eax \n\t"
5210 "pop %%edx \n\t"
5213 : "eax"
5215 #else
5216 __asm__ __volatile__
5218 "push %%edx \n\t"
5219 "movl $0, %%eax \n\t"
5220 "movl $0, %%edx \n\t"
5221 "shl $5, %%eax \n\t" // ax * 32
5222 "addl %0, %%eax \n\t"
5223 "pushl %%eax \n\t"
5224 "pushl %1 \n\t"
5225 "call *%%edx \n\t" // printf (via dx)
5226 "addl $8, %%esp \n\t"
5227 "xorl %%eax, %%eax \n\t"
5228 "pop %%edx \n\t"
5229 ::"m"(*export_names), "m"(*called_unk)
5230 : "memory", "edx", "eax"
5232 #endif
5236 //static void add_stub(int pos)
5238 extern int unk_exp1;
5239 static int pos=0;
5240 static char extcode[20000];// place for 200 unresolved exports
5241 static const char* called_unk = "Called unk_%s\n";
5243 static void* add_stub(void)
5245 // generated code in runtime!
5246 char* answ = (char*)extcode+pos*0x30;
5247 #if 0
5248 memcpy(answ, &unk_exp1, 0x64);
5249 *(int*)(answ+9)=pos;
5250 *(int*)(answ+47)-=((int)answ-(int)&unk_exp1);
5251 #endif
5252 memcpy(answ, ext_stubs, 0x2f); // 0x2c is current size
5253 //answ[4] = 0xb8; // movl $0, eax (0xb8 0x00000000)
5254 *((int*) (answ + 5)) = pos;
5255 //answ[9] = 0xba; // movl $0, edx (0xba 0x00000000)
5256 *((long*) (answ + 10)) = (long)printf;
5257 //answ[17] = 0x05; // addl $0, eax (0x05 0x00000000)
5258 *((long*) (answ + 18)) = (long)export_names;
5259 //answ[23] = 0x68; // pushl $0 (0x68 0x00000000)
5260 *((long*) (answ + 24)) = (long)called_unk;
5261 pos++;
5262 return (void*)answ;
5265 void* LookupExternal(const char* library, int ordinal)
5267 int i,j;
5268 if(library==0)
5270 printf("ERROR: library=0\n");
5271 return (void*)ext_unknown;
5273 // printf("%x %x\n", &unk_exp1, &unk_exp2);
5275 dbgprintf("External func %s:%d\n", library, ordinal);
5277 for(i=0; i<sizeof(libraries)/sizeof(struct libs); i++)
5279 if(strcasecmp(library, libraries[i].name))
5280 continue;
5281 for(j=0; j<libraries[i].length; j++)
5283 if(ordinal!=libraries[i].exps[j].id)
5284 continue;
5285 //printf("Hit: 0x%p\n", libraries[i].exps[j].func);
5286 return libraries[i].exps[j].func;
5290 #ifndef LOADLIB_TRY_NATIVE
5291 /* hack for truespeech and vssh264*/
5292 if (!strcmp(library, "tsd32.dll") || !strcmp(library,"vssh264dec.dll") || !strcmp(library,"LCMW2.dll") || !strcmp(library,"VDODEC32.dll"))
5293 #endif
5294 /* ok, this is a hack, and a big memory leak. should be fixed. - alex */
5296 int hand;
5297 WINE_MODREF *wm;
5298 void *func;
5300 hand = LoadLibraryA(library);
5301 if (!hand)
5302 goto no_dll;
5303 wm = MODULE32_LookupHMODULE(hand);
5304 if (!wm)
5306 FreeLibrary(hand);
5307 goto no_dll;
5309 func = PE_FindExportedFunction(wm, (LPCSTR) ordinal, 0);
5310 if (!func)
5312 printf("No such ordinal in external dll\n");
5313 FreeLibrary((int)hand);
5314 goto no_dll;
5317 printf("External dll loaded (offset: 0x%x, func: %p)\n",
5318 hand, func);
5319 return func;
5322 no_dll:
5323 if(pos>150)return 0;
5324 sprintf(export_names[pos], "%s:%d", library, ordinal);
5325 return add_stub();
5328 void* LookupExternalByName(const char* library, const char* name)
5330 char* answ;
5331 int i,j;
5332 // return (void*)ext_unknown;
5333 if(library==0)
5335 printf("ERROR: library=0\n");
5336 return (void*)ext_unknown;
5338 if(name==0)
5340 printf("ERROR: name=0\n");
5341 return (void*)ext_unknown;
5343 dbgprintf("External func %s:%s\n", library, name);
5344 for(i=0; i<sizeof(libraries)/sizeof(struct libs); i++)
5346 if(strcasecmp(library, libraries[i].name))
5347 continue;
5348 for(j=0; j<libraries[i].length; j++)
5350 if(strcmp(name, libraries[i].exps[j].name))
5351 continue;
5352 // printf("Hit: 0x%08X\n", libraries[i].exps[j].func);
5353 return libraries[i].exps[j].func;
5357 #ifndef LOADLIB_TRY_NATIVE
5358 /* hack for vss h264 */
5359 if (!strcmp(library,"vssh264core.dll"))
5360 #endif
5361 /* ok, this is a hack, and a big memory leak. should be fixed. - alex */
5363 int hand;
5364 WINE_MODREF *wm;
5365 void *func;
5367 hand = LoadLibraryA(library);
5368 if (!hand)
5369 goto no_dll_byname;
5370 wm = MODULE32_LookupHMODULE(hand);
5371 if (!wm)
5373 FreeLibrary(hand);
5374 goto no_dll_byname;
5376 func = PE_FindExportedFunction(wm, name, 0);
5377 if (!func)
5379 printf("No such name in external dll\n");
5380 FreeLibrary((int)hand);
5381 goto no_dll_byname;
5384 printf("External dll loaded (offset: 0x%x, func: %p)\n",
5385 hand, func);
5386 return func;
5389 no_dll_byname:
5390 if(pos>150)return 0;// to many symbols
5391 strcpy(export_names[pos], name);
5392 return add_stub();
5395 void my_garbagecollection(void)
5397 #ifdef GARBAGE
5398 int unfree = 0, unfreecnt = 0;
5400 int max_fatal = 8;
5401 free_registry();
5402 while (last_alloc)
5404 alloc_header* mem = last_alloc + 1;
5405 unfree += my_size(mem);
5406 unfreecnt++;
5407 if (my_release(mem) != 0)
5408 // avoid endless loop when memory is trashed
5409 if (--max_fatal < 0)
5410 break;
5412 dbgprintf("Total Unfree %d bytes cnt %d [%p,%d]\n",unfree, unfreecnt, last_alloc, alccnt);
5413 #endif
5414 g_tls = NULL;
5415 list = NULL;