1
|
1 /***********************************************************
|
|
2
|
|
3 Win32 emulation code. Functions that emulate
|
|
4 responses from corresponding Win32 API calls.
|
|
5 Since we are not going to be able to load
|
|
6 virtually any DLL, we can only implement this
|
|
7 much, adding needed functions with each new codec.
|
|
8
|
|
9 ************************************************************/
|
|
10
|
|
11 #include <config.h>
|
|
12
|
|
13 #include "win32.h"
|
|
14 #include <stdio.h>
|
|
15 #include <pthread.h>
|
|
16 #ifdef HAVE_MALLOC_H
|
|
17 #include <malloc.h>
|
|
18 #else
|
|
19 #include <stdlib.h>
|
|
20 #endif
|
|
21 #include <time.h>
|
|
22 #include <sys/types.h>
|
|
23 #include <sys/time.h>
|
|
24 #include <sys/timeb.h>
|
|
25
|
|
26 #include <wine/winbase.h>
|
|
27 #include <wine/winreg.h>
|
|
28 #include <wine/winnt.h>
|
|
29 #include <wine/winerror.h>
|
|
30 #include <wine/debugtools.h>
|
|
31 #include <wine/module.h>
|
|
32
|
|
33 #include <registry.h>
|
|
34 #include <loader.h>
|
|
35 #ifdef USE_TSC
|
|
36 static unsigned int localcount()
|
|
37 {
|
|
38 int a;
|
|
39 __asm__ __volatile__("rdtsc\n\t"
|
|
40 :"=a"(a)
|
|
41 :
|
|
42 :"edx");
|
|
43 return a;
|
|
44 }
|
|
45 static void longcount(long long* z)
|
|
46 {
|
|
47 __asm__ __volatile__(
|
|
48 "pushl %%ebx\n\t"
|
|
49 "movl %%eax, %%ebx\n\t"
|
|
50 "rdtsc\n\t"
|
|
51 "movl %%eax, 0(%%ebx)\n\t"
|
|
52 "movl %%edx, 4(%%ebx)\n\t"
|
|
53 "popl %%ebx\n\t"
|
|
54 ::"a"(z));
|
|
55 }
|
|
56 #else
|
|
57 #include <sys/time.h>
|
|
58 #include <unistd.h>
|
|
59 static unsigned int localcount()
|
|
60 {
|
|
61 struct timeval tv;
|
|
62 unsigned limit=~0;
|
|
63 limit/=1000000;
|
|
64 gettimeofday(&tv, 0);
|
|
65 return limit*tv.tv_usec;
|
|
66 }
|
|
67 static void longcount(long long* z)
|
|
68 {
|
|
69 struct timeval tv;
|
|
70 unsigned long long result;
|
|
71 unsigned limit=~0;
|
|
72 if(!z)return;
|
|
73 limit/=1000000;
|
|
74 gettimeofday(&tv, 0);
|
|
75 result=tv.tv_sec;
|
|
76 result<<=32;
|
|
77 result+=limit*tv.tv_usec;
|
|
78 *z=result;
|
|
79 }
|
|
80 #endif
|
|
81
|
|
82 void dbgprintf(char* fmt, ...)
|
|
83 {
|
|
84 #ifdef DETAILED_OUT
|
|
85 #if 1
|
|
86 va_list va;
|
|
87 va_start(va, fmt);
|
|
88 vprintf(fmt, va);
|
|
89 va_end(va);
|
|
90 #else
|
|
91 va_list va;
|
|
92 FILE* f;
|
|
93 va_start(va, fmt);
|
|
94 f=fopen("./log", "a");
|
|
95 if(f==0)return;
|
|
96 vfprintf(f, fmt, va);
|
|
97 fsync(f);
|
|
98 fclose(f);
|
|
99 #endif
|
|
100 #endif
|
|
101 }
|
|
102 char export_names[500][30]={
|
|
103 "name1",
|
|
104 //"name2",
|
|
105 //"name3"
|
|
106 };
|
|
107 //#define min(x,y) ((x)<(y)?(x):(y))
|
|
108
|
|
109 static unsigned char* heap=NULL;
|
|
110 static int heap_counter=0;
|
|
111 void test_heap()
|
|
112 {
|
|
113 int offset=0;
|
|
114 if(heap==0)
|
|
115 return;
|
|
116 while(offset<heap_counter)
|
|
117 {
|
|
118 if(*(int*)(heap+offset)!=0x433476)
|
|
119 {
|
|
120 printf("Heap corruption at address %d\n", offset);
|
|
121 return;
|
|
122 }
|
|
123 offset+=8+*(int*)(heap+offset+4);
|
|
124 }
|
|
125 for(;offset<min(offset+1000, 20000000); offset++)
|
|
126 if(heap[offset]!=0xCC)
|
|
127 {
|
|
128 printf("Free heap corruption at address %d\n", offset);
|
|
129 }
|
|
130 }
|
|
131 #undef MEMORY_DEBUG
|
|
132
|
|
133 #ifdef MEMORY_DEBUG
|
|
134
|
|
135 void* my_mreq(int size, int to_zero)
|
|
136 {
|
|
137 static int test=0;
|
|
138 test++;
|
|
139 if(test%10==0)printf("Memory: %d bytes allocated\n", heap_counter);
|
|
140 // test_heap();
|
|
141 if(heap==NULL)
|
|
142 {
|
|
143 heap=malloc(20000000);
|
|
144 memset(heap, 0xCC,20000000);
|
|
145 }
|
|
146 if(heap==0)
|
|
147 {
|
|
148 printf("No enough memory\n");
|
|
149 return 0;
|
|
150 }
|
|
151 if(heap_counter+size>20000000)
|
|
152 {
|
|
153 printf("No enough memory\n");
|
|
154 return 0;
|
|
155 }
|
|
156 *(int*)(heap+heap_counter)=0x433476;
|
|
157 heap_counter+=4;
|
|
158 *(int*)(heap+heap_counter)=size;
|
|
159 heap_counter+=4;
|
|
160 printf("Allocated %d bytes of memory: sys %d, user %d-%d\n", size, heap_counter-8, heap_counter, heap_counter+size);
|
|
161 if(to_zero)
|
|
162 memset(heap+heap_counter, 0, size);
|
|
163 heap_counter+=size;
|
|
164 return heap+heap_counter-size;
|
|
165 }
|
|
166 int my_release(char* memory)
|
|
167 {
|
|
168 // test_heap();
|
|
169 if(memory==NULL)
|
|
170 {
|
|
171 printf("ERROR: free(0)\n");
|
|
172 return 0;
|
|
173 }
|
|
174 if(*(int*)(memory-8)!=0x433476)
|
|
175 {
|
|
176 printf("MEMORY CORRUPTION !!!!!!!!!!!!!!!!!!!\n");
|
|
177 return 0;
|
|
178 }
|
|
179 printf("Freed %d bytes of memory\n", *(int*)(memory-4));
|
|
180 // memset(memory-8, *(int*)(memory-4), 0xCC);
|
|
181 return 0;
|
|
182 }
|
|
183
|
|
184 #else
|
|
185 void* my_mreq(int size, int to_zero)
|
|
186 {
|
|
187 void* answer;
|
|
188 if(to_zero)
|
|
189 answer=calloc(size+4, 1);
|
|
190 else
|
|
191 answer=malloc(size+4);
|
|
192 *(int*)answer=size;
|
|
193 return (int*)answer+1;
|
|
194 }
|
|
195 int my_release(char* memory)
|
|
196 {
|
|
197 if(memory==0)return 0;
|
|
198 free(memory-4);
|
|
199 return 0;
|
|
200 }
|
|
201 #endif
|
|
202 int my_size(char* memory)
|
|
203 {
|
|
204 return *(int*)(memory-4);
|
|
205 }
|
|
206
|
|
207 extern int unk_exp1;
|
|
208 char extcode[20000];// place for 200 unresolved exports
|
|
209 int pos=0;
|
|
210
|
|
211 int WINAPI ext_unknown()
|
|
212 {
|
|
213 printf("Unknown func called\n");
|
|
214 return 0;
|
|
215 }
|
|
216 int WINAPI expIsBadWritePtr(void* ptr, unsigned int count)
|
|
217 {
|
|
218 dbgprintf("IsBadWritePtr(%x, %x)\n", ptr, count);
|
|
219 if(count==0)
|
|
220 return 0;
|
|
221 if(ptr==0)
|
|
222 return 1;
|
|
223 return 0;
|
|
224 }
|
|
225 int WINAPI expIsBadReadPtr(void* ptr, unsigned int count)
|
|
226 {
|
|
227 dbgprintf("IsBadReadPtr(%x, %x)\n", ptr, count);
|
|
228 if(count==0)
|
|
229 return 0;
|
|
230 if(ptr==0)
|
|
231 return 1;
|
|
232 return 0;
|
|
233 }
|
|
234 void* CDECL expmalloc(int size)
|
|
235 {
|
|
236 //printf("malloc");
|
|
237 // return malloc(size);
|
|
238 void* result=my_mreq(size,0);
|
|
239 dbgprintf("malloc(%x)\n", size);
|
|
240 if(result==0)
|
|
241 {
|
|
242 dbgprintf("returns 0\n");
|
|
243 printf("WARNING: malloc() failed\n");
|
|
244 }
|
|
245 return result;
|
|
246 }
|
|
247 void CDECL expfree(void* mem)
|
|
248 {
|
|
249 // return free(mem);
|
|
250 dbgprintf("free(%x)\n", mem);
|
|
251 my_release(mem);
|
|
252 }
|
|
253 void* CDECL expnew(int size)
|
|
254 {
|
|
255 // printf("NEW:: Call from address %08x\n STACK DUMP:\n", *(-1+(int*)&size));
|
|
256 // printf("%08x %08x %08x %08x\n",
|
|
257 // size, *(1+(int*)&size),
|
|
258 // *(2+(int*)&size),*(3+(int*)&size));
|
|
259 void* result=expmalloc(size);
|
|
260 dbgprintf("new(%x)\n", size);
|
|
261 if(result==0)
|
|
262 {
|
|
263 dbgprintf("returns 0\n");
|
|
264 printf("WARNING: malloc() failed\n");
|
|
265 }
|
|
266 return result;
|
|
267
|
|
268 }
|
|
269 int CDECL expdelete(void* memory)
|
|
270 {
|
|
271 dbgprintf("delete(%x)\n", memory);
|
|
272 expfree(memory);
|
|
273 return 0;
|
|
274 }
|
|
275 int WINAPI expDisableThreadLibraryCalls(int module)
|
|
276 {
|
|
277 dbgprintf("DisableThreadLibraryCalls(%x)\n", module);
|
|
278 return 0;
|
|
279 }
|
|
280 int CDECL exp_initterm(int v1, int v2)
|
|
281 {
|
|
282 return 0;
|
|
283 }
|
|
284
|
|
285 typedef struct {
|
|
286 unsigned int uDriverSignature;
|
|
287 void* hDriverModule;
|
|
288 void* DriverProc;
|
|
289 unsigned int dwDriverID;
|
|
290 } DRVR;
|
|
291
|
|
292 void* WINAPI expGetDriverModuleHandle(DRVR* pdrv)
|
|
293 {
|
|
294 dbgprintf("GetDriverModuleHandle(%x)\n", pdrv);
|
|
295 return pdrv->hDriverModule;
|
|
296 }
|
|
297
|
|
298 void* WINAPI expGetModuleHandleA(const char* name)
|
|
299 {
|
|
300 WINE_MODREF* wm;
|
|
301 dbgprintf("GetModuleHandleA(%s)\n", name);
|
|
302 if(!name)return 0;
|
|
303 wm=MODULE_FindModule(name);
|
|
304 if(wm==0)return 0;
|
|
305 return (void*)(wm->module);
|
|
306 }
|
|
307 struct th_list_t;
|
|
308 typedef struct th_list_t{
|
|
309 int id;
|
|
310 void* thread;
|
|
311 struct th_list_t* next;
|
|
312 struct th_list_t* prev;
|
|
313 }th_list;
|
|
314
|
|
315 static th_list* list=NULL;
|
|
316
|
|
317
|
|
318
|
|
319 void* WINAPI expCreateThread(void* pSecAttr, long dwStackSize, void* lpStartAddress,
|
|
320 void* lpParameter, long dwFlags, long* dwThreadId)
|
|
321 {
|
|
322 pthread_t *pth;
|
|
323 // printf("CreateThread:");
|
|
324 pth=my_mreq(sizeof(pthread_t), 0);
|
|
325 dbgprintf("pthread_create\n");
|
|
326 pthread_create(pth, NULL, (void*(*)(void*))lpStartAddress, lpParameter);
|
|
327 if(dwFlags)
|
|
328 dbgprintf( "WARNING: CreateThread flags not supported\n");
|
|
329 if(dwThreadId)
|
|
330 *dwThreadId=(long)pth;
|
|
331 dbgprintf( "Created thread %08X\n", pth);
|
|
332 if(list==NULL)
|
|
333 {
|
|
334 list=my_mreq(sizeof(th_list), 1);
|
|
335 list->next=list->prev=NULL;
|
|
336 }
|
|
337 else
|
|
338 {
|
|
339 list->next=my_mreq(sizeof(th_list), 0);
|
|
340 list->next->prev=list;
|
|
341 list->next->next=NULL;
|
|
342 list=list->next;
|
|
343 }
|
|
344 list->thread=pth;
|
|
345 return pth;
|
|
346 }
|
|
347
|
|
348 struct mutex_list_t;
|
|
349
|
|
350 struct mutex_list_t
|
|
351 {
|
|
352 pthread_mutex_t *pm;
|
|
353 char name[64];
|
|
354 struct mutex_list_t* next;
|
|
355 struct mutex_list_t* prev;
|
|
356 };
|
|
357 typedef struct mutex_list_t mutex_list;
|
|
358 static mutex_list* mlist=NULL;
|
|
359 void* WINAPI expCreateEventA(void* pSecAttr, char bManualReset,
|
|
360 char bInitialState, const char* name)
|
|
361 {
|
|
362 #warning ManualReset
|
|
363 pthread_mutex_t *pm;
|
|
364 dbgprintf("CreateEvent\n");
|
|
365 if(mlist!=NULL)
|
|
366 {
|
|
367 mutex_list* pp=mlist;
|
|
368 if(name!=NULL)
|
|
369 do
|
|
370 {
|
|
371 if(strcmp(pp->name, name)==0)
|
|
372 return pp->pm;
|
|
373 }while(pp=pp->prev);
|
|
374 }
|
|
375 pm=my_mreq(sizeof(pthread_mutex_t), 0);
|
|
376 pthread_mutex_init(pm, NULL);
|
|
377 if(mlist==NULL)
|
|
378 {
|
|
379 mlist=my_mreq(sizeof(mutex_list), 00);
|
|
380 mlist->next=mlist->prev=NULL;
|
|
381 }
|
|
382 else
|
|
383 {
|
|
384 mlist->next=my_mreq(sizeof(mutex_list), 00);
|
|
385 mlist->next->prev=mlist->next;
|
|
386 mlist->next->next=NULL;
|
|
387 mlist=mlist->next;
|
|
388 }
|
|
389 mlist->pm=pm;
|
|
390 if(name!=NULL)
|
|
391 strncpy(mlist->name, name, 64);
|
|
392 else
|
|
393 mlist->name[0]=0;
|
|
394 if(pm==NULL)
|
|
395 dbgprintf("ERROR::: CreateEventA failure\n");
|
|
396 if(bInitialState)
|
|
397 pthread_mutex_lock(pm);
|
|
398 return pm;
|
|
399 }
|
|
400
|
|
401 void* WINAPI expSetEvent(void* event)
|
|
402 {
|
|
403 dbgprintf("Trying to lock %X\n", event);
|
|
404 pthread_mutex_lock(event);
|
|
405 }
|
|
406 void* WINAPI expResetEvent(void* event)
|
|
407 {
|
|
408 dbgprintf("Unlocking %X\n", event);
|
|
409 pthread_mutex_unlock(event);
|
|
410 }
|
|
411
|
|
412 void* WINAPI expWaitForSingleObject(void* object, int duration)
|
|
413 {
|
|
414 #warning not sure
|
|
415 dbgprintf("WaitForSingleObject: duration %d\n", duration);
|
|
416 pthread_mutex_lock(object);
|
|
417 pthread_mutex_unlock(object);
|
|
418 }
|
|
419
|
|
420 static BYTE PF[64] = {0,};
|
|
421
|
|
422 void WINAPI expGetSystemInfo(SYSTEM_INFO* si)
|
|
423 {
|
|
424 /* FIXME: better values for the two entries below... */
|
|
425 static int cache = 0;
|
|
426 static SYSTEM_INFO cachedsi;
|
|
427 HKEY xhkey=0,hkey;
|
|
428 dbgprintf("GetSystemInfo()\n");
|
|
429
|
|
430 if (cache) {
|
|
431 memcpy(si,&cachedsi,sizeof(*si));
|
|
432 return;
|
|
433 }
|
|
434 memset(PF,0,sizeof(PF));
|
|
435
|
|
436 cachedsi.u.s.wProcessorArchitecture = PROCESSOR_ARCHITECTURE_INTEL;
|
|
437 cachedsi.dwPageSize = getpagesize();
|
|
438
|
|
439 /* FIXME: better values for the two entries below... */
|
|
440 cachedsi.lpMinimumApplicationAddress = (void *)0x40000000;
|
|
441 cachedsi.lpMaximumApplicationAddress = (void *)0x7FFFFFFF;
|
|
442 cachedsi.dwActiveProcessorMask = 1;
|
|
443 cachedsi.dwNumberOfProcessors = 1;
|
|
444 cachedsi.dwProcessorType = PROCESSOR_INTEL_386;
|
|
445 cachedsi.dwAllocationGranularity = 0x10000;
|
|
446 cachedsi.wProcessorLevel = 3; /* pentium */
|
|
447 cachedsi.wProcessorRevision = 0;
|
|
448
|
|
449 #ifdef __FreeBSD__
|
|
450 cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
|
|
451 cachedsi.wProcessorLevel= 5;
|
|
452 PF[PF_COMPARE_EXCHANGE_DOUBLE] = TRUE;
|
|
453 #ifdef MMX
|
|
454 PF[PF_MMX_INSTRUCTIONS_AVAILABLE] = TRUE;
|
|
455 #endif
|
|
456 cachedsi.dwNumberOfProcessors=1;
|
|
457 #else
|
|
458 {
|
|
459 char buf[20];
|
|
460 char line[200];
|
|
461 FILE *f = fopen ("/proc/cpuinfo", "r");
|
|
462
|
|
463 if (!f)
|
|
464 return;
|
|
465 xhkey = 0;
|
|
466 while (fgets(line,200,f)!=NULL) {
|
|
467 char *s,*value;
|
|
468
|
|
469 /* NOTE: the ':' is the only character we can rely on */
|
|
470 if (!(value = strchr(line,':')))
|
|
471 continue;
|
|
472 /* terminate the valuename */
|
|
473 *value++ = '\0';
|
|
474 /* skip any leading spaces */
|
|
475 while (*value==' ') value++;
|
|
476 if ((s=strchr(value,'\n')))
|
|
477 *s='\0';
|
|
478
|
|
479 /* 2.1 method */
|
|
480 if (!lstrncmpiA(line, "cpu family",strlen("cpu family"))) {
|
|
481 if (isdigit (value[0])) {
|
|
482 switch (value[0] - '0') {
|
|
483 case 3: cachedsi.dwProcessorType = PROCESSOR_INTEL_386;
|
|
484 cachedsi.wProcessorLevel= 3;
|
|
485 break;
|
|
486 case 4: cachedsi.dwProcessorType = PROCESSOR_INTEL_486;
|
|
487 cachedsi.wProcessorLevel= 4;
|
|
488 break;
|
|
489 case 5: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
|
|
490 cachedsi.wProcessorLevel= 5;
|
|
491 break;
|
|
492 case 6: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
|
|
493 cachedsi.wProcessorLevel= 5;
|
|
494 break;
|
|
495 default:cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
|
|
496 cachedsi.wProcessorLevel= 5;
|
|
497 break;
|
|
498 }
|
|
499 }
|
|
500 /* set the CPU type of the current processor */
|
|
501 sprintf(buf,"CPU %ld",cachedsi.dwProcessorType);
|
|
502 continue;
|
|
503 }
|
|
504 /* old 2.0 method */
|
|
505 if (!lstrncmpiA(line, "cpu",strlen("cpu"))) {
|
|
506 if ( isdigit (value[0]) && value[1] == '8' &&
|
|
507 value[2] == '6' && value[3] == 0
|
|
508 ) {
|
|
509 switch (value[0] - '0') {
|
|
510 case 3: cachedsi.dwProcessorType = PROCESSOR_INTEL_386;
|
|
511 cachedsi.wProcessorLevel= 3;
|
|
512 break;
|
|
513 case 4: cachedsi.dwProcessorType = PROCESSOR_INTEL_486;
|
|
514 cachedsi.wProcessorLevel= 4;
|
|
515 break;
|
|
516 case 5: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
|
|
517 cachedsi.wProcessorLevel= 5;
|
|
518 break;
|
|
519 case 6: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
|
|
520 cachedsi.wProcessorLevel= 5;
|
|
521 break;
|
|
522 default:cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM;
|
|
523 cachedsi.wProcessorLevel= 5;
|
|
524 break;
|
|
525 }
|
|
526 }
|
|
527 /* set the CPU type of the current processor */
|
|
528 sprintf(buf,"CPU %ld",cachedsi.dwProcessorType);
|
|
529 continue;
|
|
530 }
|
|
531 if (!lstrncmpiA(line,"fdiv_bug",strlen("fdiv_bug"))) {
|
|
532 if (!lstrncmpiA(value,"yes",3))
|
|
533 PF[PF_FLOATING_POINT_PRECISION_ERRATA] = TRUE;
|
|
534
|
|
535 continue;
|
|
536 }
|
|
537 if (!lstrncmpiA(line,"fpu",strlen("fpu"))) {
|
|
538 if (!lstrncmpiA(value,"no",2))
|
|
539 PF[PF_FLOATING_POINT_EMULATED] = TRUE;
|
|
540
|
|
541 continue;
|
|
542 }
|
|
543 if (!lstrncmpiA(line,"processor",strlen("processor"))) {
|
|
544 /* processor number counts up...*/
|
|
545 int x;
|
|
546
|
|
547 if (sscanf(value,"%d",&x))
|
|
548 if (x+1>cachedsi.dwNumberOfProcessors)
|
|
549 cachedsi.dwNumberOfProcessors=x+1;
|
|
550
|
|
551 /* Create a new processor subkey on a multiprocessor
|
|
552 * system
|
|
553 */
|
|
554 sprintf(buf,"%d",x);
|
|
555 }
|
|
556 if (!lstrncmpiA(line,"stepping",strlen("stepping"))) {
|
|
557 int x;
|
|
558
|
|
559 if (sscanf(value,"%d",&x))
|
|
560 cachedsi.wProcessorRevision = x;
|
|
561 }
|
|
562 if ( (!lstrncmpiA(line,"flags",strlen("flags"))) ||
|
|
563 (!lstrncmpiA(line,"features",strlen("features"))) ) {
|
|
564 if (strstr(value,"cx8"))
|
|
565 PF[PF_COMPARE_EXCHANGE_DOUBLE] = TRUE;
|
|
566 if (strstr(value,"mmx"))
|
|
567 PF[PF_MMX_INSTRUCTIONS_AVAILABLE] = TRUE;
|
|
568
|
|
569 }
|
|
570 }
|
|
571 fclose (f);
|
|
572 }
|
|
573 #endif /* __FreeBSD__ */
|
|
574 memcpy(si,&cachedsi,sizeof(*si));
|
|
575 }
|
|
576
|
|
577 long WINAPI expGetVersion()
|
|
578 {
|
|
579 return 0xC0000A04;//Windows 98
|
|
580 }
|
|
581
|
|
582 HANDLE WINAPI expHeapCreate(long flags, long init_size, long max_size)
|
|
583 {
|
|
584 // printf("HeapCreate:");
|
|
585 dbgprintf("HeapCreate(%X, %X, %X)\n", flags, init_size, max_size);
|
|
586 if(init_size==0)
|
|
587 return (HANDLE)my_mreq(0x110000, 0);
|
|
588 else
|
|
589 return (HANDLE)my_mreq(init_size, 0);
|
|
590 }
|
|
591 void* WINAPI expHeapAlloc(HANDLE heap, int flags, int size)
|
|
592 {
|
|
593 void* z;
|
|
594 dbgprintf("HeapAlloc(%X, %X, %X)\n", heap, flags, size);
|
|
595 // printf("HeapAlloc:");
|
|
596 z=my_mreq(size, flags&8);
|
|
597 // z=HeapAlloc(heap,flags,size);
|
|
598 if(z==0)
|
|
599 printf("HeapAlloc failure\n");
|
|
600 return z;
|
|
601 }
|
|
602 long WINAPI expHeapDestroy(void* heap)
|
|
603 {
|
|
604 dbgprintf("HeapDestroy(%X)\n", heap);
|
|
605 my_release(heap);
|
|
606 return 1;
|
|
607 }
|
|
608
|
|
609 long WINAPI expHeapFree(int arg1, int arg2, void* ptr)
|
|
610 {
|
|
611 dbgprintf("HeapFree(%X, %X, %X)\n", arg1, arg2, ptr);
|
|
612 my_release(ptr);
|
|
613 return 1;
|
|
614 }
|
|
615 long WINAPI expHeapSize(int heap, int flags, void* pointer)
|
|
616 {
|
|
617 return my_size(pointer);
|
|
618 }
|
|
619 long WINAPI expGetProcessHeap(void)
|
|
620 {
|
|
621 return 1;
|
|
622 }
|
|
623 void* WINAPI expVirtualAlloc(void* v1, long v2, long v3, long v4)
|
|
624 {
|
|
625 void* z;
|
|
626 dbgprintf("VirtualAlloc(%d %d %d %d) \n",v1,v2,v3,v4);
|
|
627 z=VirtualAlloc(v1, v2, v3, v4);
|
|
628 if(z==0)
|
|
629 printf("VirtualAlloc failure\n");
|
|
630 return z;
|
|
631 }
|
|
632 int WINAPI expVirtualFree(void* v1, int v2, int v3)
|
|
633 {
|
|
634 dbgprintf("VirtualFree(%X %X %X) \n",v1,v2,v3);
|
|
635 return VirtualFree(v1,v2,v3);
|
|
636 }
|
|
637 struct CRITSECT
|
|
638 {
|
|
639 pthread_t id;
|
|
640 pthread_mutex_t mutex;
|
|
641 int locked;
|
|
642 };
|
|
643 void WINAPI expInitializeCriticalSection(CRITICAL_SECTION* c)
|
|
644 {
|
|
645 struct CRITSECT cs;
|
|
646 dbgprintf("InitCriticalSection(%X) \n", c);
|
|
647 /* if(sizeof(pthread_mutex_t)>sizeof(CRITICAL_SECTION))
|
|
648 {
|
|
649 printf(" ERROR:::: sizeof(pthread_mutex_t) is %d, expected <=%d!\n",
|
|
650 sizeof(pthread_mutex_t), sizeof(CRITICAL_SECTION));
|
|
651 return;
|
|
652 }*/
|
|
653 /* pthread_mutex_init((pthread_mutex_t*)c, NULL); */
|
|
654 pthread_mutex_init(&cs.mutex, NULL);
|
|
655 cs.locked=0;
|
|
656 *(void**)c=malloc(sizeof cs);
|
|
657 memcpy(*(void**)c, &cs, sizeof cs);
|
|
658 return;
|
|
659 }
|
|
660 void WINAPI expEnterCriticalSection(CRITICAL_SECTION* c)
|
|
661 {
|
|
662 struct CRITSECT* cs=(struct CRITSECT*)c;
|
|
663 dbgprintf("EnterCriticalSection(%X) \n",c);
|
|
664 // cs.id=pthread_self();
|
|
665 if(cs->locked)
|
|
666 if(cs->id==pthread_self())
|
|
667 return;
|
|
668 pthread_mutex_lock(&(cs->mutex));
|
|
669 cs->locked=1;
|
|
670 cs->id=pthread_self();
|
|
671 return;
|
|
672 }
|
|
673 void WINAPI expLeaveCriticalSection(CRITICAL_SECTION* c)
|
|
674 {
|
|
675 struct CRITSECT* cs=(struct CRITSECT*)c;
|
|
676 dbgprintf("LeaveCriticalSection(%X) \n",c);
|
|
677 cs->locked=0;
|
|
678 pthread_mutex_unlock(&(cs->mutex));
|
|
679 return;
|
|
680 }
|
|
681 void WINAPI expDeleteCriticalSection(CRITICAL_SECTION *c)
|
|
682 {
|
|
683 dbgprintf("DeleteCriticalSection(%X) \n",c);
|
|
684 pthread_mutex_destroy((pthread_mutex_t*)c);
|
|
685 return;
|
|
686 }
|
|
687 int WINAPI expGetCurrentThreadId()
|
|
688 {
|
|
689 dbgprintf("GetCurrentThreadId() \n");
|
|
690 return getpid();
|
|
691 }
|
|
692 struct tls_s;
|
|
693 typedef struct tls_s
|
|
694 {
|
|
695 void* value;
|
|
696 int used;
|
|
697 struct tls_s* prev;
|
|
698 struct tls_s* next;
|
|
699 }tls_t;
|
|
700
|
|
701 tls_t* g_tls=NULL;
|
|
702
|
|
703 void* WINAPI expTlsAlloc()
|
|
704 {
|
|
705 dbgprintf("TlsAlloc \n");
|
|
706 if(g_tls==NULL)
|
|
707 {
|
|
708 g_tls=my_mreq(sizeof(tls_t), 0);
|
|
709 g_tls->next=g_tls->prev=NULL;
|
|
710 }
|
|
711 else
|
|
712 {
|
|
713 g_tls->next=my_mreq(sizeof(tls_t), 0);
|
|
714 g_tls->next->prev=g_tls;
|
|
715 g_tls->next->next=NULL;
|
|
716 g_tls=g_tls->next;
|
|
717 }
|
|
718 return g_tls;
|
|
719 }
|
|
720
|
|
721 int WINAPI expTlsSetValue(tls_t* index, void* value)
|
|
722 {
|
|
723 dbgprintf("TlsSetVal(%X %X) \n", index, value );
|
|
724 if(index==0)
|
|
725 return 0;
|
|
726 index->value=value;
|
|
727 return 1;
|
|
728 }
|
|
729 void* WINAPI expTlsGetValue(tls_t* index)
|
|
730 {
|
|
731 dbgprintf("TlsGetVal(%X) \n", index );
|
|
732 if(index==0)
|
|
733 return 0;
|
|
734 return index->value;
|
|
735 }
|
|
736 int WINAPI expTlsFree(tls_t* index)
|
|
737 {
|
|
738 dbgprintf("TlsFree(%X) \n", index);
|
|
739 if(index==0)
|
|
740 return 0;
|
|
741 if(index->next)
|
|
742 index->next->prev=index->prev;
|
|
743 if(index->prev)
|
|
744 index->prev->next=index->next;
|
|
745 my_release((void*)index);
|
|
746 return 1;
|
|
747 }
|
|
748
|
|
749 void* WINAPI expLocalAlloc(int flags, int size)
|
|
750 {
|
|
751 void* z;
|
|
752 dbgprintf("LocalAlloc(%d, flags %X)\n", size, flags);
|
|
753 if(flags&GMEM_ZEROINIT)
|
|
754 z=my_mreq(size, 1);
|
|
755 else
|
|
756 z=my_mreq(size, 0);
|
|
757 if(z==0)
|
|
758 printf("LocalAlloc() failed\n");
|
|
759 return z;
|
|
760 }
|
|
761 void* WINAPI expLocalLock(void* z)
|
|
762 {
|
|
763 dbgprintf("LocalLock\n");
|
|
764 return z;
|
|
765 }
|
|
766 void* WINAPI expGlobalAlloc(int flags, int size)
|
|
767 {
|
|
768 void* z;
|
|
769 dbgprintf("GlobalAlloc(%d, flags 0x%X)\n", size, flags);
|
|
770 if(flags&GMEM_ZEROINIT)
|
|
771 z=my_mreq(size, 1);
|
|
772 else
|
|
773 z=my_mreq(size, 0);
|
|
774 if(z==0)
|
|
775 printf("LocalAlloc() failed\n");
|
|
776 return z;
|
|
777 }
|
|
778 void* WINAPI expGlobalLock(void* z)
|
|
779 {
|
|
780 dbgprintf("GlobalLock\n");
|
|
781 return z;
|
|
782 }
|
|
783
|
|
784 int WINAPI expLoadStringA(long instance, long id, void* buf, long size)
|
|
785 {
|
|
786 dbgprintf("LoadStringA\n");
|
|
787 return LoadStringA(instance, id, buf, size);
|
|
788 }
|
|
789
|
|
790 long WINAPI expMultiByteToWideChar(long v1, long v2, char* s1, long siz1, char* s2, int siz2)
|
|
791 {
|
|
792 #warning FIXME
|
|
793 dbgprintf("MB2WCh\n");
|
|
794 dbgprintf("WARNING: Unsupported call: MBToWCh %s\n", s1);
|
|
795 if(s2==0)
|
|
796 return 1;
|
|
797 s2[0]=s2[1]=0;
|
|
798 return 1;
|
|
799 }
|
|
800 long WINAPI expWideCharToMultiByte(long v1, long v2, short* s1, long siz1, char* s2, int siz2, char* c3, int* siz3)
|
|
801 {
|
|
802 int result;
|
|
803 dbgprintf("WCh2MB\n");
|
|
804 result=WideCharToMultiByte(v1, v2, s1, siz1, s2, siz2, c3, siz3);
|
|
805 dbgprintf("=> %d\n", result);
|
|
806 return result;
|
|
807 }
|
|
808 long WINAPI expGetVersionExA(OSVERSIONINFOA* c)
|
|
809 {
|
|
810 dbgprintf("GetVersionExA\n");
|
|
811 c->dwMajorVersion=4;
|
|
812 c->dwMinorVersion=10;
|
|
813 c->dwBuildNumber=0x40a07ce;
|
|
814 c->dwPlatformId=VER_PLATFORM_WIN32_WINDOWS;
|
|
815 strcpy(c->szCSDVersion, "Win98");
|
|
816 return 1;
|
|
817 }
|
|
818 #include <sys/types.h>
|
|
819 #include <sys/ipc.h>
|
|
820 #include <sys/sem.h>
|
|
821 HANDLE WINAPI expCreateSemaphoreA(char* v1, long init_count, long max_count, char* name)
|
|
822 {
|
|
823 #warning FIXME
|
|
824 /* struct sembuf buf[1];
|
|
825 int sem=semget(IPC_PRIVATE,1,IPC_CREAT);
|
|
826 if(sem==-1)
|
|
827 {
|
|
828 printf("semget() failed\n");
|
|
829 return (HANDLE)-1;
|
|
830 }
|
|
831 buf[0].sem_num=0;
|
|
832 printf("%s\n", name);
|
|
833 printf("Init count %d, max count %d\n", init_count, max_count);
|
|
834 buf[0].sem_op=-max_count+init_count;
|
|
835 buf[0].sem_flg=0;
|
|
836 if(semop(sem, &buf, 1)<0)
|
|
837 {
|
|
838 printf("semop() failed\n");
|
|
839 }
|
|
840 return sem;
|
|
841 */
|
|
842 void* z;
|
|
843 dbgprintf("CreateSemaphoreA\n");
|
|
844 z=my_mreq(24, 0);
|
|
845 pthread_mutex_init(z, NULL);
|
|
846 return (HANDLE)z;
|
|
847 }
|
|
848
|
|
849 long WINAPI expReleaseSemaphore(long hsem, long increment, long* prev_count)
|
|
850 {
|
|
851 // The state of a semaphore object is signaled when its count
|
|
852 // is greater than zero and nonsignaled when its count is equal to zero
|
|
853 // Each time a waiting thread is released because of the semaphore's signaled
|
|
854 // state, the count of the semaphore is decreased by one.
|
|
855 struct sembuf buf[1];
|
|
856 dbgprintf("ReleaseSemaphore\n");
|
|
857 dbgprintf("WARNING: Unsupported call: ReleaseSemaphoreA\n");
|
|
858 /* if(hsem==-1)return 0;
|
|
859 buf[0].sem_num=0;
|
|
860 buf[0].sem_op=-1;
|
|
861 buf[0].sem_flg=0;
|
|
862 if(semop(hsem, &buf, 1)<0)
|
|
863 {
|
|
864 printf("ReleaseSemaphore: semop() failed\n");
|
|
865 }*/
|
|
866
|
|
867 return 1;//zero on error
|
|
868 }
|
|
869
|
|
870
|
|
871 long WINAPI expRegOpenKeyExA(long key, const char* subkey, long reserved, long access, int* newkey)
|
|
872 {
|
|
873 dbgprintf("RegOpenKeyExA(%d,%s)\n", key, subkey);
|
|
874 return RegOpenKeyExA(key, subkey, reserved, access, newkey);
|
|
875 }
|
|
876 long WINAPI expRegCloseKey(long key)
|
|
877 {
|
|
878 dbgprintf("RegCloseKey()\n");
|
|
879 return RegCloseKey(key);
|
|
880 }
|
|
881 long WINAPI expRegQueryValueExA(long key, const char* value, int* reserved, int* type, int* data, int* count)
|
|
882 {
|
|
883 dbgprintf("RegQueryValueExA()\n");
|
|
884 return RegQueryValueExA(key, value, reserved, type, data, count);
|
|
885 }
|
|
886 long WINAPI expRegCreateKeyExA(long key, const char* name, long reserved,
|
|
887 void* classs, long options, long security,
|
|
888 void* sec_attr, int* newkey, int* status)
|
|
889 {
|
|
890 dbgprintf("RegCreateKeyExA()\n");
|
|
891 return RegCreateKeyExA(key, name, reserved, classs, options, security, sec_attr, newkey, status);
|
|
892 }
|
|
893 long WINAPI expRegSetValueExA(long key, const char* name, long v1, long v2, void* data, long size)
|
|
894 {
|
|
895 dbgprintf("RegSetValueExA()\n");
|
|
896 return RegSetValueExA(key, name, v1, v2, data, size);
|
|
897 }
|
|
898
|
|
899 long WINAPI expRegOpenKeyA (
|
|
900 long hKey,
|
|
901 LPCSTR lpSubKey,
|
|
902 int* phkResult
|
|
903 ){
|
|
904 return RegOpenKeyExA(hKey, lpSubKey, 0, 0, phkResult);
|
|
905 }
|
|
906
|
|
907 long WINAPI expQueryPerformanceCounter(long long* z)
|
|
908 {
|
|
909 dbgprintf("QueryPerformanceCounter()\n");
|
|
910 longcount(z);
|
|
911 return 1;
|
|
912 }
|
|
913
|
|
914 static double old_freq()
|
|
915 {
|
|
916 int i=time(NULL);
|
|
917 int x,y;
|
|
918 while(i==time(NULL));
|
|
919 x=localcount();
|
|
920 i++;
|
|
921 while(i==time(NULL));
|
|
922 y=localcount();
|
|
923 return (double)(y-x)/1000.;
|
|
924 }
|
|
925 static double CPU_Freq()
|
|
926 {
|
|
927 #ifdef USE_TSC
|
|
928 FILE *f = fopen ("/proc/cpuinfo", "r");
|
|
929 char line[200];
|
|
930 char model[200]="unknown";
|
|
931 char flags[500]="";
|
|
932 char *s,*value;
|
|
933 double freq=-1;
|
|
934
|
|
935 if (!f)
|
|
936 {
|
|
937 printf("Can't open /proc/cpuinfo for reading\n");
|
|
938 return old_freq();
|
|
939 }
|
|
940 while (fgets(line,200,f)!=NULL)
|
|
941 {
|
|
942 /* NOTE: the ':' is the only character we can rely on */
|
|
943 if (!(value = strchr(line,':')))
|
|
944 continue;
|
|
945 /* terminate the valuename */
|
|
946 *value++ = '\0';
|
|
947 /* skip any leading spaces */
|
|
948 while (*value==' ') value++;
|
|
949 if ((s=strchr(value,'\n')))
|
|
950 *s='\0';
|
|
951
|
|
952 if (!strncasecmp(line, "cpu MHz",strlen("cpu MHz")))
|
|
953 {
|
|
954 sscanf(value, "%lf", &freq);
|
|
955 freq*=1000;
|
|
956 break;
|
|
957 }
|
|
958 continue;
|
|
959
|
|
960 }
|
|
961 fclose(f);
|
|
962 if(freq<0)return old_freq();
|
|
963 return freq;
|
|
964 #else
|
|
965 return old_freq();
|
|
966 #endif
|
|
967 }
|
|
968
|
|
969 long WINAPI expQueryPerformanceFrequency(long long* z)
|
|
970 {
|
|
971 dbgprintf("QueryPerformanceFrequency()\n");
|
|
972 *z=(long long)CPU_Freq();
|
|
973 return 1;
|
|
974 }
|
|
975 long WINAPI exptimeGetTime()
|
|
976 {
|
|
977 struct timeval t;
|
|
978 dbgprintf("timeGetTime()\n");
|
|
979 gettimeofday(&t, 0);
|
|
980 return 1000*t.tv_sec+t.tv_usec/1000;
|
|
981 }
|
|
982 void* WINAPI expLocalHandle(void* v)
|
|
983 {
|
|
984 dbgprintf("LocalHandle\n");
|
|
985 return v;
|
|
986 }
|
|
987 void* WINAPI expGlobalHandle(void* v)
|
|
988 {
|
|
989 dbgprintf("GlobalHandle\n");
|
|
990 return v;
|
|
991 }
|
|
992 int WINAPI expGlobalUnlock(void* v)
|
|
993 {
|
|
994 dbgprintf("GlobalUnlock\n");
|
|
995 return 1;
|
|
996 }
|
|
997 //
|
|
998 void* WINAPI expGlobalFree(void* v)
|
|
999 {
|
|
1000 dbgprintf("GlobalFree(%X)\n", v);
|
|
1001 my_release(v);
|
|
1002 return 0;
|
|
1003 }
|
|
1004
|
|
1005 int WINAPI expLocalUnlock(void* v)
|
|
1006 {
|
|
1007 dbgprintf("LocalUnlock\n");
|
|
1008 return 1;
|
|
1009 }
|
|
1010 //
|
|
1011 void* WINAPI expLocalFree(void* v)
|
|
1012 {
|
|
1013 dbgprintf("LocalFree(%X)\n", v);
|
|
1014 my_release(v);
|
|
1015 return 0;
|
|
1016 }
|
|
1017
|
|
1018 HRSRC WINAPI expFindResourceA(HMODULE module, char* name, char* type)
|
|
1019 {
|
|
1020 dbgprintf("FindResourceA\n");
|
|
1021 return FindResourceA(module, name, type);
|
|
1022 }
|
|
1023 HGLOBAL WINAPI expLoadResource(HMODULE module, HRSRC res)
|
|
1024 {
|
|
1025 dbgprintf("LoadResource\n");
|
|
1026 return LoadResource(module, res);;
|
|
1027 }
|
|
1028 void* WINAPI expLockResource(long res)
|
|
1029 {
|
|
1030 dbgprintf("LockResource\n");
|
|
1031 return LockResource(res);
|
|
1032 }
|
|
1033 int WINAPI expFreeResource(long res)
|
|
1034 {
|
|
1035 dbgprintf("FreeResource\n");
|
|
1036 return FreeResource(res);
|
|
1037 }
|
|
1038 //bool fun(HANDLE)
|
|
1039 //!0 on success
|
|
1040 int WINAPI expCloseHandle(long v1)
|
|
1041 {
|
|
1042 dbgprintf("CloseHandle\n");
|
|
1043 return 1;
|
|
1044 }
|
|
1045
|
|
1046 const char* WINAPI expGetCommandLineA()
|
|
1047 {
|
|
1048 dbgprintf("GetCommandLine\n");
|
|
1049 return "c:\\aviplay.exe";
|
|
1050 }
|
|
1051 LPWSTR WINAPI expGetEnvironmentStringsW()
|
|
1052 {
|
|
1053 static wchar_t envs[]={'p', 'a', 't', 'h', ' ', 'c', ':', '\\', 0, 0};
|
|
1054 dbgprintf("GetEnvStringsW\n");
|
|
1055 return (LPWSTR)envs;
|
|
1056 }
|
|
1057
|
|
1058 int WINAPI expFreeEnvironmentStringsW(short* strings)
|
|
1059 {
|
|
1060 dbgprintf("FreeEnvStringsW\n");
|
|
1061 return 1;
|
|
1062 }
|
|
1063 LPCSTR WINAPI expGetEnvironmentStrings()
|
|
1064 {
|
|
1065 dbgprintf("GetEnvStrings\n");
|
|
1066 return "\0\0";
|
|
1067 }
|
|
1068
|
|
1069 int WINAPI expGetStartupInfoA(STARTUPINFOA *s)
|
|
1070 {
|
|
1071 int i;
|
|
1072 dbgprintf("GetStartupInfoA\n");
|
|
1073 /*
|
|
1074 for(i=0; i<sizeof(STARTUPINFOA)/4; i++)
|
|
1075 ((int*)s)[i]=i+0x200;
|
|
1076 */
|
|
1077 memset(s, 0, sizeof(*s));
|
|
1078 s->cb=sizeof(*s);
|
|
1079 s->lpReserved="qwe";
|
|
1080 s->lpDesktop="rty";
|
|
1081 s->lpTitle="uio";
|
|
1082 s->dwX=s->dwY=0;
|
|
1083 s->dwXSize=s->dwYSize=200;
|
|
1084 s->dwFlags=s->wShowWindow=0;
|
|
1085 return 1;
|
|
1086 }
|
|
1087
|
|
1088 int WINAPI expGetStdHandle(int z)
|
|
1089 {
|
|
1090 dbgprintf("GetStdHandle\n");
|
|
1091 dbgprintf("WARNING: Unsupported call: GetStdHandle\n");
|
|
1092 return 1234;
|
|
1093 }
|
|
1094 int WINAPI expGetFileType(int handle)
|
|
1095 {
|
|
1096 dbgprintf("GetFileType\n");
|
|
1097 dbgprintf("WARNING: Unsupported call: GetFileType\n");
|
|
1098 return 5678;
|
|
1099 }
|
|
1100 int WINAPI expSetHandleCount(int count)
|
|
1101 {
|
|
1102 dbgprintf("SetHandleCount\n");
|
|
1103 return 1;
|
|
1104 }
|
|
1105 int WINAPI expGetACP()
|
|
1106 {
|
|
1107 dbgprintf("GetACP\n");
|
|
1108 dbgprintf("WARNING: Unsupported call: GetACP\n");
|
|
1109 return 0;
|
|
1110 }
|
|
1111 extern WINE_MODREF *MODULE32_LookupHMODULE(HMODULE m);
|
|
1112 int WINAPI expGetModuleFileNameA(int module, char* s, int len)
|
|
1113 {
|
|
1114 WINE_MODREF *mr;
|
|
1115 dbgprintf("GetModuleFileNameA\n");
|
|
1116 // printf("File name of module %X requested\n", module);
|
|
1117 if(s==0)
|
|
1118 return 0;
|
|
1119 if(len<35)
|
|
1120 return 0;
|
|
1121 strcpy(s, "c:\\windows\\system\\");
|
|
1122 mr=MODULE32_LookupHMODULE(module);
|
|
1123 if(mr==0)//oops
|
|
1124 {
|
|
1125 strcat(s, "aviplay.dll");
|
|
1126 return 1;
|
|
1127 }
|
|
1128 if(strrchr(mr->filename, '/')==NULL)
|
|
1129 strcat(s, mr->filename);
|
|
1130 else
|
|
1131 strcat(s, strrchr(mr->filename, '/')+1);
|
|
1132 return 1;
|
|
1133 }
|
|
1134
|
|
1135 int WINAPI expSetUnhandledExceptionFilter(void* filter)
|
|
1136 {
|
|
1137 dbgprintf("SetUnhandledExcFilter\n");
|
|
1138 return 1;//unsupported and probably won't ever be supported
|
|
1139 }
|
|
1140 extern char* def_path;
|
|
1141
|
|
1142 int WINAPI expLoadLibraryA(char* name)
|
|
1143 {
|
|
1144 char qq[256];
|
|
1145 dbgprintf("LoadLibraryA\n");
|
|
1146 printf("They want library %s\n", name);
|
|
1147 strcpy(qq, def_path);
|
|
1148 strcat(qq, "/");
|
|
1149 strcat(qq, name);
|
|
1150 return LoadLibraryA(qq);
|
|
1151 }
|
|
1152 int WINAPI expFreeLibrary(int module)
|
|
1153 {
|
|
1154 dbgprintf("FreeLibrary\n");
|
|
1155 return FreeLibrary(module);
|
|
1156 }
|
|
1157 void* WINAPI expGetProcAddress(HMODULE mod, char* name)
|
|
1158 {
|
|
1159 dbgprintf("GetProcAddress\n");
|
|
1160 return GetProcAddress(mod, name);
|
|
1161 }
|
|
1162
|
|
1163 long WINAPI expCreateFileMappingA(int hFile, void* lpAttr,
|
|
1164 long flProtect, long dwMaxHigh, long dwMaxLow, const char* name)
|
|
1165 {
|
|
1166 dbgprintf("CreateFileMappingA\n");
|
|
1167 return CreateFileMappingA(hFile, lpAttr, flProtect, dwMaxHigh, dwMaxLow, name);
|
|
1168 }
|
|
1169
|
|
1170 long WINAPI expOpenFileMappingA(long hFile, long hz, const char* name)
|
|
1171 {
|
|
1172 dbgprintf("OpenFileMappingA\n");
|
|
1173 return OpenFileMappingA(hFile, hz, name);
|
|
1174 }
|
|
1175
|
|
1176 void* WINAPI expMapViewOfFile(HANDLE file, DWORD mode, DWORD offHigh, DWORD offLow, DWORD size)
|
|
1177 {
|
|
1178 dbgprintf("MapViewOfFile(%d, %x, %x, %x, %x)\n",
|
|
1179 file,mode,offHigh,offLow,size);
|
|
1180 return (char*)file+offLow;
|
|
1181 }
|
|
1182
|
|
1183 void* WINAPI expUnmapViewOfFile(void* view)
|
|
1184 {
|
|
1185 dbgprintf("UnmapViewOfFile()\n");
|
|
1186 return 0;
|
|
1187 }
|
|
1188
|
|
1189 void* WINAPI expSleep(int time)
|
|
1190 {
|
|
1191 dbgprintf("Sleep(%d)\n", time);
|
|
1192 usleep(time);
|
|
1193 return 0;
|
|
1194 }
|
|
1195 // why does IV32 codec want to call this? I don't know ...
|
|
1196 void* WINAPI expCreateCompatibleDC(int hdc)
|
|
1197 {
|
|
1198 dbgprintf("CreateCompatibleDC(%d)\n", hdc);
|
|
1199 return (void*)129;
|
|
1200 }
|
|
1201
|
|
1202 int WINAPI expGetDeviceCaps(int hdc, int unk)
|
|
1203 {
|
|
1204 dbgprintf("GetDeviceCaps(%d, %d)\n", hdc, unk);
|
|
1205 return 0;
|
|
1206 }
|
|
1207
|
|
1208 WIN_BOOL WINAPI expDeleteDC(int hdc)
|
|
1209 {
|
|
1210 dbgprintf("DeleteDC(%d)\n", hdc);
|
|
1211 return 0;
|
|
1212 }
|
|
1213
|
|
1214 int expwsprintfA(char* string, char* format, ...)
|
|
1215 {
|
|
1216 va_list va;
|
|
1217 va_start(va, format);
|
|
1218 dbgprintf("wsprintfA\n");
|
|
1219 return vsprintf(string, format, va);
|
|
1220 }
|
|
1221
|
|
1222 int WINAPI expGetPrivateProfileIntA(const char* appname, const char* keyname, int default_value, const char* filename)
|
|
1223 {
|
|
1224 int size=255;
|
|
1225 char buffer[256];
|
|
1226 char* fullname;
|
|
1227 int result;
|
|
1228
|
|
1229 buffer[255]=0;
|
|
1230 dbgprintf("GetPrivateProfileIntA(%s, %s, %s)\n", appname, keyname, filename );
|
|
1231 if(!(appname && keyname && filename) ) return default_value;
|
|
1232 fullname=(char*)malloc(50+strlen(appname)+strlen(keyname)+strlen(filename));
|
|
1233 strcpy(fullname, "Software\\IniFileMapping\\");
|
|
1234 strcat(fullname, appname);
|
|
1235 strcat(fullname, "\\");
|
|
1236 strcat(fullname, keyname);
|
|
1237 strcat(fullname, "\\");
|
|
1238 strcat(fullname, filename);
|
|
1239 result=RegQueryValueExA(HKEY_LOCAL_MACHINE, fullname, NULL, NULL, (int*)buffer, &size);
|
|
1240 if((size>=0)&&(size<256))
|
|
1241 buffer[size]=0;
|
|
1242 // printf("GetPrivateProfileIntA(%s, %s, %s) -> %s\n", appname, keyname, filename, buffer);
|
|
1243 free(fullname);
|
|
1244 if(result)
|
|
1245 return default_value;
|
|
1246 else
|
|
1247 return atoi(buffer);
|
|
1248 }
|
|
1249 int WINAPI expGetPrivateProfileStringA(const char* appname, const char* keyname,
|
|
1250 const char* def_val, char* dest, unsigned int len, const char* filename)
|
|
1251 {
|
|
1252 int result;
|
|
1253 int size;
|
|
1254 char* fullname;
|
|
1255 dbgprintf("GetPrivateProfileStringA(%s, %s, %s, %X, %X, %s)\n", appname, keyname, def_val, dest, len, filename );
|
|
1256 if(!(appname && keyname && filename) ) return 0;
|
|
1257 fullname=(char*)malloc(50+strlen(appname)+strlen(keyname)+strlen(filename));
|
|
1258 strcpy(fullname, "Software\\IniFileMapping\\");
|
|
1259 strcat(fullname, appname);
|
|
1260 strcat(fullname, "\\");
|
|
1261 strcat(fullname, keyname);
|
|
1262 strcat(fullname, "\\");
|
|
1263 strcat(fullname, filename);
|
|
1264 size=len;
|
|
1265 result=RegQueryValueExA(HKEY_LOCAL_MACHINE, fullname, NULL, NULL, (int*)dest, &size);
|
|
1266 // printf("GetPrivateProfileStringA(%s, %s, %s, %X, %X, %s)\n", appname, keyname, def_val, dest, len, filename );
|
|
1267 free(fullname);
|
|
1268 if(!result)
|
|
1269 return size;
|
|
1270 strncpy(dest, def_val, size);
|
|
1271 return size;
|
|
1272 }
|
|
1273 int WINAPI expWritePrivateProfileStringA(const char* appname, const char* keyname,
|
|
1274 const char* string, const char* filename)
|
|
1275 {
|
|
1276 int size=256;
|
|
1277 char* fullname;
|
|
1278 dbgprintf("WritePrivateProfileStringA(%s, %s, %s, %s)\n", appname, keyname, string, filename );
|
|
1279 if(!(appname && keyname && filename) ) return -1;
|
|
1280 fullname=(char*)malloc(50+strlen(appname)+strlen(keyname)+strlen(filename));
|
|
1281 strcpy(fullname, "Software\\IniFileMapping\\");
|
|
1282 strcat(fullname, appname);
|
|
1283 strcat(fullname, "\\");
|
|
1284 strcat(fullname, keyname);
|
|
1285 strcat(fullname, "\\");
|
|
1286 strcat(fullname, filename);
|
|
1287 RegSetValueExA(HKEY_LOCAL_MACHINE, fullname, 0, REG_SZ, (int*)string, strlen(string));
|
|
1288 // printf("RegSetValueExA(%s,%d)\n", string, strlen(string));
|
|
1289 // printf("WritePrivateProfileStringA(%s, %s, %s, %s)\n", appname, keyname, string, filename );
|
|
1290 free(fullname);
|
|
1291 return 0;
|
|
1292 }
|
|
1293
|
|
1294 unsigned int _GetPrivateProfileIntA(const char* appname, const char* keyname, INT default_value, const char* filename)
|
|
1295 {
|
|
1296 return expGetPrivateProfileIntA(appname, keyname, default_value, filename);
|
|
1297 }
|
|
1298 int _GetPrivateProfileStringA(const char* appname, const char* keyname,
|
|
1299 const char* def_val, char* dest, unsigned int len, const char* filename)
|
|
1300 {
|
|
1301 return expGetPrivateProfileStringA(appname, keyname, def_val, dest, len, filename);
|
|
1302 }
|
|
1303 int _WritePrivateProfileStringA(const char* appname, const char* keyname,
|
|
1304 const char* string, const char* filename)
|
|
1305 {
|
|
1306 return expWritePrivateProfileStringA(appname, keyname, string, filename);
|
|
1307 }
|
|
1308
|
|
1309
|
|
1310 int WINAPI expDefDriverProc(int _private, int id, int msg, int arg1, int arg2)
|
|
1311 {
|
|
1312 printf("Called DefDriverProc(%X)\n", msg);
|
|
1313 return 0;
|
|
1314 }
|
|
1315
|
|
1316 int WINAPI expSizeofResource(int v1, int v2)
|
|
1317 {
|
|
1318 dbgprintf("SizeofResource()\n");
|
|
1319 return SizeofResource(v1, v2);
|
|
1320 }
|
|
1321
|
|
1322 int WINAPI expGetLastError()
|
|
1323 {
|
|
1324 dbgprintf("GetLastError()\n");
|
|
1325 return GetLastError();
|
|
1326 }
|
|
1327
|
|
1328 void WINAPI expSetLastError(int error)
|
|
1329 {
|
|
1330 dbgprintf("SetLastError()\n");
|
|
1331 SetLastError(error);
|
|
1332 }
|
|
1333
|
|
1334 char* expstrrchr(char* string, int value)
|
|
1335 {
|
|
1336 return strrchr(string, value);
|
|
1337 }
|
|
1338
|
|
1339 char* expstrchr(char* string, int value)
|
|
1340 {
|
|
1341 return strchr(string, value);
|
|
1342 }
|
|
1343
|
|
1344 int WINAPI expGetFileVersionInfoSizeA(const char* name, int* lpHandle)
|
|
1345 {
|
|
1346 printf("GetFileVersionInfoSizeA(%s,0x%X)\n", name, lpHandle);
|
|
1347 return 0;
|
|
1348 }
|
|
1349
|
|
1350 int WINAPI expIsBadStringPtrW(const short* string, int nchars)
|
|
1351 {
|
|
1352 if(string==0)return 1;
|
|
1353 return 0;
|
|
1354 }
|
|
1355 extern long WINAPI InterlockedExchangeAdd( long* dest, long incr )
|
|
1356 {
|
|
1357 long ret;
|
|
1358 __asm__ __volatile__( "lock; xaddl %0,(%1)"
|
|
1359 : "=r" (ret) : "r" (dest), "0" (incr) : "memory" );
|
|
1360 return ret;
|
|
1361 }
|
|
1362
|
|
1363 extern long WINAPI expInterlockedIncrement( long* dest )
|
|
1364 {
|
|
1365 return InterlockedExchangeAdd( dest, 1 ) + 1;
|
|
1366 }
|
|
1367 extern long WINAPI expInterlockedDecrement( long* dest )
|
|
1368 {
|
|
1369 return InterlockedExchangeAdd( dest, -1 ) - 1;
|
|
1370 }
|
|
1371
|
|
1372 extern void WINAPI expOutputDebugStringA( const char* string )
|
|
1373 {
|
|
1374 fprintf(stderr, "DEBUG: %s\n", string);
|
|
1375 }
|
|
1376
|
|
1377 int WINAPI expGetDC(int hwnd)
|
|
1378 {
|
|
1379 return 0;
|
|
1380 }
|
|
1381
|
|
1382 int WINAPI expGetDesktopWindow()
|
|
1383 {
|
|
1384 return 0;
|
|
1385 }
|
|
1386
|
|
1387 int WINAPI expReleaseDC(int hwnd, int hdc)
|
|
1388 {
|
|
1389 return 0;
|
|
1390 }
|
|
1391
|
|
1392 int WINAPI expGetSystemPaletteEntries(int hdc, int iStartIndex, int nEntries, void* lppe)
|
|
1393 {
|
|
1394 return 0;
|
|
1395 }
|
|
1396 /*
|
|
1397 typedef struct _TIME_ZONE_INFORMATION {
|
|
1398 long Bias;
|
|
1399 char StandardName[32];
|
|
1400 SYSTEMTIME StandardDate;
|
|
1401 long StandardBias;
|
|
1402 char DaylightName[32];
|
|
1403 SYSTEMTIME DaylightDate;
|
|
1404 long DaylightBias;
|
|
1405 } TIME_ZONE_INFORMATION, *LPTIME_ZONE_INFORMATION;
|
|
1406 */
|
|
1407
|
|
1408 int WINAPI expGetTimeZoneInformation(LPTIME_ZONE_INFORMATION lpTimeZoneInformation)
|
|
1409 {
|
|
1410 memset(lpTimeZoneInformation, 0, sizeof(TIME_ZONE_INFORMATION));
|
|
1411 return 0;
|
|
1412 }
|
|
1413
|
|
1414 void WINAPI expGetLocalTime(SYSTEMTIME* systime)
|
|
1415 {
|
|
1416 time_t local_time;
|
|
1417 struct tm *local_tm;
|
|
1418 struct timeval tv;
|
|
1419
|
|
1420 gettimeofday(&tv, NULL);
|
|
1421 local_time=tv.tv_sec;
|
|
1422 local_tm=localtime(&local_time);
|
|
1423
|
|
1424 systime->wYear = local_tm->tm_year + 1900;
|
|
1425 systime->wMonth = local_tm->tm_mon + 1;
|
|
1426 systime->wDayOfWeek = local_tm->tm_wday;
|
|
1427 systime->wDay = local_tm->tm_mday;
|
|
1428 systime->wHour = local_tm->tm_hour;
|
|
1429 systime->wMinute = local_tm->tm_min;
|
|
1430 systime->wSecond = local_tm->tm_sec;
|
|
1431 systime->wMilliseconds = (tv.tv_usec / 1000) % 1000;
|
|
1432 }
|
|
1433
|
|
1434 int WINAPI expGetSystemTime(SYSTEMTIME* systime)
|
|
1435 {
|
|
1436 time_t local_time;
|
|
1437 struct tm *local_tm;
|
|
1438 struct timeval tv;
|
|
1439
|
|
1440 gettimeofday(&tv, NULL);
|
|
1441 local_time=tv.tv_sec;
|
|
1442 local_tm=gmtime(&local_time);
|
|
1443
|
|
1444 systime->wYear = local_tm->tm_year + 1900;
|
|
1445 systime->wMonth = local_tm->tm_mon + 1;
|
|
1446 systime->wDayOfWeek = local_tm->tm_wday;
|
|
1447 systime->wDay = local_tm->tm_mday;
|
|
1448 systime->wHour = local_tm->tm_hour;
|
|
1449 systime->wMinute = local_tm->tm_min;
|
|
1450 systime->wSecond = local_tm->tm_sec;
|
|
1451 systime->wMilliseconds = (tv.tv_usec / 1000) % 1000;
|
|
1452
|
|
1453 }
|
|
1454
|
|
1455 int WINAPI expGetEnvironmentVariableA(const char* name, char* field, int size)
|
|
1456 {
|
|
1457 dbgprintf("GetEnvironmentVariableA\n");
|
|
1458 printf("%s %x %x\n", name, field, size);
|
|
1459 if(field)field[0]=0;
|
|
1460 return 0;
|
|
1461 }
|
|
1462
|
|
1463
|
|
1464 //HDRVR WINAPI expOpenDriverA(LPCSTR szDriverName, LPCSTR szSectionName, LPARAM lParam2);
|
|
1465 //HDRVR WINAPI expOpenDriverW(LPCWSTR szDriverName, LPCWSTR szSectionName, LPARAM lParam2);
|
|
1466 HDRVR WINAPI expOpenDriver(LPCSTR szDriverName, LPCSTR szSectionName, LPARAM lParam2){
|
|
1467 printf("winmm32::OpenDriver() called\n");
|
|
1468 return NULL;
|
|
1469 }
|
|
1470
|
|
1471
|
|
1472 struct exports
|
|
1473 {
|
|
1474 char name[64];
|
|
1475 int id;
|
|
1476 void* func;
|
|
1477 };
|
|
1478 struct libs
|
|
1479 {
|
|
1480 char name[64];
|
|
1481 int length;
|
|
1482 struct exports* exps;
|
|
1483 };
|
|
1484
|
|
1485 #define FF(X,Y) \
|
|
1486 {#X, Y, (void*)exp##X},
|
|
1487
|
|
1488 struct exports exp_kernel32[]={
|
|
1489 FF(IsBadWritePtr, 357)
|
|
1490 FF(IsBadReadPtr, 354)
|
|
1491 FF(IsBadStringPtrW, -1)
|
|
1492 FF(DisableThreadLibraryCalls, -1)
|
|
1493 FF(CreateThread, -1)
|
|
1494 FF(CreateEventA, -1)
|
|
1495 FF(SetEvent, -1)
|
|
1496 FF(ResetEvent, -1)
|
|
1497 FF(WaitForSingleObject, -1)
|
|
1498 FF(GetSystemInfo, -1)
|
|
1499 FF(GetVersion, 332)
|
|
1500 FF(HeapCreate, 461)
|
|
1501 FF(HeapAlloc, -1)
|
|
1502 FF(HeapDestroy, -1)
|
|
1503 FF(HeapFree, -1)
|
|
1504 FF(HeapSize, -1)
|
|
1505 FF(GetProcessHeap, -1)
|
|
1506 FF(VirtualAlloc, -1)
|
|
1507 FF(VirtualFree, -1)
|
|
1508 FF(InitializeCriticalSection, -1)
|
|
1509 FF(EnterCriticalSection, -1)
|
|
1510 FF(LeaveCriticalSection, -1)
|
|
1511 FF(DeleteCriticalSection, -1)
|
|
1512 FF(TlsAlloc, -1)
|
|
1513 FF(TlsFree, -1)
|
|
1514 FF(TlsGetValue, -1)
|
|
1515 FF(TlsSetValue, -1)
|
|
1516 FF(GetCurrentThreadId, -1)
|
|
1517 FF(LocalAlloc, -1)
|
|
1518 FF(LocalLock, -1)
|
|
1519 FF(GlobalAlloc, -1)
|
|
1520 FF(GlobalLock, -1)
|
|
1521 FF(MultiByteToWideChar, 427)
|
|
1522 FF(WideCharToMultiByte, -1)
|
|
1523 FF(GetVersionExA, -1)
|
|
1524 FF(CreateSemaphoreA, -1)
|
|
1525 FF(QueryPerformanceCounter, -1)
|
|
1526 FF(QueryPerformanceFrequency, -1)
|
|
1527 FF(LocalHandle, -1)
|
|
1528 FF(LocalUnlock, -1)
|
|
1529 FF(LocalFree, -1)
|
|
1530 FF(GlobalHandle, -1)
|
|
1531 FF(GlobalUnlock, -1)
|
|
1532 FF(GlobalFree, -1)
|
|
1533 FF(LoadResource, -1)
|
|
1534 FF(ReleaseSemaphore, -1)
|
|
1535 FF(FindResourceA, -1)
|
|
1536 FF(LockResource, -1)
|
|
1537 FF(FreeResource, -1)
|
|
1538 FF(SizeofResource, -1)
|
|
1539 FF(CloseHandle, -1)
|
|
1540 FF(GetCommandLineA, -1)
|
|
1541 FF(GetEnvironmentStringsW, -1)
|
|
1542 FF(FreeEnvironmentStringsW, -1)
|
|
1543 FF(GetEnvironmentStrings, -1)
|
|
1544 FF(GetStartupInfoA, -1)
|
|
1545 FF(GetStdHandle, -1)
|
|
1546 FF(GetFileType, -1)
|
|
1547 FF(SetHandleCount, -1)
|
|
1548 FF(GetACP, -1)
|
|
1549 FF(GetModuleFileNameA, -1)
|
|
1550 FF(SetUnhandledExceptionFilter, -1)
|
|
1551 FF(LoadLibraryA, -1)
|
|
1552 FF(GetProcAddress, -1)
|
|
1553 FF(FreeLibrary, -1)
|
|
1554 FF(CreateFileMappingA, -1)
|
|
1555 FF(OpenFileMappingA, -1)
|
|
1556 FF(MapViewOfFile, -1)
|
|
1557 FF(UnmapViewOfFile, -1)
|
|
1558 FF(Sleep, -1)
|
|
1559 FF(GetModuleHandleA, -1)
|
|
1560 FF(GetPrivateProfileIntA, -1)
|
|
1561 FF(GetPrivateProfileStringA, -1)
|
|
1562 FF(WritePrivateProfileStringA, -1)
|
|
1563 FF(GetLastError, -1)
|
|
1564 FF(SetLastError, -1)
|
|
1565 FF(InterlockedIncrement, -1)
|
|
1566 FF(InterlockedDecrement, -1)
|
|
1567 FF(GetTimeZoneInformation, -1)
|
|
1568 FF(OutputDebugStringA, -1)
|
|
1569 FF(GetLocalTime, -1)
|
|
1570 FF(GetSystemTime, -1)
|
|
1571 FF(GetEnvironmentVariableA, -1)
|
|
1572 };
|
|
1573
|
|
1574 struct exports exp_msvcrt[]={
|
|
1575 FF(malloc, -1)
|
|
1576 FF(_initterm, -1)
|
|
1577 FF(free, -1)
|
|
1578 {"??3@YAXPAX@Z", -1, expdelete},
|
|
1579 {"??2@YAPAXI@Z", -1, expnew},
|
|
1580 FF(strrchr, -1)
|
|
1581 FF(strchr, -1)
|
|
1582 };
|
|
1583 struct exports exp_winmm[]={
|
|
1584 FF(GetDriverModuleHandle, -1)
|
|
1585 FF(timeGetTime, -1)
|
|
1586 FF(DefDriverProc, -1)
|
|
1587 FF(OpenDriver, -1)
|
|
1588 };
|
|
1589 struct exports exp_user32[]={
|
|
1590 FF(LoadStringA, -1)
|
|
1591 FF(wsprintfA, -1)
|
|
1592 FF(GetDC, -1)
|
|
1593 FF(GetDesktopWindow, -1)
|
|
1594 FF(ReleaseDC, -1)
|
|
1595 };
|
|
1596 struct exports exp_advapi32[]={
|
|
1597 FF(RegOpenKeyA, -1)
|
|
1598 FF(RegOpenKeyExA, -1)
|
|
1599 FF(RegCreateKeyExA, -1)
|
|
1600 FF(RegQueryValueExA, -1)
|
|
1601 FF(RegSetValueExA, -1)
|
|
1602 FF(RegCloseKey, -1)
|
|
1603 };
|
|
1604 struct exports exp_gdi32[]={
|
|
1605 FF(CreateCompatibleDC, -1)
|
|
1606 FF(GetDeviceCaps, -1)
|
|
1607 FF(DeleteDC, -1)
|
|
1608 FF(GetSystemPaletteEntries, -1)
|
|
1609 };
|
|
1610 struct exports exp_version[]={
|
|
1611 FF(GetFileVersionInfoSizeA, -1)
|
|
1612 };
|
|
1613 #define LL(X) \
|
|
1614 {#X".dll", sizeof(exp_##X)/sizeof(struct exports), exp_##X},
|
|
1615
|
|
1616 struct libs libraries[]={
|
|
1617 LL(kernel32)
|
|
1618 LL(msvcrt)
|
|
1619 LL(winmm)
|
|
1620 LL(user32)
|
|
1621 LL(advapi32)
|
|
1622 LL(gdi32)
|
|
1623 LL(version)
|
|
1624 };
|
|
1625
|
|
1626 void* LookupExternal(const char* library, int ordinal)
|
|
1627 {
|
|
1628 char* answ;
|
|
1629 int i,j;
|
|
1630 if(library==0)
|
|
1631 {
|
|
1632 printf("ERROR: library=0\n");
|
|
1633 return (void*)ext_unknown;
|
|
1634 }
|
|
1635 printf("External func %s:%d\n", library, ordinal);
|
|
1636 // printf("%x %x\n", &unk_exp1, &unk_exp2);
|
|
1637
|
|
1638 for(i=0; i<sizeof(libraries)/sizeof(struct libs); i++)
|
|
1639 {
|
|
1640 if(strcasecmp(library, libraries[i].name))
|
|
1641 continue;
|
|
1642 for(j=0; j<libraries[i].length; j++)
|
|
1643 {
|
|
1644 if(ordinal!=libraries[i].exps[j].id)
|
|
1645 continue;
|
|
1646 printf("Hit: 0x%08X\n", libraries[i].exps[j].func);
|
|
1647 return libraries[i].exps[j].func;
|
|
1648 }
|
|
1649 }
|
|
1650 if(pos>150)return 0;
|
|
1651 answ=(char*)extcode+pos*0x64;
|
|
1652 memcpy(answ, &unk_exp1, 0x64);
|
|
1653 *(int*)(answ+9)=pos;
|
|
1654 *(int*)(answ+47)-=((int)answ-(int)&unk_exp1);
|
|
1655 sprintf(export_names[pos], "%s:%d", library, ordinal);
|
|
1656 pos++;
|
|
1657 return (void*)answ;
|
|
1658 }
|
|
1659
|
|
1660 void* LookupExternalByName(const char* library, const char* name)
|
|
1661 {
|
|
1662 char* answ;
|
|
1663 int i,j;
|
|
1664 // return (void*)ext_unknown;
|
|
1665 if(library==0)
|
|
1666 {
|
|
1667 printf("ERROR: library=0\n");
|
|
1668 return (void*)ext_unknown;
|
|
1669 }
|
|
1670 if(name==0)
|
|
1671 {
|
|
1672 printf("ERROR: name=0\n");
|
|
1673 return (void*)ext_unknown;
|
|
1674 }
|
|
1675 // printf("External func %s:%s\n", library, name);
|
|
1676 for(i=0; i<sizeof(libraries)/sizeof(struct libs); i++)
|
|
1677 {
|
|
1678 if(strcasecmp(library, libraries[i].name))
|
|
1679 continue;
|
|
1680 for(j=0; j<libraries[i].length; j++)
|
|
1681 {
|
|
1682 if(strcmp(name, libraries[i].exps[j].name))
|
|
1683 continue;
|
|
1684 // printf("Hit: 0x%08X\n", libraries[i].exps[j].func);
|
|
1685 return libraries[i].exps[j].func;
|
|
1686 }
|
|
1687 }// printf("%x %x\n", &unk_exp1, &unk_exp2);
|
|
1688 //printf("Missing (%d) External func %s:%s\n", pos, library, name);
|
|
1689 if(pos>150){
|
|
1690 // printf("Warning! Too many missing externals!\n");
|
|
1691 return 0;
|
|
1692 }
|
|
1693 strcpy(export_names[pos], name);
|
|
1694 answ=(char*)extcode+pos*0x64;
|
|
1695 memcpy(answ, &unk_exp1, 0x64);
|
|
1696 *(int*)(answ+9)=pos;
|
|
1697 *(int*)(answ+47)-=((int)answ-(int)&unk_exp1);
|
|
1698 pos++;
|
|
1699 return (void*)answ;
|
|
1700 // memcpy(extcode, &unk_exp1, 0x64);
|
|
1701 // *(int*)(extcode+52)-=((int)extcode-(int)&unk_exp1);
|
|
1702 // return (void*)extcode;
|
|
1703 // printf("Unknown func %s:%s\n", library, name);
|
|
1704 // return (void*)ext_unknown;
|
|
1705 }
|
|
1706
|