Mercurial > mplayer.hg
annotate loader/win32.c @ 330:3c7ce767bb32
-lXdpms autodetection
author | arpi_esp |
---|---|
date | Tue, 10 Apr 2001 21:25:09 +0000 |
parents | c017b21a1990 |
children | 1f7c824033fb |
rev | line source |
---|---|
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. | |
128 | 8 |
9 Basic principle of implementation: it's not good | |
10 for DLL to know too much about its environment. | |
1 | 11 |
12 ************************************************************/ | |
13 | |
14 #include <config.h> | |
15 | |
16 #include "win32.h" | |
17 #include <stdio.h> | |
18 #include <pthread.h> | |
128 | 19 #include <errno.h> |
1 | 20 #ifdef HAVE_MALLOC_H |
21 #include <malloc.h> | |
22 #else | |
23 #include <stdlib.h> | |
24 #endif | |
25 #include <time.h> | |
128 | 26 #include <unistd.h> |
27 #include <fcntl.h> | |
1 | 28 #include <sys/types.h> |
29 #include <sys/time.h> | |
30 #include <sys/timeb.h> | |
31 | |
32 #include <wine/winbase.h> | |
33 #include <wine/winreg.h> | |
34 #include <wine/winnt.h> | |
35 #include <wine/winerror.h> | |
36 #include <wine/debugtools.h> | |
37 #include <wine/module.h> | |
38 | |
39 #include <registry.h> | |
40 #include <loader.h> | |
128 | 41 #include <com.h> |
42 | |
43 char* def_path=WIN32_PATH; | |
44 | |
45 static void do_cpuid(unsigned int *regs) | |
46 { | |
47 unsigned int ax; | |
48 ax=1; | |
49 __asm__ __volatile__( | |
50 "pushl %%ebx; pushl %%ecx; pushl %%edx; " | |
51 ".byte 0x0f, 0xa2;" | |
52 "movl %%eax, (%2);" | |
53 "movl %%ebx, 4(%2);" | |
54 "movl %%ecx, 8(%2);" | |
55 "movl %%edx, 12(%2);" | |
56 "popl %%edx; popl %%ecx; popl %%ebx; " | |
57 : "=a" (ax) | |
58 : "0" (ax), "S" (®s)); | |
59 } | |
60 static unsigned int c_localcount_tsc() | |
1 | 61 { |
62 int a; | |
63 __asm__ __volatile__("rdtsc\n\t" | |
64 :"=a"(a) | |
65 : | |
66 :"edx"); | |
67 return a; | |
68 } | |
128 | 69 static void c_longcount_tsc(long long* z) |
1 | 70 { |
71 __asm__ __volatile__( | |
72 "pushl %%ebx\n\t" | |
73 "movl %%eax, %%ebx\n\t" | |
74 "rdtsc\n\t" | |
75 "movl %%eax, 0(%%ebx)\n\t" | |
76 "movl %%edx, 4(%%ebx)\n\t" | |
77 "popl %%ebx\n\t" | |
78 ::"a"(z)); | |
79 } | |
80 #include <sys/time.h> | |
81 #include <unistd.h> | |
128 | 82 static unsigned int c_localcount_notsc() |
1 | 83 { |
84 struct timeval tv; | |
85 unsigned limit=~0; | |
86 limit/=1000000; | |
87 gettimeofday(&tv, 0); | |
88 return limit*tv.tv_usec; | |
89 } | |
128 | 90 static void c_longcount_notsc(long long* z) |
1 | 91 { |
92 struct timeval tv; | |
93 unsigned long long result; | |
94 unsigned limit=~0; | |
95 if(!z)return; | |
96 limit/=1000000; | |
97 gettimeofday(&tv, 0); | |
98 result=tv.tv_sec; | |
99 result<<=32; | |
100 result+=limit*tv.tv_usec; | |
101 *z=result; | |
102 } | |
128 | 103 static unsigned int localcount_stub(); |
104 static void longcount_stub(long long*); | |
105 static unsigned int (*localcount)()=localcount_stub; | |
106 static void (*longcount)(long long*)=longcount_stub; | |
1 | 107 |
128 | 108 static unsigned int localcount_stub() |
109 { | |
110 unsigned int regs[4]; | |
111 do_cpuid(regs); | |
112 if ((regs[3] & 0x00000010) == 0) | |
113 { | |
114 localcount=c_localcount_tsc; | |
115 longcount=c_longcount_tsc; | |
116 } | |
117 else | |
118 { | |
119 localcount=c_localcount_notsc; | |
120 longcount=c_longcount_notsc; | |
121 } | |
122 return localcount(); | |
123 } | |
124 static void longcount_stub(long long* z) | |
1 | 125 { |
128 | 126 unsigned int regs[4]; |
127 do_cpuid(regs); | |
128 if ((regs[3] & 0x00000010) == 0) | |
129 { | |
130 localcount=c_localcount_tsc; | |
131 longcount=c_longcount_tsc; | |
132 } | |
133 else | |
134 { | |
135 localcount=c_localcount_notsc; | |
136 longcount=c_longcount_notsc; | |
137 } | |
138 longcount(z); | |
139 } | |
140 | |
235 | 141 int LOADER_DEBUG=1; |
128 | 142 inline void dbgprintf(char* fmt, ...) |
143 { | |
235 | 144 #ifdef DETAILED_OUT |
128 | 145 if(LOADER_DEBUG) |
146 { | |
147 FILE* f; | |
148 va_list va; | |
149 va_start(va, fmt); | |
150 f=fopen("./log", "a"); | |
151 vprintf(fmt, va); | |
152 if(f) | |
153 { | |
154 vfprintf(f, fmt, va); | |
155 fsync(fileno(f)); | |
156 fclose(f); | |
157 } | |
158 va_end(va); | |
159 } | |
235 | 160 #endif |
1 | 161 } |
162 char export_names[500][30]={ | |
163 "name1", | |
164 //"name2", | |
165 //"name3" | |
166 }; | |
167 //#define min(x,y) ((x)<(y)?(x):(y)) | |
168 | |
169 static unsigned char* heap=NULL; | |
170 static int heap_counter=0; | |
171 void test_heap() | |
172 { | |
173 int offset=0; | |
174 if(heap==0) | |
175 return; | |
176 while(offset<heap_counter) | |
177 { | |
178 if(*(int*)(heap+offset)!=0x433476) | |
179 { | |
180 printf("Heap corruption at address %d\n", offset); | |
181 return; | |
182 } | |
183 offset+=8+*(int*)(heap+offset+4); | |
184 } | |
185 for(;offset<min(offset+1000, 20000000); offset++) | |
186 if(heap[offset]!=0xCC) | |
187 { | |
188 printf("Free heap corruption at address %d\n", offset); | |
189 } | |
190 } | |
191 #undef MEMORY_DEBUG | |
192 | |
193 #ifdef MEMORY_DEBUG | |
194 | |
195 void* my_mreq(int size, int to_zero) | |
196 { | |
197 static int test=0; | |
198 test++; | |
199 if(test%10==0)printf("Memory: %d bytes allocated\n", heap_counter); | |
200 // test_heap(); | |
201 if(heap==NULL) | |
202 { | |
203 heap=malloc(20000000); | |
204 memset(heap, 0xCC,20000000); | |
205 } | |
206 if(heap==0) | |
207 { | |
208 printf("No enough memory\n"); | |
209 return 0; | |
210 } | |
211 if(heap_counter+size>20000000) | |
212 { | |
213 printf("No enough memory\n"); | |
214 return 0; | |
215 } | |
216 *(int*)(heap+heap_counter)=0x433476; | |
217 heap_counter+=4; | |
218 *(int*)(heap+heap_counter)=size; | |
219 heap_counter+=4; | |
220 printf("Allocated %d bytes of memory: sys %d, user %d-%d\n", size, heap_counter-8, heap_counter, heap_counter+size); | |
221 if(to_zero) | |
222 memset(heap+heap_counter, 0, size); | |
223 heap_counter+=size; | |
224 return heap+heap_counter-size; | |
225 } | |
226 int my_release(char* memory) | |
227 { | |
228 // test_heap(); | |
229 if(memory==NULL) | |
230 { | |
231 printf("ERROR: free(0)\n"); | |
232 return 0; | |
233 } | |
234 if(*(int*)(memory-8)!=0x433476) | |
235 { | |
236 printf("MEMORY CORRUPTION !!!!!!!!!!!!!!!!!!!\n"); | |
237 return 0; | |
238 } | |
239 printf("Freed %d bytes of memory\n", *(int*)(memory-4)); | |
240 // memset(memory-8, *(int*)(memory-4), 0xCC); | |
241 return 0; | |
242 } | |
243 | |
244 #else | |
128 | 245 #define GARBAGE |
246 #ifdef GARBAGE | |
247 struct alc_list_t; | |
248 typedef struct alc_list_t { | |
249 int size; | |
250 int addr; | |
251 struct alc_list_t *prev; | |
252 struct alc_list_t *next; | |
253 }alc_list; | |
254 static alc_list *alclist=NULL; | |
255 static alccnt=0; | |
256 #endif | |
257 | |
1 | 258 void* my_mreq(int size, int to_zero) |
259 { | |
260 void* answer; | |
261 if(to_zero) | |
262 answer=calloc(size+4, 1); | |
263 else | |
264 answer=malloc(size+4); | |
265 *(int*)answer=size; | |
128 | 266 #ifdef GARBAGE |
267 if (alclist==NULL) { | |
268 alclist=malloc(sizeof(alc_list)); | |
269 alclist->prev=alclist->next=NULL; | |
270 } | |
271 else { | |
272 alclist->next=malloc(sizeof(alc_list)); | |
273 alclist->next->prev=alclist; | |
274 alclist->next->next=NULL; | |
275 alclist=alclist->next; | |
276 } | |
277 alclist->size=size; | |
278 alclist->addr=answer; | |
279 alccnt++; | |
280 #endif | |
281 return (int*)((int)answer+sizeof(int)); | |
1 | 282 } |
283 int my_release(char* memory) | |
284 { | |
128 | 285 #ifdef GARBAGE |
286 alc_list* pp; | |
1 | 287 if(memory==0)return 0; |
128 | 288 if(alclist!=NULL) |
289 { | |
290 pp=alclist; | |
291 if ((pp->prev==NULL) && (pp->next == NULL)){ | |
292 free(pp); | |
293 alclist=NULL; | |
294 } | |
295 else { | |
296 for(;pp;pp=pp->prev) { | |
297 if (pp->addr == memory-4) { | |
298 if (pp->prev) | |
299 pp->prev->next=pp->next; | |
300 if (pp->next) | |
301 pp->next->prev=pp->prev; | |
302 if (pp == alclist) | |
303 alclist=pp->prev; | |
304 free(pp); | |
305 alccnt--; | |
306 break; | |
307 } | |
308 } | |
309 if (pp == NULL) { | |
310 printf("Not Found %x %d\n",memory-4,alccnt); | |
311 return 0; | |
312 } | |
313 } | |
314 } | |
315 #endif | |
1 | 316 free(memory-4); |
317 return 0; | |
318 } | |
319 #endif | |
320 int my_size(char* memory) | |
321 { | |
322 return *(int*)(memory-4); | |
323 } | |
324 | |
325 extern int unk_exp1; | |
326 char extcode[20000];// place for 200 unresolved exports | |
327 int pos=0; | |
328 | |
329 int WINAPI ext_unknown() | |
330 { | |
331 printf("Unknown func called\n"); | |
332 return 0; | |
333 } | |
334 int WINAPI expIsBadWritePtr(void* ptr, unsigned int count) | |
335 { | |
128 | 336 int result; |
1 | 337 if(count==0) |
128 | 338 result=0; |
339 else | |
1 | 340 if(ptr==0) |
128 | 341 result=1; |
342 else | |
343 result=0; | |
344 dbgprintf("IsBadWritePtr(0x%x, 0x%x) => %d\n", ptr, count, result); | |
345 return result; | |
1 | 346 } |
347 int WINAPI expIsBadReadPtr(void* ptr, unsigned int count) | |
348 { | |
128 | 349 int result; |
1 | 350 if(count==0) |
128 | 351 result=0; |
352 else | |
1 | 353 if(ptr==0) |
128 | 354 result=1; |
355 else | |
356 result=0; | |
357 dbgprintf("IsBadReadPtr(0x%x, 0x%x) => %d\n", ptr, count, result); | |
358 return result; | |
1 | 359 } |
360 void* CDECL expmalloc(int size) | |
361 { | |
362 //printf("malloc"); | |
363 // return malloc(size); | |
364 void* result=my_mreq(size,0); | |
128 | 365 dbgprintf("malloc(0x%x) => 0x%x\n", size,result); |
1 | 366 if(result==0) |
367 printf("WARNING: malloc() failed\n"); | |
368 return result; | |
369 } | |
370 void CDECL expfree(void* mem) | |
371 { | |
372 // return free(mem); | |
128 | 373 dbgprintf("free(0x%x)\n", mem); |
1 | 374 my_release(mem); |
375 } | |
376 void* CDECL expnew(int size) | |
377 { | |
378 // printf("NEW:: Call from address %08x\n STACK DUMP:\n", *(-1+(int*)&size)); | |
379 // printf("%08x %08x %08x %08x\n", | |
380 // size, *(1+(int*)&size), | |
381 // *(2+(int*)&size),*(3+(int*)&size)); | |
128 | 382 void* result=my_mreq(size,0); |
383 dbgprintf("new(0x%x) => 0x%x\n", size, result); | |
1 | 384 if(result==0) |
128 | 385 printf("WARNING: new() failed\n"); |
1 | 386 return result; |
387 | |
388 } | |
389 int CDECL expdelete(void* memory) | |
390 { | |
128 | 391 dbgprintf("delete(0x%x)\n", memory); |
392 my_release(memory); | |
1 | 393 return 0; |
394 } | |
395 int WINAPI expDisableThreadLibraryCalls(int module) | |
396 { | |
128 | 397 dbgprintf("DisableThreadLibraryCalls(0x%x) => 0\n", module); |
1 | 398 return 0; |
399 } | |
400 int CDECL exp_initterm(int v1, int v2) | |
401 { | |
128 | 402 dbgprintf("_initterm(0x%x, 0x%x) => 0\n", v1, v2); |
1 | 403 return 0; |
404 } | |
405 | |
406 typedef struct { | |
407 unsigned int uDriverSignature; | |
408 void* hDriverModule; | |
409 void* DriverProc; | |
410 unsigned int dwDriverID; | |
411 } DRVR; | |
412 | |
413 void* WINAPI expGetDriverModuleHandle(DRVR* pdrv) | |
414 { | |
128 | 415 void* result; |
416 if (pdrv==NULL) result=NULL; | |
417 result=pdrv->hDriverModule; | |
418 dbgprintf("GetDriverModuleHandle(0x%x) => 0x%x\n", pdrv, result); | |
419 return result; | |
1 | 420 } |
421 | |
422 void* WINAPI expGetModuleHandleA(const char* name) | |
423 { | |
424 WINE_MODREF* wm; | |
128 | 425 void* result; |
426 if(!name) | |
427 result=0; | |
428 else | |
429 { | |
430 wm=MODULE_FindModule(name); | |
431 if(wm==0)result=0; | |
432 else | |
433 result=(void*)(wm->module); | |
434 } | |
435 if(!result) | |
436 { | |
437 if(strcasecmp(name, "kernel32")==0) | |
438 result=0x120; | |
439 } | |
440 dbgprintf("GetModuleHandleA('%s') => 0x%x\n", name, result); | |
441 return result; | |
1 | 442 } |
128 | 443 |
1 | 444 struct th_list_t; |
445 typedef struct th_list_t{ | |
446 int id; | |
447 void* thread; | |
448 struct th_list_t* next; | |
449 struct th_list_t* prev; | |
450 }th_list; | |
451 | |
452 static th_list* list=NULL; | |
453 | |
454 | |
455 | |
456 void* WINAPI expCreateThread(void* pSecAttr, long dwStackSize, void* lpStartAddress, | |
457 void* lpParameter, long dwFlags, long* dwThreadId) | |
458 { | |
459 pthread_t *pth; | |
460 // printf("CreateThread:"); | |
461 pth=my_mreq(sizeof(pthread_t), 0); | |
462 pthread_create(pth, NULL, (void*(*)(void*))lpStartAddress, lpParameter); | |
463 if(dwFlags) | |
128 | 464 printf( "WARNING: CreateThread flags not supported\n"); |
1 | 465 if(dwThreadId) |
466 *dwThreadId=(long)pth; | |
467 if(list==NULL) | |
468 { | |
469 list=my_mreq(sizeof(th_list), 1); | |
470 list->next=list->prev=NULL; | |
471 } | |
472 else | |
473 { | |
474 list->next=my_mreq(sizeof(th_list), 0); | |
475 list->next->prev=list; | |
476 list->next->next=NULL; | |
477 list=list->next; | |
478 } | |
479 list->thread=pth; | |
128 | 480 dbgprintf("CreateThread(0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x) => 0x%x\n", |
481 pSecAttr, dwStackSize, lpStartAddress, lpParameter, dwFlags, dwThreadId, pth); | |
1 | 482 return pth; |
483 } | |
484 | |
485 struct mutex_list_t; | |
486 | |
487 struct mutex_list_t | |
488 { | |
128 | 489 char type; |
1 | 490 pthread_mutex_t *pm; |
128 | 491 pthread_cond_t *pc; |
492 char state; | |
493 char reset; | |
1 | 494 char name[64]; |
128 | 495 int semaphore; |
1 | 496 struct mutex_list_t* next; |
497 struct mutex_list_t* prev; | |
498 }; | |
499 typedef struct mutex_list_t mutex_list; | |
500 static mutex_list* mlist=NULL; | |
501 void* WINAPI expCreateEventA(void* pSecAttr, char bManualReset, | |
502 char bInitialState, const char* name) | |
503 { | |
504 pthread_mutex_t *pm; | |
128 | 505 pthread_cond_t *pc; |
1 | 506 if(mlist!=NULL) |
507 { | |
508 mutex_list* pp=mlist; | |
509 if(name!=NULL) | |
510 do | |
511 { | |
128 | 512 if((strcmp(pp->name, name)==0) && (pp->type==0)) |
513 { | |
514 dbgprintf("CreateEventA(0x%x, 0x%x, 0x%x, 0x%x='%s') => 0x%x\n", | |
515 pSecAttr, bManualReset, bInitialState, name, name, pp->pm); | |
1 | 516 return pp->pm; |
128 | 517 } |
1 | 518 }while(pp=pp->prev); |
519 } | |
520 pm=my_mreq(sizeof(pthread_mutex_t), 0); | |
521 pthread_mutex_init(pm, NULL); | |
128 | 522 pc=my_mreq(sizeof(pthread_cond_t), 0); |
523 pthread_cond_init(pc, NULL); | |
1 | 524 if(mlist==NULL) |
525 { | |
526 mlist=my_mreq(sizeof(mutex_list), 00); | |
527 mlist->next=mlist->prev=NULL; | |
528 } | |
529 else | |
530 { | |
531 mlist->next=my_mreq(sizeof(mutex_list), 00); | |
128 | 532 mlist->next->prev=mlist; |
1 | 533 mlist->next->next=NULL; |
534 mlist=mlist->next; | |
535 } | |
128 | 536 mlist->type=0; /* Type Event */ |
1 | 537 mlist->pm=pm; |
128 | 538 mlist->pc=pc; |
539 mlist->state=bInitialState; | |
540 mlist->reset=bManualReset; | |
1 | 541 if(name!=NULL) |
542 strncpy(mlist->name, name, 64); | |
543 else | |
544 mlist->name[0]=0; | |
545 if(pm==NULL) | |
546 dbgprintf("ERROR::: CreateEventA failure\n"); | |
128 | 547 /* |
1 | 548 if(bInitialState) |
549 pthread_mutex_lock(pm); | |
128 | 550 */ |
551 if(name) | |
552 dbgprintf("CreateEventA(0x%x, 0x%x, 0x%x, 0x%x='%s') => 0x%x\n", | |
553 pSecAttr, bManualReset, bInitialState, name, name, mlist); | |
554 else | |
555 dbgprintf("CreateEventA(0x%x, 0x%x, 0x%x, NULL) => 0x%x\n", | |
556 pSecAttr, bManualReset, bInitialState, mlist); | |
557 return mlist; | |
1 | 558 } |
559 | |
560 void* WINAPI expSetEvent(void* event) | |
561 { | |
128 | 562 mutex_list *ml = (mutex_list *)event; |
563 dbgprintf("SetEvent(%x) => 0x1\n", event); | |
564 pthread_mutex_lock(ml->pm); | |
565 if (ml->state == 0) { | |
566 ml->state = 1; | |
567 pthread_cond_signal(ml->pc); | |
568 } | |
569 pthread_mutex_unlock(ml->pm); | |
570 | |
571 return (void *)1; | |
1 | 572 } |
573 void* WINAPI expResetEvent(void* event) | |
574 { | |
128 | 575 mutex_list *ml = (mutex_list *)event; |
576 dbgprintf("ResetEvent(0x%x) => 0x1\n", event); | |
577 pthread_mutex_lock(ml->pm); | |
578 ml->state = 0; | |
579 pthread_mutex_unlock(ml->pm); | |
580 | |
581 return (void *)1; | |
1 | 582 } |
583 | |
584 void* WINAPI expWaitForSingleObject(void* object, int duration) | |
585 { | |
128 | 586 mutex_list *ml = (mutex_list *)object; |
295
c017b21a1990
added expRegEnumValueA(), fixed expWaitForSingleObject()
arpi_esp
parents:
235
diff
changeset
|
587 int ret=0x12345678; // fixed by Zdenek Kabelac |
128 | 588 mutex_list* pp=mlist; |
589 // dbgprintf("WaitForSingleObject(0x%x, duration %d) =>\n",object, duration); | |
590 do { | |
591 if (pp == NULL) dbgprintf("WaitForSingleObject: NotFound\n"); | |
592 if((pp->pm, mlist->pm)==0) | |
593 break;; | |
594 }while(pp=pp->prev); | |
595 | |
596 | |
597 pthread_mutex_lock(ml->pm); | |
598 | |
599 switch(ml->type) { | |
600 case 0: /* Event */ | |
601 if (duration == 0) { /* Check Only */ | |
602 if (ml->state == 1) ret = WAIT_FAILED; | |
603 else ret = WAIT_OBJECT_0; | |
604 } | |
605 if (duration == -1) { /* INFINITE */ | |
606 if (ml->state == 0) | |
607 pthread_cond_wait(ml->pc,ml->pm); | |
608 if (ml->reset) | |
609 ml->state = 0; | |
610 ret = WAIT_OBJECT_0; | |
611 } | |
612 if (duration > 0) { /* Timed Wait */ | |
613 struct timespec abstime; | |
614 struct timeval now; | |
615 gettimeofday(&now, 0); | |
616 abstime.tv_sec = now.tv_sec + (now.tv_usec+duration)/1000000; | |
617 abstime.tv_nsec = ((now.tv_usec+duration)%1000000)*1000; | |
618 if (ml->state == 0) | |
619 ret=pthread_cond_timedwait(ml->pc,ml->pm,&abstime); | |
620 if (ret == ETIMEDOUT) ret = WAIT_TIMEOUT; | |
621 else ret = WAIT_OBJECT_0; | |
622 if (ml->reset) | |
623 ml->state = 0; | |
624 } | |
625 break; | |
626 case 1: /* Semaphore */ | |
627 if (duration == 0) { | |
628 if(ml->semaphore==0) ret = WAIT_FAILED; | |
629 else { | |
630 ml->semaphore++; | |
631 ret = WAIT_OBJECT_0; | |
632 } | |
633 } | |
634 if (duration == -1) { | |
635 if (ml->semaphore==0) | |
636 pthread_cond_wait(ml->pc,ml->pm); | |
637 ml->semaphore--; | |
638 } | |
639 break; | |
640 } | |
641 pthread_mutex_unlock(ml->pm); | |
642 | |
643 dbgprintf("WaitForSingleObject(0x%x, %d): 0x%x => 0x%x \n",object,duration,ml,ret); | |
644 return (void *)ret; | |
1 | 645 } |
646 | |
647 static BYTE PF[64] = {0,}; | |
648 | |
128 | 649 WIN_BOOL WINAPI expIsProcessorFeaturePresent(DWORD v) |
650 { | |
651 WIN_BOOL result; | |
652 if(v>63)result=0; | |
653 else result=PF[v]; | |
654 dbgprintf("IsProcessorFeaturePresent(0x%x) => 0x%x\n", v, result); | |
655 return result; | |
656 } | |
657 | |
658 static void DumpSystemInfo(const SYSTEM_INFO* si) | |
659 { | |
660 dbgprintf(" Processor architecture %d\n", si->u.s.wProcessorArchitecture); | |
661 dbgprintf(" Page size: %d\n", si->dwPageSize); | |
662 dbgprintf(" Minimum app address: %d\n", si->lpMinimumApplicationAddress); | |
663 dbgprintf(" Maximum app address: %d\n", si->lpMaximumApplicationAddress); | |
664 dbgprintf(" Active processor mask: 0x%x\n", si->dwActiveProcessorMask); | |
665 dbgprintf(" Number of processors: %d\n", si->dwNumberOfProcessors); | |
666 dbgprintf(" Processor type: 0x%x\n", si->dwProcessorType); | |
667 dbgprintf(" Allocation granularity: 0x%x\n", si->dwAllocationGranularity); | |
668 dbgprintf(" Processor level: 0x%x\n", si->wProcessorLevel); | |
669 dbgprintf(" Processor revision: 0x%x\n", si->wProcessorRevision); | |
670 } | |
671 | |
1 | 672 void WINAPI expGetSystemInfo(SYSTEM_INFO* si) |
673 { | |
674 /* FIXME: better values for the two entries below... */ | |
675 static int cache = 0; | |
676 static SYSTEM_INFO cachedsi; | |
128 | 677 unsigned int regs[4]; |
1 | 678 HKEY xhkey=0,hkey; |
128 | 679 dbgprintf("GetSystemInfo(0x%d) =>\n"); |
1 | 680 |
681 if (cache) { | |
682 memcpy(si,&cachedsi,sizeof(*si)); | |
128 | 683 DumpSystemInfo(si); |
1 | 684 return; |
685 } | |
686 memset(PF,0,sizeof(PF)); | |
687 | |
688 cachedsi.u.s.wProcessorArchitecture = PROCESSOR_ARCHITECTURE_INTEL; | |
689 cachedsi.dwPageSize = getpagesize(); | |
690 | |
691 /* FIXME: better values for the two entries below... */ | |
128 | 692 cachedsi.lpMinimumApplicationAddress = (void *)0x00000000; |
1 | 693 cachedsi.lpMaximumApplicationAddress = (void *)0x7FFFFFFF; |
694 cachedsi.dwActiveProcessorMask = 1; | |
695 cachedsi.dwNumberOfProcessors = 1; | |
696 cachedsi.dwProcessorType = PROCESSOR_INTEL_386; | |
697 cachedsi.dwAllocationGranularity = 0x10000; | |
128 | 698 cachedsi.wProcessorLevel = 5; /* pentium */ |
699 cachedsi.wProcessorRevision = 0x0101; | |
1 | 700 |
128 | 701 #if defined(__FreeBSD__) || defined(__NetBSD__) |
1 | 702 cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM; |
703 cachedsi.wProcessorLevel= 5; | |
704 PF[PF_COMPARE_EXCHANGE_DOUBLE] = TRUE; | |
128 | 705 do_cpuid(regs); |
706 if (regs[3] & 0x00800000) | |
707 PF[PF_MMX_INSTRUCTIONS_AVAILABLE] = TRUE; | |
1 | 708 cachedsi.dwNumberOfProcessors=1; |
709 #else | |
710 { | |
711 char buf[20]; | |
712 char line[200]; | |
713 FILE *f = fopen ("/proc/cpuinfo", "r"); | |
714 | |
715 if (!f) | |
716 return; | |
717 xhkey = 0; | |
718 while (fgets(line,200,f)!=NULL) { | |
719 char *s,*value; | |
720 | |
721 /* NOTE: the ':' is the only character we can rely on */ | |
722 if (!(value = strchr(line,':'))) | |
723 continue; | |
724 /* terminate the valuename */ | |
725 *value++ = '\0'; | |
726 /* skip any leading spaces */ | |
727 while (*value==' ') value++; | |
728 if ((s=strchr(value,'\n'))) | |
729 *s='\0'; | |
730 | |
731 /* 2.1 method */ | |
732 if (!lstrncmpiA(line, "cpu family",strlen("cpu family"))) { | |
733 if (isdigit (value[0])) { | |
734 switch (value[0] - '0') { | |
735 case 3: cachedsi.dwProcessorType = PROCESSOR_INTEL_386; | |
736 cachedsi.wProcessorLevel= 3; | |
737 break; | |
738 case 4: cachedsi.dwProcessorType = PROCESSOR_INTEL_486; | |
739 cachedsi.wProcessorLevel= 4; | |
740 break; | |
741 case 5: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM; | |
742 cachedsi.wProcessorLevel= 5; | |
743 break; | |
744 case 6: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM; | |
745 cachedsi.wProcessorLevel= 5; | |
746 break; | |
747 default:cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM; | |
748 cachedsi.wProcessorLevel= 5; | |
749 break; | |
750 } | |
751 } | |
752 /* set the CPU type of the current processor */ | |
753 sprintf(buf,"CPU %ld",cachedsi.dwProcessorType); | |
754 continue; | |
755 } | |
756 /* old 2.0 method */ | |
757 if (!lstrncmpiA(line, "cpu",strlen("cpu"))) { | |
758 if ( isdigit (value[0]) && value[1] == '8' && | |
759 value[2] == '6' && value[3] == 0 | |
760 ) { | |
761 switch (value[0] - '0') { | |
762 case 3: cachedsi.dwProcessorType = PROCESSOR_INTEL_386; | |
763 cachedsi.wProcessorLevel= 3; | |
764 break; | |
765 case 4: cachedsi.dwProcessorType = PROCESSOR_INTEL_486; | |
766 cachedsi.wProcessorLevel= 4; | |
767 break; | |
768 case 5: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM; | |
769 cachedsi.wProcessorLevel= 5; | |
770 break; | |
771 case 6: cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM; | |
772 cachedsi.wProcessorLevel= 5; | |
773 break; | |
774 default:cachedsi.dwProcessorType = PROCESSOR_INTEL_PENTIUM; | |
775 cachedsi.wProcessorLevel= 5; | |
776 break; | |
777 } | |
778 } | |
779 /* set the CPU type of the current processor */ | |
780 sprintf(buf,"CPU %ld",cachedsi.dwProcessorType); | |
781 continue; | |
782 } | |
783 if (!lstrncmpiA(line,"fdiv_bug",strlen("fdiv_bug"))) { | |
784 if (!lstrncmpiA(value,"yes",3)) | |
785 PF[PF_FLOATING_POINT_PRECISION_ERRATA] = TRUE; | |
786 | |
787 continue; | |
788 } | |
789 if (!lstrncmpiA(line,"fpu",strlen("fpu"))) { | |
790 if (!lstrncmpiA(value,"no",2)) | |
791 PF[PF_FLOATING_POINT_EMULATED] = TRUE; | |
792 | |
793 continue; | |
794 } | |
795 if (!lstrncmpiA(line,"processor",strlen("processor"))) { | |
796 /* processor number counts up...*/ | |
797 int x; | |
798 | |
799 if (sscanf(value,"%d",&x)) | |
800 if (x+1>cachedsi.dwNumberOfProcessors) | |
801 cachedsi.dwNumberOfProcessors=x+1; | |
802 | |
803 /* Create a new processor subkey on a multiprocessor | |
804 * system | |
805 */ | |
806 sprintf(buf,"%d",x); | |
807 } | |
808 if (!lstrncmpiA(line,"stepping",strlen("stepping"))) { | |
809 int x; | |
810 | |
811 if (sscanf(value,"%d",&x)) | |
812 cachedsi.wProcessorRevision = x; | |
813 } | |
128 | 814 if |
815 ( (!lstrncmpiA(line,"flags",strlen("flags"))) | |
816 || (!lstrncmpiA(line,"features",strlen("features"))) ) | |
817 { | |
1 | 818 if (strstr(value,"cx8")) |
819 PF[PF_COMPARE_EXCHANGE_DOUBLE] = TRUE; | |
820 if (strstr(value,"mmx")) | |
821 PF[PF_MMX_INSTRUCTIONS_AVAILABLE] = TRUE; | |
822 | |
823 } | |
824 } | |
825 fclose (f); | |
128 | 826 /* |
827 * ad hoc fix for smp machines. | |
828 * some problems on WaitForSingleObject,CreateEvent,SetEvent | |
829 * CreateThread ...etc.. | |
830 * | |
831 */ | |
832 cachedsi.dwNumberOfProcessors=1; | |
1 | 833 } |
834 #endif /* __FreeBSD__ */ | |
835 memcpy(si,&cachedsi,sizeof(*si)); | |
128 | 836 DumpSystemInfo(si); |
1 | 837 } |
838 | |
839 long WINAPI expGetVersion() | |
840 { | |
128 | 841 dbgprintf("GetVersion() => 0xC0000004\n"); |
842 return 0xC0000004;//Windows 95 | |
1 | 843 } |
844 | |
845 HANDLE WINAPI expHeapCreate(long flags, long init_size, long max_size) | |
846 { | |
847 // printf("HeapCreate:"); | |
128 | 848 HANDLE result; |
1 | 849 if(init_size==0) |
128 | 850 result=(HANDLE)my_mreq(0x110000, 0); |
1 | 851 else |
128 | 852 result=(HANDLE)my_mreq(init_size, 0); |
853 dbgprintf("HeapCreate(flags 0x%x, initial size %d, maximum size %d) => 0x%x\n", flags, init_size, max_size, result); | |
854 return result; | |
1 | 855 } |
856 void* WINAPI expHeapAlloc(HANDLE heap, int flags, int size) | |
857 { | |
858 void* z; | |
859 // printf("HeapAlloc:"); | |
128 | 860 /** |
861 Morgan's m3jpeg32.dll v. 2.0 encoder expects that request for | |
862 HeapAlloc returns area larger than size argument :-/ | |
863 **/ | |
864 z=my_mreq(((size+4095)/4096)*4096, flags&8); | |
1 | 865 // z=HeapAlloc(heap,flags,size); |
866 if(z==0) | |
867 printf("HeapAlloc failure\n"); | |
128 | 868 dbgprintf("HeapAlloc(heap 0x%x, flags 0x%x, size 0x%x) => 0x%x\n", heap, flags, size, z); |
1 | 869 return z; |
870 } | |
871 long WINAPI expHeapDestroy(void* heap) | |
872 { | |
128 | 873 dbgprintf("HeapDestroy(heap 0x%x) => 1\n", heap); |
1 | 874 my_release(heap); |
875 return 1; | |
876 } | |
877 | |
878 long WINAPI expHeapFree(int arg1, int arg2, void* ptr) | |
879 { | |
128 | 880 dbgprintf("HeapFree(0x%x, 0x%x, pointer 0x%x) => 1\n", arg1, arg2, ptr); |
1 | 881 my_release(ptr); |
882 return 1; | |
883 } | |
884 long WINAPI expHeapSize(int heap, int flags, void* pointer) | |
885 { | |
128 | 886 long result=my_size(pointer); |
887 dbgprintf("HeapSize(heap 0x%x, flags 0x%x, pointer 0x%x) => %d\n", heap, flags, pointer, result); | |
888 return result; | |
1 | 889 } |
890 long WINAPI expGetProcessHeap(void) | |
891 { | |
128 | 892 dbgprintf("GetProcessHeap() => 1\n"); |
1 | 893 return 1; |
894 } | |
895 void* WINAPI expVirtualAlloc(void* v1, long v2, long v3, long v4) | |
896 { | |
897 void* z; | |
898 z=VirtualAlloc(v1, v2, v3, v4); | |
899 if(z==0) | |
900 printf("VirtualAlloc failure\n"); | |
128 | 901 dbgprintf("VirtualAlloc(0x%x, %d, %d, %d) => 0x%x \n",v1,v2,v3,v4, z); |
1 | 902 return z; |
903 } | |
904 int WINAPI expVirtualFree(void* v1, int v2, int v3) | |
905 { | |
128 | 906 int result=VirtualFree(v1,v2,v3); |
907 dbgprintf("VirtualFree(0x%x, %d, %d) => %d\n",v1,v2,v3, result); | |
908 return result; | |
1 | 909 } |
910 struct CRITSECT | |
911 { | |
912 pthread_t id; | |
913 pthread_mutex_t mutex; | |
914 int locked; | |
915 }; | |
916 void WINAPI expInitializeCriticalSection(CRITICAL_SECTION* c) | |
917 { | |
918 struct CRITSECT cs; | |
128 | 919 dbgprintf("InitializeCriticalSection(0x%x)\n", c); |
1 | 920 /* if(sizeof(pthread_mutex_t)>sizeof(CRITICAL_SECTION)) |
921 { | |
922 printf(" ERROR:::: sizeof(pthread_mutex_t) is %d, expected <=%d!\n", | |
923 sizeof(pthread_mutex_t), sizeof(CRITICAL_SECTION)); | |
924 return; | |
925 }*/ | |
926 /* pthread_mutex_init((pthread_mutex_t*)c, NULL); */ | |
927 pthread_mutex_init(&cs.mutex, NULL); | |
928 cs.locked=0; | |
929 *(void**)c=malloc(sizeof cs); | |
930 memcpy(*(void**)c, &cs, sizeof cs); | |
931 return; | |
932 } | |
933 void WINAPI expEnterCriticalSection(CRITICAL_SECTION* c) | |
934 { | |
128 | 935 struct CRITSECT* cs=*(struct CRITSECT**)c; |
936 dbgprintf("EnterCriticalSection(0x%x)\n",c); | |
1 | 937 // cs.id=pthread_self(); |
938 if(cs->locked) | |
939 if(cs->id==pthread_self()) | |
940 return; | |
941 pthread_mutex_lock(&(cs->mutex)); | |
942 cs->locked=1; | |
943 cs->id=pthread_self(); | |
944 return; | |
945 } | |
946 void WINAPI expLeaveCriticalSection(CRITICAL_SECTION* c) | |
947 { | |
128 | 948 struct CRITSECT* cs=*(struct CRITSECT**)c; |
949 // struct CRITSECT* cs=(struct CRITSECT*)c; | |
950 dbgprintf("LeaveCriticalSection(0x%x)\n",c); | |
1 | 951 cs->locked=0; |
952 pthread_mutex_unlock(&(cs->mutex)); | |
953 return; | |
954 } | |
955 void WINAPI expDeleteCriticalSection(CRITICAL_SECTION *c) | |
956 { | |
128 | 957 struct CRITSECT* cs=*(struct CRITSECT**)c; |
958 // struct CRITSECT* cs=(struct CRITSECT*)c; | |
959 dbgprintf("DeleteCriticalSection(0x%x)\n",c); | |
960 pthread_mutex_destroy(&(cs->mutex)); | |
961 free(cs); | |
1 | 962 return; |
963 } | |
964 int WINAPI expGetCurrentThreadId() | |
965 { | |
128 | 966 dbgprintf("GetCurrentThreadId() => %d\n", getpid()); |
967 return getpid(); | |
968 } | |
969 int WINAPI expGetCurrentProcess() | |
970 { | |
971 dbgprintf("GetCurrentProcess() => %d\n", getpid()); | |
1 | 972 return getpid(); |
973 } | |
974 struct tls_s; | |
975 typedef struct tls_s | |
976 { | |
977 void* value; | |
978 int used; | |
979 struct tls_s* prev; | |
980 struct tls_s* next; | |
981 }tls_t; | |
982 | |
983 tls_t* g_tls=NULL; | |
984 | |
985 void* WINAPI expTlsAlloc() | |
986 { | |
987 if(g_tls==NULL) | |
988 { | |
989 g_tls=my_mreq(sizeof(tls_t), 0); | |
990 g_tls->next=g_tls->prev=NULL; | |
991 } | |
992 else | |
993 { | |
994 g_tls->next=my_mreq(sizeof(tls_t), 0); | |
995 g_tls->next->prev=g_tls; | |
996 g_tls->next->next=NULL; | |
997 g_tls=g_tls->next; | |
998 } | |
128 | 999 dbgprintf("TlsAlloc() => 0x%x\n", g_tls); |
1000 return g_tls; | |
1 | 1001 } |
1002 | |
1003 int WINAPI expTlsSetValue(tls_t* index, void* value) | |
1004 { | |
128 | 1005 int result; |
1 | 1006 if(index==0) |
128 | 1007 result=0; |
1008 else | |
1009 { | |
1010 index->value=value; | |
1011 result=1; | |
1012 } | |
1013 dbgprintf("TlsSetValue(index 0x%x, value 0x%x) => %d \n", index, value, result ); | |
1014 return result; | |
1 | 1015 } |
1016 void* WINAPI expTlsGetValue(tls_t* index) | |
1017 { | |
128 | 1018 void* result; |
1 | 1019 if(index==0) |
128 | 1020 result=0; |
1021 else | |
1022 result=index->value; | |
1023 dbgprintf("TlsGetValue(index 0x%x) => 0x%x\n", index, result); | |
1024 return result; | |
1 | 1025 } |
1026 int WINAPI expTlsFree(tls_t* index) | |
1027 { | |
128 | 1028 int result; |
1 | 1029 if(index==0) |
128 | 1030 result=0; |
1031 else | |
1032 { | |
1033 if(index->next) | |
1034 index->next->prev=index->prev; | |
1035 if(index->prev) | |
1036 index->prev->next=index->next; | |
1037 my_release((void*)index); | |
1038 result=1; | |
1039 } | |
1040 dbgprintf("TlsFree(index 0x%x) => %d\n", index, result); | |
1041 return result; | |
1 | 1042 } |
1043 void* WINAPI expLocalAlloc(int flags, int size) | |
1044 { | |
1045 void* z; | |
1046 if(flags&GMEM_ZEROINIT) | |
1047 z=my_mreq(size, 1); | |
1048 else | |
1049 z=my_mreq(size, 0); | |
1050 if(z==0) | |
1051 printf("LocalAlloc() failed\n"); | |
128 | 1052 dbgprintf("LocalAlloc(%d, flags 0x%x) => 0x%x\n", size, flags, z); |
1 | 1053 return z; |
1054 } | |
1055 void* WINAPI expLocalLock(void* z) | |
1056 { | |
128 | 1057 dbgprintf("LocalLock(0x%x) => 0x%x\n", z, z); |
1 | 1058 return z; |
1059 } | |
128 | 1060 |
1 | 1061 void* WINAPI expGlobalAlloc(int flags, int size) |
1062 { | |
1063 void* z; | |
1064 dbgprintf("GlobalAlloc(%d, flags 0x%X)\n", size, flags); | |
1065 if(flags&GMEM_ZEROINIT) | |
128 | 1066 z=calloc(size, 1); |
1067 // z=my_mreq(size, 1); | |
1 | 1068 else |
128 | 1069 z=malloc(size); |
1070 // z=my_mreq(size, 0); | |
1 | 1071 if(z==0) |
128 | 1072 printf("GlobalAlloc() failed\n"); |
1073 dbgprintf("GlobalAlloc(%d, flags 0x%x) => 0x%x\n", size, flags, z); | |
1 | 1074 return z; |
1075 } | |
1076 void* WINAPI expGlobalLock(void* z) | |
1077 { | |
128 | 1078 dbgprintf("GlobalLock(0x%x) => 0x%x\n", z, z); |
1 | 1079 return z; |
1080 } | |
1081 int WINAPI expLoadStringA(long instance, long id, void* buf, long size) | |
1082 { | |
128 | 1083 int result=LoadStringA(instance, id, buf, size); |
1084 // if(buf) | |
1085 dbgprintf("LoadStringA(instance 0x%x, id 0x%x, buffer 0x%x, size %d) => %d ( %s )\n", | |
1086 instance, id, buf, size, result, buf); | |
1087 // else | |
1088 // dbgprintf("LoadStringA(instance 0x%x, id 0x%x, buffer 0x%x, size %d) => %d\n", | |
1089 // instance, id, buf, size, result); | |
1090 return result; | |
1 | 1091 } |
1092 | |
128 | 1093 long WINAPI expMultiByteToWideChar(long v1, long v2, char* s1, long siz1, short* s2, int siz2) |
1 | 1094 { |
1095 #warning FIXME | |
128 | 1096 int i; |
1097 int result; | |
1 | 1098 if(s2==0) |
128 | 1099 result=1; |
1100 else | |
1101 { | |
1102 if(siz1>siz2/2)siz1=siz2/2; | |
1103 for(i=1; i<=siz1; i++) | |
1104 { | |
1105 *s2=*s1; | |
1106 if(!*s1)break; | |
1107 s2++; | |
1108 s1++; | |
1109 } | |
1110 result=i; | |
1111 } | |
1112 if(s1) | |
1113 dbgprintf("MultiByteToWideChar(codepage %d, flags 0x%x, string 0x%x='%s', | |
1114 size %d, dest buffer 0x%x, dest size %d) => %d\n", | |
1115 v1, v2, s1, s1, siz1, s2, siz2, result); | |
1116 else | |
1117 dbgprintf("MultiByteToWideChar(codepage %d, flags 0x%x, string NULL, | |
1118 size %d, dest buffer 0x%x, dest size %d) =>\n", | |
1119 v1, v2, siz1, s2, siz2, result); | |
1120 return result; | |
1121 } | |
1122 static void wch_print(const short* str) | |
1123 { | |
1124 dbgprintf(" src: "); | |
1125 while(*str)dbgprintf("%c", *str++); | |
1126 dbgprintf("\n"); | |
1 | 1127 } |
1128 long WINAPI expWideCharToMultiByte(long v1, long v2, short* s1, long siz1, char* s2, int siz2, char* c3, int* siz3) | |
1129 { | |
1130 int result; | |
128 | 1131 dbgprintf("WideCharToMultiByte(codepage %d, flags 0x%x, src 0x%x, src size %d, " |
1132 "dest 0x%x, dest size %d, defch 0x%x, used_defch 0x%x)", v1, v2, s1, siz1, s2, siz2, c3, siz3); | |
1 | 1133 result=WideCharToMultiByte(v1, v2, s1, siz1, s2, siz2, c3, siz3); |
1134 dbgprintf("=> %d\n", result); | |
128 | 1135 if(s1)wch_print(s1); |
1136 if(s2)dbgprintf(" dest: %s\n", s2); | |
1 | 1137 return result; |
1138 } | |
1139 long WINAPI expGetVersionExA(OSVERSIONINFOA* c) | |
1140 { | |
128 | 1141 dbgprintf("GetVersionExA(0x%x) => 1\n"); |
1142 c->dwOSVersionInfoSize=sizeof(*c); | |
1 | 1143 c->dwMajorVersion=4; |
128 | 1144 c->dwMinorVersion=0; |
1145 c->dwBuildNumber=0x4000457; | |
1 | 1146 c->dwPlatformId=VER_PLATFORM_WIN32_WINDOWS; |
128 | 1147 strcpy(c->szCSDVersion, " B"); |
1148 dbgprintf(" Major version: 4\n Minor version: 0\n Build number: 0x4000457\n" | |
1149 " Platform Id: VER_PLATFORM_WIN32_WINDOWS\n Version string: ' B'\n"); | |
1 | 1150 return 1; |
1151 } | |
1152 HANDLE WINAPI expCreateSemaphoreA(char* v1, long init_count, long max_count, char* name) | |
1153 { | |
128 | 1154 pthread_mutex_t *pm; |
1155 pthread_cond_t *pc; | |
1156 if(mlist!=NULL) | |
1 | 1157 { |
128 | 1158 mutex_list* pp=mlist; |
1159 if(name!=NULL) | |
1160 do | |
1161 { | |
1162 if((strcmp(pp->name, name)==0) && (pp->type==1)) | |
1163 { | |
1164 dbgprintf("CreateSemaphoreA(0x%x, init_count %d, max_count %d, name 0x%x='%s') => 0x%x", | |
1165 v1, init_count, max_count, name, name, mlist); | |
1166 return (HANDLE)mlist; | |
1167 } | |
1168 }while(pp=pp->prev); | |
1 | 1169 } |
128 | 1170 pm=my_mreq(sizeof(pthread_mutex_t), 0); |
1171 pthread_mutex_init(pm, NULL); | |
1172 pc=my_mreq(sizeof(pthread_cond_t), 0); | |
1173 pthread_cond_init(pc, NULL); | |
1174 if(mlist==NULL) | |
1175 { | |
1176 mlist=my_mreq(sizeof(mutex_list), 00); | |
1177 mlist->next=mlist->prev=NULL; | |
1178 } | |
1179 else | |
1 | 1180 { |
128 | 1181 mlist->next=my_mreq(sizeof(mutex_list), 00); |
1182 mlist->next->prev=mlist; | |
1183 mlist->next->next=NULL; | |
1184 mlist=mlist->next; | |
1 | 1185 } |
128 | 1186 mlist->type=1; /* Type Semaphore */ |
1187 mlist->pm=pm; | |
1188 mlist->pc=pc; | |
1189 mlist->state=0; | |
1190 mlist->reset=0; | |
1191 mlist->semaphore=init_count; | |
1192 if(name!=NULL) | |
1193 strncpy(mlist->name, name, 64); | |
1194 else | |
1195 mlist->name[0]=0; | |
1196 if(pm==NULL) | |
1197 dbgprintf("ERROR::: CreateSemaphoreA failure\n"); | |
1198 if(name) | |
1199 dbgprintf("CreateSemaphoreA(0x%x, init_count %d, max_count %d, name 0x%x='%s') => 0x%x", | |
1200 v1, init_count, max_count, name, name, mlist); | |
1201 else | |
1202 dbgprintf("CreateSemaphoreA(0x%x, init_count %d, max_count %d, name 0) => 0x%x", | |
1203 v1, init_count, max_count, mlist); | |
1204 return (HANDLE)mlist; | |
1 | 1205 } |
1206 | |
1207 long WINAPI expReleaseSemaphore(long hsem, long increment, long* prev_count) | |
1208 { | |
1209 // The state of a semaphore object is signaled when its count | |
1210 // is greater than zero and nonsignaled when its count is equal to zero | |
1211 // Each time a waiting thread is released because of the semaphore's signaled | |
1212 // state, the count of the semaphore is decreased by one. | |
128 | 1213 mutex_list *ml = (mutex_list *)hsem; |
1 | 1214 |
128 | 1215 pthread_mutex_lock(ml->pm); |
1216 if (prev_count != 0) *prev_count = ml->semaphore; | |
1217 if (ml->semaphore == 0) pthread_cond_signal(ml->pc); | |
1218 ml->semaphore += increment; | |
1219 pthread_mutex_unlock(ml->pm); | |
1220 dbgprintf("ReleaseSemaphore(semaphore 0x%x, increment %d, prev_count 0x%x) => 1\n", | |
1221 hsem, increment, prev_count); | |
1222 return 1; | |
1 | 1223 } |
1224 | |
1225 | |
1226 long WINAPI expRegOpenKeyExA(long key, const char* subkey, long reserved, long access, int* newkey) | |
1227 { | |
128 | 1228 long result=RegOpenKeyExA(key, subkey, reserved, access, newkey); |
1229 dbgprintf("RegOpenKeyExA(key 0x%x, subkey %s, reserved %d, access 0x%x, pnewkey 0x%x) => %d\n", | |
1230 key, subkey, reserved, access, newkey, result); | |
1231 if(newkey)dbgprintf(" New key: 0x%x\n", *newkey); | |
1232 return result; | |
1 | 1233 } |
1234 long WINAPI expRegCloseKey(long key) | |
1235 { | |
128 | 1236 long result=RegCloseKey(key); |
1237 dbgprintf("RegCloseKey(0x%x) => %d\n", key, result); | |
1238 return result; | |
1 | 1239 } |
1240 long WINAPI expRegQueryValueExA(long key, const char* value, int* reserved, int* type, int* data, int* count) | |
1241 { | |
128 | 1242 long result=RegQueryValueExA(key, value, reserved, type, data, count); |
1243 dbgprintf("RegQueryValueExA(key 0x%x, value %s, reserved 0x%x, data 0x%x, count 0x%x)" | |
1244 " => 0x%x\n", key, value, reserved, data, count, result); | |
1245 if(data && count)dbgprintf(" read %d bytes: '%s'\n", *count, data); | |
1246 return result; | |
1 | 1247 } |
1248 long WINAPI expRegCreateKeyExA(long key, const char* name, long reserved, | |
1249 void* classs, long options, long security, | |
1250 void* sec_attr, int* newkey, int* status) | |
1251 { | |
128 | 1252 long result=RegCreateKeyExA(key, name, reserved, classs, options, security, sec_attr, newkey, status); |
1253 dbgprintf("RegCreateKeyExA(key 0x%x, name 0x%x='%s', reserved=0x%x," | |
1254 " 0x%x, 0x%x, 0x%x, newkey=0x%x, status=0x%x) => %d\n", | |
1255 key, name, name, reserved, classs, options, security, sec_attr, newkey, status, result); | |
1256 if(!result && newkey) dbgprintf(" New key: 0x%x\n", *newkey); | |
1257 if(!result && status) dbgprintf(" New key status: 0x%x\n", *status); | |
1258 return result; | |
1 | 1259 } |
1260 long WINAPI expRegSetValueExA(long key, const char* name, long v1, long v2, void* data, long size) | |
1261 { | |
128 | 1262 long result=RegSetValueExA(key, name, v1, v2, data, size); |
1263 dbgprintf("RegSetValueExA(key 0x%x, name '%s', 0x%x, 0x%x, data 0x%x -> 0x%x '%s', size=%d) => %d", | |
1264 key, name, v1, v2, data, *(int*)data, data, size, result); | |
1265 return result; | |
1 | 1266 } |
1267 | |
1268 long WINAPI expRegOpenKeyA ( | |
1269 long hKey, | |
1270 LPCSTR lpSubKey, | |
1271 int* phkResult | |
1272 ){ | |
128 | 1273 long result=RegOpenKeyExA(hKey, lpSubKey, 0, 0, phkResult); |
1274 dbgprintf("RegOpenKeyExA(key 0x%x, subkey '%s', 0x%x) => %d\n", | |
1275 hKey, lpSubKey, phkResult, result); | |
1276 if(!result && phkResult) dbgprintf(" New key: 0x%x\n", *phkResult); | |
1277 return result; | |
1 | 1278 } |
1279 | |
1280 long WINAPI expQueryPerformanceCounter(long long* z) | |
1281 { | |
1282 longcount(z); | |
128 | 1283 dbgprintf("QueryPerformanceCounter(0x%x) => 1 ( %Ld )\n", z, *z); |
1 | 1284 return 1; |
1285 } | |
1286 | |
1287 static double old_freq() | |
1288 { | |
128 | 1289 static double ofreq=0.0; |
1290 int i; | |
1 | 1291 int x,y; |
128 | 1292 i=time(NULL); |
1293 if (ofreq != 0.0) return ofreq; | |
1 | 1294 while(i==time(NULL)); |
1295 x=localcount(); | |
1296 i++; | |
1297 while(i==time(NULL)); | |
1298 y=localcount(); | |
128 | 1299 ofreq = (double)(y-x)/1000.; |
1300 return ofreq; | |
1 | 1301 } |
1302 static double CPU_Freq() | |
1303 { | |
128 | 1304 //#ifdef USE_TSC |
1 | 1305 FILE *f = fopen ("/proc/cpuinfo", "r"); |
1306 char line[200]; | |
1307 char model[200]="unknown"; | |
1308 char flags[500]=""; | |
1309 char *s,*value; | |
1310 double freq=-1; | |
1311 | |
1312 if (!f) | |
1313 { | |
128 | 1314 //printf("Can't open /proc/cpuinfo for reading\n"); |
1 | 1315 return old_freq(); |
1316 } | |
1317 while (fgets(line,200,f)!=NULL) | |
1318 { | |
1319 /* NOTE: the ':' is the only character we can rely on */ | |
1320 if (!(value = strchr(line,':'))) | |
1321 continue; | |
1322 /* terminate the valuename */ | |
1323 *value++ = '\0'; | |
1324 /* skip any leading spaces */ | |
1325 while (*value==' ') value++; | |
1326 if ((s=strchr(value,'\n'))) | |
1327 *s='\0'; | |
1328 | |
1329 if (!strncasecmp(line, "cpu MHz",strlen("cpu MHz"))) | |
1330 { | |
1331 sscanf(value, "%lf", &freq); | |
1332 freq*=1000; | |
1333 break; | |
1334 } | |
1335 continue; | |
1336 | |
1337 } | |
1338 fclose(f); | |
1339 if(freq<0)return old_freq(); | |
1340 return freq; | |
128 | 1341 //#else |
1342 // return old_freq(); | |
1343 //#endif | |
1 | 1344 } |
1345 | |
1346 long WINAPI expQueryPerformanceFrequency(long long* z) | |
1347 { | |
1348 *z=(long long)CPU_Freq(); | |
128 | 1349 dbgprintf("QueryPerformanceFrequency(0x%x) => 1 ( %Ld )\n", z, *z); |
1 | 1350 return 1; |
1351 } | |
1352 long WINAPI exptimeGetTime() | |
1353 { | |
1354 struct timeval t; | |
128 | 1355 long result; |
1 | 1356 gettimeofday(&t, 0); |
128 | 1357 result=1000*t.tv_sec+t.tv_usec/1000; |
1358 dbgprintf("timeGetTime() => %d\n", result); | |
1359 return result; | |
1 | 1360 } |
1361 void* WINAPI expLocalHandle(void* v) | |
1362 { | |
128 | 1363 dbgprintf("LocalHandle(0x%x) => 0x%x\n", v, v); |
1 | 1364 return v; |
1365 } | |
1366 void* WINAPI expGlobalHandle(void* v) | |
1367 { | |
128 | 1368 dbgprintf("GlobalHandle(0x%x) => 0x%x\n", v, v); |
1 | 1369 return v; |
1370 } | |
1371 int WINAPI expGlobalUnlock(void* v) | |
1372 { | |
128 | 1373 dbgprintf("GlobalUnlock(0x%x) => 1\n", v); |
1 | 1374 return 1; |
1375 } | |
1376 // | |
1377 void* WINAPI expGlobalFree(void* v) | |
1378 { | |
128 | 1379 dbgprintf("GlobalFree(0x%x) => 0\n", v); |
1380 //my_release(v); | |
1381 free(v); | |
1 | 1382 return 0; |
128 | 1383 } |
1384 | |
1385 | |
1386 void* WINAPI expGlobalReAlloc(void* v, int size, int flags) | |
1387 { | |
1388 void* result=realloc(v, size); | |
1389 dbgprintf("GlobalReAlloc(0x%x, size %d, flags 0x%x) => 0x%x\n", v,size,flags,result); | |
1390 return result; | |
1391 } | |
1 | 1392 |
1393 int WINAPI expLocalUnlock(void* v) | |
1394 { | |
128 | 1395 dbgprintf("LocalUnlock(0x%x) => 1\n", v); |
1 | 1396 return 1; |
1397 } | |
128 | 1398 // |
1 | 1399 void* WINAPI expLocalFree(void* v) |
1400 { | |
128 | 1401 dbgprintf("LocalFree(0x%x) => 0\n", v); |
1 | 1402 my_release(v); |
1403 return 0; | |
1404 } | |
1405 HRSRC WINAPI expFindResourceA(HMODULE module, char* name, char* type) | |
1406 { | |
128 | 1407 HRSRC result=FindResourceA(module, name, type); |
1408 dbgprintf("FindResourceA(module 0x%x, name 0x%x, type 0x%x) => 0x%x\n", module, name, type, result); | |
1409 return result; | |
1 | 1410 } |
128 | 1411 extern HRSRC WINAPI LoadResource(HMODULE, HRSRC); |
1 | 1412 HGLOBAL WINAPI expLoadResource(HMODULE module, HRSRC res) |
1413 { | |
128 | 1414 HGLOBAL result=LoadResource(module, res); |
1415 dbgprintf("LoadResource(module 0x%x, resource 0x%x) => 0x%x\n", module, res, result); | |
1416 return result; | |
1 | 1417 } |
1418 void* WINAPI expLockResource(long res) | |
1419 { | |
128 | 1420 void* result=LockResource(res); |
1421 dbgprintf("LockResource(0x%x) => 0x%x\n", res, result); | |
1422 return result; | |
1 | 1423 } |
1424 int WINAPI expFreeResource(long res) | |
1425 { | |
128 | 1426 int result=FreeResource(res); |
1427 dbgprintf("FreeResource(0x%x) => %d\n", res, result); | |
1428 return result; | |
1 | 1429 } |
1430 //bool fun(HANDLE) | |
1431 //!0 on success | |
1432 int WINAPI expCloseHandle(long v1) | |
1433 { | |
128 | 1434 dbgprintf("CloseHandle(0x%x) => 1\n", v1); |
1 | 1435 return 1; |
1436 } | |
1437 | |
1438 const char* WINAPI expGetCommandLineA() | |
1439 { | |
128 | 1440 dbgprintf("GetCommandLineA() => \"c:\\aviplay.exe\"\n"); |
1 | 1441 return "c:\\aviplay.exe"; |
1442 } | |
128 | 1443 static short envs[]={'p', 'a', 't', 'h', ' ', 'c', ':', '\\', 0, 0}; |
1 | 1444 LPWSTR WINAPI expGetEnvironmentStringsW() |
1445 { | |
128 | 1446 dbgprintf("GetEnvironmentStringsW() => 0\n", envs); |
1447 return 0; | |
1 | 1448 } |
121 | 1449 void * WINAPI expRtlZeroMemory(void *p, size_t len) |
1450 { | |
1451 void* result=memset(p,0,len); | |
1452 dbgprintf("RtlZeroMemory(0x%x, len %d) => 0x%x\n",p,len,result); | |
1453 return result; | |
1454 } | |
1455 void * WINAPI expRtlMoveMemory(void *dst, void *src, size_t len) | |
1456 { | |
1457 void* result=memmove(dst,src,len); | |
1458 dbgprintf("RtlMoveMemory (dest 0x%x, src 0x%x, len %d) => 0x%x\n",dst,src,len,result); | |
1459 return result; | |
1460 } | |
1461 | |
1462 void * WINAPI expRtlFillMemory(void *p, int ch, size_t len) | |
1463 { | |
1464 void* result=memset(p,ch,len); | |
1465 dbgprintf("RtlFillMemory(0x%x, char 0x%x, len %d) => 0x%x\n",p,ch,len,result); | |
1466 return result; | |
1467 } | |
1 | 1468 int WINAPI expFreeEnvironmentStringsW(short* strings) |
1469 { | |
128 | 1470 dbgprintf("FreeEnvironmentStringsW(0x%x) => 1\n", strings); |
1 | 1471 return 1; |
1472 } | |
128 | 1473 int WINAPI expFreeEnvironmentStringsA(char* strings) |
1474 { | |
1475 dbgprintf("FreeEnvironmentStringsA(0x%x) => 1\n", strings); | |
1476 return 1; | |
1477 } | |
1478 static const char ch_envs[]= | |
1479 "__MSVCRT_HEAP_SELECT=__GLOBAL_HEAP_SELECTED,1\r\n" | |
1480 "PATH=C:\\;C:\\windows\\;C:\\windows\\system\r\n"; | |
1 | 1481 LPCSTR WINAPI expGetEnvironmentStrings() |
1482 { | |
128 | 1483 dbgprintf("GetEnvironmentStrings() => 0x%x\n", ch_envs); |
1484 return (LPCSTR)ch_envs; | |
1485 // dbgprintf("GetEnvironmentStrings() => 0\n"); | |
1486 // return 0; | |
1 | 1487 } |
1488 | |
1489 int WINAPI expGetStartupInfoA(STARTUPINFOA *s) | |
1490 { | |
1491 int i; | |
128 | 1492 dbgprintf("GetStartupInfoA(0x%x) => 1\n"); |
1 | 1493 memset(s, 0, sizeof(*s)); |
1494 s->cb=sizeof(*s); | |
128 | 1495 // s->lpReserved="Reserved"; |
1496 // s->lpDesktop="Desktop"; | |
1497 // s->lpTitle="Title"; | |
1498 // s->dwX=s->dwY=0; | |
1499 // s->dwXSize=s->dwYSize=200; | |
1500 s->dwFlags=s->wShowWindow=1; | |
1501 // s->hStdInput=s->hStdOutput=s->hStdError=0x1234; | |
1502 dbgprintf(" cb=%d\n", s->cb); | |
1503 dbgprintf(" lpReserved='%s'\n", s->lpReserved); | |
1504 dbgprintf(" lpDesktop='%s'\n", s->lpDesktop); | |
1505 dbgprintf(" lpTitle='%s'\n", s->lpTitle); | |
1506 dbgprintf(" dwX=%d dwY=%d dwXSize=%d dwYSize=%d\n", | |
1507 s->dwX, s->dwY, s->dwXSize, s->dwYSize); | |
1508 dbgprintf(" dwXCountChars=%d dwYCountChars=%d dwFillAttribute=%d\n", | |
1509 s->dwXCountChars, s->dwYCountChars, s->dwFillAttribute); | |
1510 dbgprintf(" dwFlags=0x%x wShowWindow=0x%x cbReserved2=0x%x\n", | |
1511 s->dwFlags, s->wShowWindow, s->cbReserved2); | |
1512 dbgprintf(" lpReserved2=0x%x hStdInput=0x%x hStdOutput=0x%x hStdError=0x%x\n", | |
1513 s->lpReserved2, s->hStdInput, s->hStdOutput, s->hStdError); | |
1 | 1514 return 1; |
1515 } | |
1516 | |
1517 int WINAPI expGetStdHandle(int z) | |
1518 { | |
128 | 1519 dbgprintf("GetStdHandle(0x%x) => 0x%x\n", z+0x1234); |
1520 return z+0x1234; | |
1 | 1521 } |
1522 int WINAPI expGetFileType(int handle) | |
1523 { | |
128 | 1524 dbgprintf("GetFileType(0x%x) => 0x3 = pipe\n", handle); |
1525 return 0x3; | |
1 | 1526 } |
1527 int WINAPI expSetHandleCount(int count) | |
1528 { | |
128 | 1529 dbgprintf("SetHandleCount(0x%x) => 1\n", count); |
1 | 1530 return 1; |
1531 } | |
1532 int WINAPI expGetACP() | |
1533 { | |
128 | 1534 dbgprintf("GetACP() => 0\n"); |
1 | 1535 return 0; |
1536 } | |
1537 extern WINE_MODREF *MODULE32_LookupHMODULE(HMODULE m); | |
1538 int WINAPI expGetModuleFileNameA(int module, char* s, int len) | |
1539 { | |
1540 WINE_MODREF *mr; | |
128 | 1541 int result; |
1 | 1542 // printf("File name of module %X requested\n", module); |
1543 if(s==0) | |
128 | 1544 result=0; |
1545 else | |
1 | 1546 if(len<35) |
128 | 1547 result=0; |
1548 else | |
1 | 1549 { |
128 | 1550 result=1; |
1551 strcpy(s, "c:\\windows\\system\\"); | |
1552 mr=MODULE32_LookupHMODULE(module); | |
1553 if(mr==0)//oops | |
1554 strcat(s, "aviplay.dll"); | |
1555 else | |
1556 if(strrchr(mr->filename, '/')==NULL) | |
1557 strcat(s, mr->filename); | |
1558 else | |
1559 strcat(s, strrchr(mr->filename, '/')+1); | |
1560 } | |
1561 if(!s) | |
1562 dbgprintf("GetModuleFileNameA(0x%x, 0x%x, %d) => %d\n", | |
1563 module, s, len, result); | |
1 | 1564 else |
128 | 1565 dbgprintf("GetModuleFileNameA(0x%x, 0x%x, %d) => %d ( '%s' )", |
1566 module, s, len, result, s); | |
1567 return result; | |
1 | 1568 } |
1569 | |
1570 int WINAPI expSetUnhandledExceptionFilter(void* filter) | |
1571 { | |
128 | 1572 dbgprintf("SetUnhandledExceptionFilter(0x%x) => 1\n", filter); |
1 | 1573 return 1;//unsupported and probably won't ever be supported |
1574 } | |
1575 extern char* def_path; | |
1576 int WINAPI expLoadLibraryA(char* name) | |
1577 { | |
1578 char qq[256]; | |
128 | 1579 int result; |
130 | 1580 printf("They want library [%s] %s\n", def_path, name); |
128 | 1581 if(strncmp(name, "c:\\windows\\", 11)==0)name+=11; |
1582 if(name[0]!='/') | |
1583 { | |
1584 strcpy(qq, def_path); | |
1585 strcat(qq, "/"); | |
1586 if(strncmp(name, ".\\", 2)==0) | |
1587 strcat(qq, name+2); | |
1588 else | |
1589 strcat(qq, name); | |
1590 } | |
130 | 1591 printf("Entering LoadLibraryA(%s)\n", name); |
128 | 1592 result=LoadLibraryA(qq); |
130 | 1593 printf("Returned LoadLibraryA(0x%x='%s'), def_path=%s => 0x%x\n", name, name, def_path, result); |
128 | 1594 return result; |
1 | 1595 } |
1596 int WINAPI expFreeLibrary(int module) | |
1597 { | |
128 | 1598 int result=FreeLibrary(module); |
1599 dbgprintf("FreeLibrary(0x%x) => %d\n", module, result); | |
1600 return result; | |
1 | 1601 } |
1602 void* WINAPI expGetProcAddress(HMODULE mod, char* name) | |
1603 { | |
128 | 1604 int result; |
1605 if(mod!=0x120) | |
1606 result=GetProcAddress(mod, name); | |
1607 else | |
1608 result=LookupExternalByName("kernel32.dll", name); | |
1609 dbgprintf("GetProcAddress(0x%x, '%s') => 0x%x\n", mod, name, result); | |
1610 return result; | |
1 | 1611 } |
1612 | |
1613 long WINAPI expCreateFileMappingA(int hFile, void* lpAttr, | |
1614 long flProtect, long dwMaxHigh, long dwMaxLow, const char* name) | |
1615 { | |
128 | 1616 long result=CreateFileMappingA(hFile, lpAttr, flProtect, dwMaxHigh, dwMaxLow, name); |
1617 if(!name) | |
1618 dbgprintf("CreateFileMappingA(file 0x%x, lpAttr 0x%x, | |
1619 flProtect 0x%x, dwMaxHigh 0x%x, dwMaxLow 0x%x, name 0) => %d\n", | |
1620 hFile, lpAttr, flProtect, dwMaxHigh, dwMaxLow, result); | |
1621 else | |
1622 dbgprintf("CreateFileMappingA(file 0x%x, lpAttr 0x%x, | |
1623 flProtect 0x%x, dwMaxHigh 0x%x, dwMaxLow 0x%x, name 0x%x='%s') => %d\n", | |
1624 hFile, lpAttr, flProtect, dwMaxHigh, dwMaxLow, name, name, result); | |
1625 return result; | |
1 | 1626 } |
1627 | |
1628 long WINAPI expOpenFileMappingA(long hFile, long hz, const char* name) | |
1629 { | |
128 | 1630 long result=OpenFileMappingA(hFile, hz, name); |
1631 if(!name) | |
1632 dbgprintf("OpenFileMappingA(0x%x, 0x%x, 0) => %d\n", | |
1633 hFile, hz, result); | |
1634 else | |
1635 dbgprintf("OpenFileMappingA(0x%x, 0x%x, 0x%x='%s') => %d\n", | |
1636 hFile, hz, name, name, result); | |
1637 return result; | |
1 | 1638 } |
1639 | |
1640 void* WINAPI expMapViewOfFile(HANDLE file, DWORD mode, DWORD offHigh, DWORD offLow, DWORD size) | |
1641 { | |
128 | 1642 dbgprintf("MapViewOfFile(0x%x, 0x%x, 0x%x, 0x%x, size %d) => 0x%x\n", |
1643 file,mode,offHigh,offLow,size,(char*)file+offLow); | |
1 | 1644 return (char*)file+offLow; |
1645 } | |
1646 | |
1647 void* WINAPI expUnmapViewOfFile(void* view) | |
1648 { | |
128 | 1649 dbgprintf("UnmapViewOfFile(0x%x) => 0\n", view); |
1 | 1650 return 0; |
1651 } | |
1652 | |
1653 void* WINAPI expSleep(int time) | |
1654 { | |
128 | 1655 dbgprintf("Sleep(%d) => 0\n", time); |
1 | 1656 usleep(time); |
1657 return 0; | |
1658 } | |
1659 // why does IV32 codec want to call this? I don't know ... | |
1660 void* WINAPI expCreateCompatibleDC(int hdc) | |
1661 { | |
128 | 1662 dbgprintf("CreateCompatibleDC(%d) => 0x81\n", hdc); |
1663 return (void*)0x81; | |
1 | 1664 } |
1665 | |
1666 int WINAPI expGetDeviceCaps(int hdc, int unk) | |
1667 { | |
128 | 1668 dbgprintf("GetDeviceCaps(0x%x, %d) => 0\n", hdc, unk); |
1 | 1669 return 0; |
1670 } | |
1671 | |
1672 WIN_BOOL WINAPI expDeleteDC(int hdc) | |
1673 { | |
128 | 1674 dbgprintf("DeleteDC(0x%x) => 0\n", hdc); |
1 | 1675 return 0; |
1676 } | |
1677 | |
1678 int expwsprintfA(char* string, char* format, ...) | |
1679 { | |
1680 va_list va; | |
128 | 1681 int result; |
1 | 1682 va_start(va, format); |
128 | 1683 result=vsprintf(string, format, va); |
1684 dbgprintf("wsprintfA(0x%x, '%s', ...) => %d\n", string, format, result); | |
1685 va_end(va); | |
1686 return result; | |
1 | 1687 } |
1688 | |
1689 int WINAPI expGetPrivateProfileIntA(const char* appname, const char* keyname, int default_value, const char* filename) | |
1690 { | |
1691 int size=255; | |
1692 char buffer[256]; | |
1693 char* fullname; | |
1694 int result; | |
1695 | |
1696 buffer[255]=0; | |
128 | 1697 if(!(appname && keyname && filename) ) |
1698 { | |
1699 dbgprintf("GetPrivateProfileIntA('%s', '%s', %d, '%s') => %d\n", appname, keyname, default_value, filename, default_value ); | |
1700 return default_value; | |
1701 } | |
1 | 1702 fullname=(char*)malloc(50+strlen(appname)+strlen(keyname)+strlen(filename)); |
1703 strcpy(fullname, "Software\\IniFileMapping\\"); | |
1704 strcat(fullname, appname); | |
1705 strcat(fullname, "\\"); | |
1706 strcat(fullname, keyname); | |
1707 strcat(fullname, "\\"); | |
1708 strcat(fullname, filename); | |
1709 result=RegQueryValueExA(HKEY_LOCAL_MACHINE, fullname, NULL, NULL, (int*)buffer, &size); | |
1710 if((size>=0)&&(size<256)) | |
1711 buffer[size]=0; | |
1712 // printf("GetPrivateProfileIntA(%s, %s, %s) -> %s\n", appname, keyname, filename, buffer); | |
1713 free(fullname); | |
1714 if(result) | |
128 | 1715 result=default_value; |
1 | 1716 else |
128 | 1717 result=atoi(buffer); |
1718 dbgprintf("GetPrivateProfileIntA('%s', '%s', %d, '%s') => %d\n", appname, keyname, default_value, filename, result); | |
1719 return result; | |
1 | 1720 } |
128 | 1721 int WINAPI expGetProfileIntA(const char* appname, const char* keyname, int default_value) |
1722 { | |
1723 dbgprintf("GetProfileIntA -> "); | |
1724 // dbgprintf("GetProfileIntA(%s, %s, %d)\n", appname, keyname, default_value); | |
1725 return expGetPrivateProfileIntA(appname, keyname, default_value, "default"); | |
1726 } | |
1727 | |
1 | 1728 int WINAPI expGetPrivateProfileStringA(const char* appname, const char* keyname, |
1729 const char* def_val, char* dest, unsigned int len, const char* filename) | |
1730 { | |
1731 int result; | |
1732 int size; | |
1733 char* fullname; | |
128 | 1734 dbgprintf("GetPrivateProfileStringA('%s', '%s', def_val '%s', 0x%x, 0x%x, '%s')", appname, keyname, def_val, dest, len, filename ); |
1 | 1735 if(!(appname && keyname && filename) ) return 0; |
1736 fullname=(char*)malloc(50+strlen(appname)+strlen(keyname)+strlen(filename)); | |
1737 strcpy(fullname, "Software\\IniFileMapping\\"); | |
1738 strcat(fullname, appname); | |
1739 strcat(fullname, "\\"); | |
1740 strcat(fullname, keyname); | |
1741 strcat(fullname, "\\"); | |
1742 strcat(fullname, filename); | |
1743 size=len; | |
1744 result=RegQueryValueExA(HKEY_LOCAL_MACHINE, fullname, NULL, NULL, (int*)dest, &size); | |
1745 // printf("GetPrivateProfileStringA(%s, %s, %s, %X, %X, %s)\n", appname, keyname, def_val, dest, len, filename ); | |
1746 free(fullname); | |
128 | 1747 if(result) |
1748 { | |
1749 strncpy(dest, def_val, size); | |
1750 if (strlen(def_val)< size) size = strlen(def_val); | |
1751 } | |
1752 dbgprintf(" => %d ( '%s' )\n", size, dest); | |
1 | 1753 return size; |
1754 } | |
1755 int WINAPI expWritePrivateProfileStringA(const char* appname, const char* keyname, | |
1756 const char* string, const char* filename) | |
1757 { | |
1758 int size=256; | |
1759 char* fullname; | |
128 | 1760 dbgprintf("WritePrivateProfileStringA('%s', '%s', '%s', '%s')", appname, keyname, string, filename ); |
1761 if(!(appname && keyname && filename) ) | |
1762 { | |
1763 dbgprintf(" => -1\n"); | |
1764 return -1; | |
1765 } | |
1 | 1766 fullname=(char*)malloc(50+strlen(appname)+strlen(keyname)+strlen(filename)); |
1767 strcpy(fullname, "Software\\IniFileMapping\\"); | |
1768 strcat(fullname, appname); | |
1769 strcat(fullname, "\\"); | |
1770 strcat(fullname, keyname); | |
1771 strcat(fullname, "\\"); | |
1772 strcat(fullname, filename); | |
1773 RegSetValueExA(HKEY_LOCAL_MACHINE, fullname, 0, REG_SZ, (int*)string, strlen(string)); | |
1774 // printf("RegSetValueExA(%s,%d)\n", string, strlen(string)); | |
1775 // printf("WritePrivateProfileStringA(%s, %s, %s, %s)\n", appname, keyname, string, filename ); | |
1776 free(fullname); | |
128 | 1777 dbgprintf(" => 0\n"); |
1 | 1778 return 0; |
1779 } | |
1780 | |
1781 unsigned int _GetPrivateProfileIntA(const char* appname, const char* keyname, INT default_value, const char* filename) | |
1782 { | |
1783 return expGetPrivateProfileIntA(appname, keyname, default_value, filename); | |
1784 } | |
1785 int _GetPrivateProfileStringA(const char* appname, const char* keyname, | |
1786 const char* def_val, char* dest, unsigned int len, const char* filename) | |
1787 { | |
1788 return expGetPrivateProfileStringA(appname, keyname, def_val, dest, len, filename); | |
1789 } | |
1790 int _WritePrivateProfileStringA(const char* appname, const char* keyname, | |
1791 const char* string, const char* filename) | |
1792 { | |
1793 return expWritePrivateProfileStringA(appname, keyname, string, filename); | |
1794 } | |
1795 | |
1796 | |
128 | 1797 |
1 | 1798 int WINAPI expDefDriverProc(int _private, int id, int msg, int arg1, int arg2) |
1799 { | |
128 | 1800 dbgprintf("DefDriverProc(0x%x, 0x%x, 0x%x, 0x%x, 0x%x) => 0\n", _private, id, msg, arg1, arg2); |
1 | 1801 return 0; |
1802 } | |
1803 | |
1804 int WINAPI expSizeofResource(int v1, int v2) | |
1805 { | |
128 | 1806 int result=SizeofResource(v1, v2); |
1807 dbgprintf("SizeofResource(0x%x, 0x%x) => %d\n", v1, v2, result); | |
1808 return result; | |
1 | 1809 } |
1810 | |
1811 int WINAPI expGetLastError() | |
1812 { | |
128 | 1813 int result=GetLastError(); |
1814 dbgprintf("GetLastError() => 0x%x\n", result); | |
1815 return result; | |
1 | 1816 } |
1817 | |
1818 void WINAPI expSetLastError(int error) | |
1819 { | |
128 | 1820 dbgprintf("SetLastError(0x%x)\n", error); |
1 | 1821 SetLastError(error); |
1822 } | |
1823 | |
1824 char* expstrrchr(char* string, int value) | |
1825 { | |
128 | 1826 char* result=strrchr(string, value); |
1827 if(result) | |
1828 dbgprintf("strrchr(0x%x='%s', %d) => 0x%x='%s'", string, string, value, result, result); | |
1829 else | |
1830 dbgprintf("strrchr(0x%x='%s', %d) => 0", string, string, value); | |
1831 return result; | |
1 | 1832 } |
1833 | |
1834 char* expstrchr(char* string, int value) | |
1835 { | |
128 | 1836 char* result=strchr(string, value); |
1837 if(result) | |
1838 dbgprintf("strchr(0x%x='%s', %d) => 0x%x='%s'", string, string, value, result, result); | |
1839 else | |
1840 dbgprintf("strchr(0x%x='%s', %d) => 0", string, string, value); | |
1841 return result; | |
1 | 1842 } |
128 | 1843 int expstrlen(char* str) |
1844 { | |
1845 int result=strlen(str); | |
1846 dbgprintf("strlen(0x%x='%s') => %d\n", str, str, result); | |
1847 return result; | |
1848 } | |
1849 int expstrcpy(char* str1, const char* str2) | |
1850 { | |
1851 int result=strcpy(str1, str2); | |
1852 dbgprintf("strcpy(0x%x, 0x%x='%s') => %d\n", str1, str2, str2, result); | |
1853 return result; | |
1854 } | |
1855 int expstrcmp(const char* str1, const char* str2) | |
1856 { | |
1857 int result=strcmp(str1, str2); | |
1858 dbgprintf("strcmp(0x%x='%s', 0x%x='%s') => %d\n", str1, str1, str2, str2, result); | |
1859 return result; | |
1860 } | |
1861 int expstrcat(char* str1, const char* str2) | |
1862 { | |
1863 int result=strcat(str1, str2); | |
1864 dbgprintf("strcat(0x%x='%s', 0x%x='%s') => %d\n", str1, str1, str2, str2, result); | |
1865 return result; | |
1866 } | |
1867 int expmemmove(void* dest, void* src, int n) | |
1868 { | |
1869 int result=memmove(dest, src, n); | |
1870 dbgprintf("memmove(0x%x, 0x%x, %d) => %d\n", dest, src, n, result); | |
1871 return memmove; | |
1872 } | |
1873 int expmemcmp(void* dest, void* src, int n) | |
1874 { | |
1875 int result=memcmp(dest, src, n); | |
1876 dbgprintf("memcmp(0x%x, 0x%x, %d) => %d\n", dest, src, n, result); | |
1877 return result; | |
1878 } | |
130 | 1879 int expmemcpy(void* dest, void* src, int n) |
1880 { | |
1881 int result=memcpy(dest, src, n); | |
1882 dbgprintf("memcpy(0x%x, 0x%x, %d) => %x\n", dest, src, n, result); | |
1883 return result; | |
1884 } | |
128 | 1885 time_t exptime(time_t* t) |
1886 { | |
1887 time_t result=time(t); | |
1888 dbgprintf("time(0x%x) => %d\n", t, result); | |
1889 return result; | |
1890 } | |
1891 | |
1892 int WINAPI expStringFromGUID2(GUID* guid, char* str, int cbMax) | |
1893 { | |
1894 int result=snprintf(str, cbMax, "%.8x-%.4x-%.4x-%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x", | |
1895 guid->f1, guid->f2, guid->f3, | |
1896 (unsigned char)guid->f4[0], (unsigned char)guid->f4[1], (unsigned char)guid->f4[2], (unsigned char)guid->f4[3], | |
1897 (unsigned char)guid->f4[4], (unsigned char)guid->f4[5], (unsigned char)guid->f4[6], (unsigned char)guid->f4[7]); | |
1898 dbgprintf("StringFromGUID2(0x%x, 0x%x='%s', %d) => %d\n", guid, str, str, cbMax, result); | |
1899 return result; | |
1900 } | |
1901 | |
1 | 1902 |
1903 int WINAPI expGetFileVersionInfoSizeA(const char* name, int* lpHandle) | |
1904 { | |
128 | 1905 dbgprintf("GetFileVersionInfoSizeA(0x%x='%s', 0x%X) => 0\n", name, name, lpHandle); |
1 | 1906 return 0; |
1907 } | |
1908 | |
1909 int WINAPI expIsBadStringPtrW(const short* string, int nchars) | |
1910 { | |
128 | 1911 int result; |
1912 if(string==0)result=1; else result=0; | |
1913 dbgprintf("IsBadStringPtrW(0x%x, %d) => %d", string, nchars, result); | |
1914 if(string)wch_print(string); | |
1915 return result; | |
1 | 1916 } |
1917 extern long WINAPI InterlockedExchangeAdd( long* dest, long incr ) | |
1918 { | |
1919 long ret; | |
1920 __asm__ __volatile__( "lock; xaddl %0,(%1)" | |
1921 : "=r" (ret) : "r" (dest), "0" (incr) : "memory" ); | |
1922 return ret; | |
1923 } | |
1924 | |
1925 extern long WINAPI expInterlockedIncrement( long* dest ) | |
1926 { | |
128 | 1927 long result=InterlockedExchangeAdd( dest, 1 ) + 1; |
1928 dbgprintf("InterlockedIncrement(0x%x => %d) => %d\n", dest, *dest, result); | |
1929 return result; | |
1 | 1930 } |
1931 extern long WINAPI expInterlockedDecrement( long* dest ) | |
1932 { | |
128 | 1933 long result=InterlockedExchangeAdd( dest, -1 ) - 1; |
1934 dbgprintf("InterlockedDecrement(0x%x => %d) => %d\n", dest, *dest, result); | |
1935 return result; | |
1 | 1936 } |
1937 | |
1938 extern void WINAPI expOutputDebugStringA( const char* string ) | |
1939 { | |
128 | 1940 dbgprintf("OutputDebugStringA(0x%x='%s')\n", string); |
1 | 1941 fprintf(stderr, "DEBUG: %s\n", string); |
1942 } | |
1943 | |
1944 int WINAPI expGetDC(int hwnd) | |
1945 { | |
128 | 1946 dbgprintf("GetDC(0x%x) => 0\n", hwnd); |
1 | 1947 return 0; |
1948 } | |
1949 | |
1950 int WINAPI expGetDesktopWindow() | |
1951 { | |
128 | 1952 dbgprintf("GetDesktopWindow() => 0\n"); |
1 | 1953 return 0; |
1954 } | |
1955 | |
1956 int WINAPI expReleaseDC(int hwnd, int hdc) | |
1957 { | |
128 | 1958 dbgprintf("ReleaseDC(0x%x, 0x%x) => 0\n", hwnd, hdc); |
1959 return 0; | |
1960 } | |
1961 static int cursor[100]; | |
1962 | |
1963 int WINAPI expLoadCursorA(int handle,LPCSTR name) | |
1964 { | |
1965 dbgprintf("LoadCursorA(%d, 0x%x='%s') => 0x%x\n", handle, name, (int)&cursor[0]); | |
1966 return (int)&cursor[0]; | |
1967 } | |
1968 int WINAPI expSetCursor(void *cursor) | |
1969 { | |
1970 dbgprintf("SetCursor(0x%x) => 0x%x\n", cursor, cursor); | |
1971 return (int)cursor; | |
1972 } | |
1973 int WINAPI expGetSystemPaletteEntries(int hdc, int iStartIndex, int nEntries, void* lppe) | |
1974 { | |
1975 dbgprintf("GetSystemPaletteEntries(0x%x, 0x%x, 0x%x, 0x%x) => 0\n", | |
1976 hdc, iStartIndex, nEntries, lppe); | |
1 | 1977 return 0; |
1978 } | |
1979 | |
1980 /* | |
1981 typedef struct _TIME_ZONE_INFORMATION { | |
1982 long Bias; | |
1983 char StandardName[32]; | |
1984 SYSTEMTIME StandardDate; | |
1985 long StandardBias; | |
1986 char DaylightName[32]; | |
1987 SYSTEMTIME DaylightDate; | |
1988 long DaylightBias; | |
1989 } TIME_ZONE_INFORMATION, *LPTIME_ZONE_INFORMATION; | |
1990 */ | |
1991 | |
1992 int WINAPI expGetTimeZoneInformation(LPTIME_ZONE_INFORMATION lpTimeZoneInformation) | |
1993 { | |
128 | 1994 const short name[]={'C', 'e', 'n', 't', 'r', 'a', 'l', ' ', 'S', 't', 'a', |
1995 'n', 'd', 'a', 'r', 'd', ' ', 'T', 'i', 'm', 'e', 0}; | |
1996 const short pname[]={'C', 'e', 'n', 't', 'r', 'a', 'l', ' ', 'D', 'a', 'y', | |
1997 'l', 'i', 'g', 'h', 't', ' ', 'T', 'i', 'm', 'e', 0}; | |
1998 dbgprintf("GetTimeZoneInformation(0x%x) => TIME_ZONE_ID_STANDARD\n"); | |
1 | 1999 memset(lpTimeZoneInformation, 0, sizeof(TIME_ZONE_INFORMATION)); |
128 | 2000 lpTimeZoneInformation->Bias=360;//GMT-6 |
2001 memcpy(lpTimeZoneInformation->StandardName, name, sizeof(name)); | |
2002 lpTimeZoneInformation->StandardDate.wMonth=10; | |
2003 lpTimeZoneInformation->StandardDate.wDay=5; | |
2004 lpTimeZoneInformation->StandardDate.wHour=2; | |
2005 lpTimeZoneInformation->StandardBias=0; | |
2006 memcpy(lpTimeZoneInformation->DaylightName, pname, sizeof(pname)); | |
2007 lpTimeZoneInformation->DaylightDate.wMonth=4; | |
2008 lpTimeZoneInformation->DaylightDate.wDay=1; | |
2009 lpTimeZoneInformation->DaylightDate.wHour=2; | |
2010 lpTimeZoneInformation->DaylightBias=-60; | |
2011 return TIME_ZONE_ID_STANDARD; | |
1 | 2012 } |
2013 | |
2014 void WINAPI expGetLocalTime(SYSTEMTIME* systime) | |
2015 { | |
2016 time_t local_time; | |
2017 struct tm *local_tm; | |
2018 struct timeval tv; | |
2019 | |
128 | 2020 dbgprintf("GetLocalTime(0x%x)\n"); |
1 | 2021 gettimeofday(&tv, NULL); |
2022 local_time=tv.tv_sec; | |
2023 local_tm=localtime(&local_time); | |
2024 | |
2025 systime->wYear = local_tm->tm_year + 1900; | |
2026 systime->wMonth = local_tm->tm_mon + 1; | |
2027 systime->wDayOfWeek = local_tm->tm_wday; | |
2028 systime->wDay = local_tm->tm_mday; | |
2029 systime->wHour = local_tm->tm_hour; | |
2030 systime->wMinute = local_tm->tm_min; | |
2031 systime->wSecond = local_tm->tm_sec; | |
2032 systime->wMilliseconds = (tv.tv_usec / 1000) % 1000; | |
128 | 2033 dbgprintf(" Year: %d\n Month: %d\n Day of week: %d\n" |
2034 " Day: %d\n Hour: %d\n Minute: %d\n Second: %d\n" | |
2035 " Milliseconds: %d\n", | |
2036 systime->wYear, systime->wMonth, systime->wDayOfWeek, systime->wDay, | |
2037 systime->wHour, systime->wMinute, systime->wSecond, systime->wMilliseconds); | |
1 | 2038 } |
2039 | |
2040 int WINAPI expGetSystemTime(SYSTEMTIME* systime) | |
2041 { | |
2042 time_t local_time; | |
2043 struct tm *local_tm; | |
2044 struct timeval tv; | |
2045 | |
128 | 2046 dbgprintf("GetSystemTime(0x%x)\n", systime); |
1 | 2047 gettimeofday(&tv, NULL); |
2048 local_time=tv.tv_sec; | |
2049 local_tm=gmtime(&local_time); | |
2050 | |
2051 systime->wYear = local_tm->tm_year + 1900; | |
2052 systime->wMonth = local_tm->tm_mon + 1; | |
2053 systime->wDayOfWeek = local_tm->tm_wday; | |
2054 systime->wDay = local_tm->tm_mday; | |
2055 systime->wHour = local_tm->tm_hour; | |
2056 systime->wMinute = local_tm->tm_min; | |
2057 systime->wSecond = local_tm->tm_sec; | |
2058 systime->wMilliseconds = (tv.tv_usec / 1000) % 1000; | |
128 | 2059 dbgprintf(" Year: %d\n Month: %d\n Day of week: %d\n" |
2060 " Day: %d\n Hour: %d\n Minute: %d\n Second: %d\n" | |
2061 " Milliseconds: %d\n", | |
2062 systime->wYear, systime->wMonth, systime->wDayOfWeek, systime->wDay, | |
2063 systime->wHour, systime->wMinute, systime->wSecond, systime->wMilliseconds); | |
1 | 2064 } |
2065 | |
2066 int WINAPI expGetEnvironmentVariableA(const char* name, char* field, int size) | |
2067 { | |
128 | 2068 char *p; |
2069 // printf("%s %x %x\n", name, field, size); | |
1 | 2070 if(field)field[0]=0; |
128 | 2071 /* |
2072 p = getenv(name); | |
2073 if (p) strncpy(field,p,size); | |
2074 */ | |
2075 if (strcmp(name,"__MSVCRT_HEAP_SELECT")==0) | |
2076 strcpy(field,"__GLOBAL_HEAP_SELECTED,1"); | |
2077 dbgprintf("GetEnvironmentVariableA(0x%x='%s', 0x%x, %d) => %d\n", name, name, field, size, strlen(field)); | |
2078 return strlen(field); | |
2079 } | |
2080 | |
2081 void* WINAPI expCoTaskMemAlloc(ULONG cb) | |
2082 { | |
2083 return my_mreq(cb, 0); | |
2084 } | |
2085 void WINAPI expCoTaskMemFree(void* cb) | |
2086 { | |
2087 my_release(cb); | |
2088 } | |
2089 | |
2090 void* CoTaskMemAlloc(ULONG cb){return expCoTaskMemAlloc(cb);} | |
2091 void CoTaskMemFree(void* cb){expCoTaskMemFree(cb);} | |
2092 | |
2093 struct COM_OBJECT_INFO | |
2094 { | |
2095 GUID clsid; | |
2096 long (*GetClassObject) (GUID* clsid, GUID* iid, void** ppv); | |
2097 }; | |
2098 | |
2099 static struct COM_OBJECT_INFO* com_object_table=0; | |
2100 static int com_object_size=0; | |
2101 int RegisterComClass(GUID* clsid, GETCLASSOBJECT gcs) | |
2102 { | |
2103 if(!clsid)return -1; | |
2104 if(!gcs)return -1; | |
2105 com_object_table=realloc(com_object_table, sizeof(struct COM_OBJECT_INFO)*(++com_object_size)); | |
2106 com_object_table[com_object_size-1].clsid=*clsid; | |
2107 com_object_table[com_object_size-1].GetClassObject=gcs; | |
2108 return 0; | |
2109 } | |
2110 | |
2111 GUID IID_IUnknown={0x00000000, 0x0000, 0x0000, | |
2112 {0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}}; | |
2113 GUID IID_IClassFactory={0x00000001, 0x0000, 0x0000, | |
2114 {0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}}; | |
2115 | |
2116 long WINAPI expCoCreateInstance(GUID* rclsid, struct IUnknown* pUnkOuter, | |
2117 long dwClsContext, GUID* riid, void** ppv) | |
2118 { | |
2119 int i; | |
2120 struct COM_OBJECT_INFO* ci=0; | |
2121 for(i=0; i<com_object_size; i++) | |
2122 if(!memcmp(rclsid, &com_object_table[i].clsid, sizeof(GUID))) | |
2123 ci=&com_object_table[i]; | |
2124 if(!ci)return 0x80040154; | |
2125 // in 'real' world we should mess with IClassFactory here | |
2126 i=ci->GetClassObject(rclsid, riid, ppv); | |
2127 return i; | |
2128 } | |
2129 | |
2130 long CoCreateInstance(GUID* rclsid, struct IUnknown* pUnkOuter, | |
2131 long dwClsContext, GUID* riid, void** ppv) | |
2132 { | |
2133 return expCoCreateInstance(rclsid, pUnkOuter, dwClsContext, riid, ppv); | |
2134 } | |
2135 | |
2136 int WINAPI | |
2137 expIsRectEmpty( | |
2138 CONST RECT *lprc) | |
2139 { | |
2140 dbgprintf("IsRectEmpty(0x%x)"); | |
2141 if((!lprc) || (lprc->right==lprc->left) || (lprc->top==lprc->bottom)) | |
2142 { | |
2143 dbgprintf(" => TRUE\n"); | |
2144 return TRUE; | |
2145 } | |
2146 dbgprintf(" => FALSE\n"); | |
2147 return FALSE; | |
2148 } | |
2149 | |
2150 int _adjust_fdiv=0; //what's this? | |
2151 | |
2152 | |
2153 | |
2154 | |
2155 unsigned int WINAPI expGetTempPathA(unsigned int len, char* path) | |
2156 { | |
2157 dbgprintf("GetTempPathA(%d, 0x%x)", len, path); | |
2158 if(len<5) | |
2159 { | |
2160 dbgprintf(" => 0\n"); | |
2161 return 0; | |
2162 } | |
2163 strcpy(path, "/tmp"); | |
2164 dbgprintf(" => 5 ( '/tmp' )\n"); | |
2165 return 5; | |
2166 } | |
2167 /* | |
2168 FYI: | |
2169 typedef struct | |
2170 { | |
2171 DWORD dwFileAttributes; | |
2172 FILETIME ftCreationTime; | |
2173 FILETIME ftLastAccessTime; | |
2174 FILETIME ftLastWriteTime; | |
2175 DWORD nFileSizeHigh; | |
2176 DWORD nFileSizeLow; | |
2177 DWORD dwReserved0; | |
2178 DWORD dwReserved1; | |
2179 CHAR cFileName[260]; | |
2180 CHAR cAlternateFileName[14]; | |
2181 } WIN32_FIND_DATAA, *LPWIN32_FIND_DATAA; | |
2182 */ | |
2183 | |
2184 HANDLE WINAPI expFindFirstFileA(LPCSTR s, LPWIN32_FIND_DATAA lpfd) | |
2185 { | |
2186 dbgprintf("FindFirstFileA(0x%x='%s', 0x%x) => 0\n", s, s, lpfd); | |
2187 strcpy(lpfd->cFileName, "msms001.vwp"); | |
2188 strcpy(lpfd->cAlternateFileName, "msms001.vwp"); | |
2189 return (HANDLE)0; | |
2190 } | |
2191 WIN_BOOL WINAPI expFindNextFileA(HANDLE h,LPWIN32_FIND_DATAA p) | |
2192 { | |
2193 dbgprintf("FindNextFileA(0x%x, 0x%x) => 0\n", h, p); | |
1 | 2194 return 0; |
2195 } | |
128 | 2196 WIN_BOOL WINAPI expFindClose(HANDLE h) |
2197 { | |
2198 dbgprintf("FindClose(0x%x) => 0\n", h); | |
2199 return 0; | |
2200 } | |
2201 UINT WINAPI expSetErrorMode(UINT i) | |
2202 { | |
2203 dbgprintf("SetErrorMode(%d) => 0\n", i); | |
2204 return 0; | |
2205 } | |
2206 UINT WINAPI expGetWindowsDirectoryA(LPSTR s,UINT c) | |
2207 { | |
2208 char windir[]="c:\\windows"; | |
2209 int result; | |
2210 strncpy(s, windir, c); | |
2211 result=1+((c<strlen(windir))?c:strlen(windir)); | |
2212 dbgprintf("GetWindowsDirectoryA(0x%x, %d) => %d\n", s, c, result); | |
2213 return result; | |
2214 } | |
2215 | |
2216 WIN_BOOL WINAPI expDeleteFileA(LPCSTR s) | |
2217 { | |
2218 dbgprintf("DeleteFileA(0x%x='%s') => 0\n", s, s); | |
2219 return 0; | |
2220 } | |
2221 WIN_BOOL WINAPI expFileTimeToLocalFileTime(const FILETIME* cpf, LPFILETIME pf) | |
2222 { | |
2223 dbgprintf("FileTimeToLocalFileTime(0x%x, 0x%x) => 0\n", cpf, pf); | |
2224 return 0; | |
2225 } | |
2226 | |
2227 UINT WINAPI expGetTempFileNameA(LPCSTR cs1,LPCSTR cs2,UINT i,LPSTR ps) | |
2228 { | |
2229 char mask[16]="/tmp/AP_XXXXXX"; | |
2230 int result; | |
2231 dbgprintf("GetTempFileNameA(0x%x='%s', 0x%x='%s', %d, 0x%x)", cs1, cs1, cs2, cs2, i, ps); | |
2232 if(i && i<10) | |
2233 { | |
2234 dbgprintf(" => -1\n"); | |
2235 return -1; | |
2236 } | |
2237 result=mkstemp(mask); | |
2238 sprintf(ps, "AP%d", result); | |
2239 dbgprintf(" => %d\n", strlen(ps)); | |
2240 return strlen(ps); | |
2241 } | |
2242 // | |
2243 // This func might need proper implementation if we want AngelPotion codec. | |
2244 // They try to open APmpeg4v1.apl with it. | |
2245 // DLL will close opened file with CloseHandle(). | |
2246 // | |
2247 HANDLE WINAPI expCreateFileA(LPCSTR cs1,DWORD i1,DWORD i2, | |
2248 LPSECURITY_ATTRIBUTES p1, DWORD i3,DWORD i4,HANDLE i5) | |
2249 { | |
2250 dbgprintf("CreateFileA(0x%x='%s', %d, %d, 0x%x, %d, %d, 0x%x)\n", cs1, cs1, i1, | |
2251 i2, p1, i3, i4, i5); | |
2252 if((!cs1) || (strlen(cs1)<2))return -1; | |
2253 if(strncmp(cs1, "AP", 2)) | |
2254 { | |
2255 int result; | |
2256 char* tmp=(char*)malloc(strlen(def_path)+50); | |
2257 strcpy(tmp, def_path); | |
2258 strcat(tmp, "/"); | |
2259 strcat(tmp, "APmpg4v1.apl"); | |
2260 result=open(tmp, O_RDONLY); | |
2261 free(tmp); | |
2262 return result; | |
2263 }; | |
2264 return atoi(cs1+2); | |
2265 } | |
2266 static char sysdir[]="."; | |
2267 LPCSTR WINAPI expGetSystemDirectoryA() | |
2268 { | |
2269 dbgprintf("GetSystemDirectoryA() => 0x%x='%s'\n", sysdir, sysdir); | |
2270 return sysdir; | |
2271 } | |
2272 WIN_BOOL WINAPI expReadFile(HANDLE h,LPVOID pv,DWORD size,LPDWORD rd,LPOVERLAPPED unused) | |
2273 { | |
2274 int result; | |
2275 dbgprintf("ReadFile(%d, 0x%x, %d -> 0x%x)\n", h, pv, size, rd); | |
2276 result=read(h, pv, size); | |
2277 if(rd)*rd=result; | |
2278 if(!result)return 0; | |
2279 return 1; | |
2280 } | |
2281 | |
2282 WIN_BOOL WINAPI expWriteFile(HANDLE h,LPCVOID pv,DWORD size,LPDWORD wr,LPOVERLAPPED unused) | |
2283 { | |
2284 int result; | |
2285 dbgprintf("WriteFile(%d, 0x%x, %d -> 0x%x)\n", h, pv, size, wr); | |
2286 if(h==1234)h=1; | |
2287 result=write(h, pv, size); | |
2288 if(wr)*wr=result; | |
2289 if(!result)return 0; | |
2290 return 1; | |
2291 } | |
2292 DWORD WINAPI expSetFilePointer(HANDLE h, LONG val, LPLONG ext, DWORD whence) | |
2293 { | |
2294 int wh; | |
2295 dbgprintf("SetFilePointer(%d, %d, 0x%x, %d)\n", h, val, ext, whence); | |
2296 //why would DLL want temporary file with >2Gb size? | |
2297 switch(whence) | |
2298 { | |
2299 case FILE_BEGIN: | |
2300 wh=SEEK_SET;break; | |
2301 case FILE_END: | |
2302 wh=SEEK_END;break; | |
2303 case FILE_CURRENT: | |
2304 wh=SEEK_CUR;break; | |
2305 default: | |
2306 return -1; | |
2307 } | |
2308 return lseek(h, val, wh); | |
2309 } | |
2310 | |
2311 HDRVR WINAPI expOpenDriverA(LPCSTR szDriverName, LPCSTR szSectionName, | |
2312 LPARAM lParam2) | |
2313 { | |
2314 dbgprintf("OpenDriverA(0x%x='%s', 0x%x='%s', 0x%x) => -1\n", szDriverName, szDriverName, szSectionName, szSectionName, lParam2); | |
2315 return -1; | |
2316 } | |
2317 HDRVR WINAPI expOpenDriver(LPCSTR szDriverName, LPCSTR szSectionName, | |
2318 LPARAM lParam2) | |
2319 { | |
2320 dbgprintf("OpenDriver(0x%x='%s', 0x%x='%s', 0x%x) => -1\n", szDriverName, szDriverName, szSectionName, szSectionName, lParam2); | |
2321 return -1; | |
2322 } | |
1 | 2323 |
2324 | |
128 | 2325 WIN_BOOL |
2326 WINAPI | |
2327 expGetProcessAffinityMask( | |
2328 HANDLE hProcess, | |
2329 LPDWORD lpProcessAffinityMask, | |
2330 LPDWORD lpSystemAffinityMask | |
2331 ) | |
2332 { | |
2333 dbgprintf("GetProcessAffinityMask(0x%x, 0x%x, 0x%x) => 1\n", | |
2334 hProcess, lpProcessAffinityMask, lpSystemAffinityMask); | |
2335 if(lpProcessAffinityMask)*lpProcessAffinityMask=1; | |
2336 if(lpSystemAffinityMask)*lpSystemAffinityMask=1; | |
2337 return 1; | |
1 | 2338 } |
2339 | |
2340 | |
295
c017b21a1990
added expRegEnumValueA(), fixed expWaitForSingleObject()
arpi_esp
parents:
235
diff
changeset
|
2341 /****************************************************************************** |
c017b21a1990
added expRegEnumValueA(), fixed expWaitForSingleObject()
arpi_esp
parents:
235
diff
changeset
|
2342 * RegEnumValueA [ADVAPI32.@] |
c017b21a1990
added expRegEnumValueA(), fixed expWaitForSingleObject()
arpi_esp
parents:
235
diff
changeset
|
2343 */ |
c017b21a1990
added expRegEnumValueA(), fixed expWaitForSingleObject()
arpi_esp
parents:
235
diff
changeset
|
2344 DWORD WINAPI expRegEnumValueA( HKEY hkey, DWORD index, LPSTR value, LPDWORD val_count, |
c017b21a1990
added expRegEnumValueA(), fixed expWaitForSingleObject()
arpi_esp
parents:
235
diff
changeset
|
2345 LPDWORD reserved, LPDWORD type, LPBYTE data, LPDWORD count ) |
c017b21a1990
added expRegEnumValueA(), fixed expWaitForSingleObject()
arpi_esp
parents:
235
diff
changeset
|
2346 { |
c017b21a1990
added expRegEnumValueA(), fixed expWaitForSingleObject()
arpi_esp
parents:
235
diff
changeset
|
2347 |
c017b21a1990
added expRegEnumValueA(), fixed expWaitForSingleObject()
arpi_esp
parents:
235
diff
changeset
|
2348 printf("RegEnumValueA(%x,%ld,%p,%p,%p,%p,%p,%p)\n", |
c017b21a1990
added expRegEnumValueA(), fixed expWaitForSingleObject()
arpi_esp
parents:
235
diff
changeset
|
2349 hkey, index, value, val_count, reserved, type, data, count ); |
128 | 2350 |
295
c017b21a1990
added expRegEnumValueA(), fixed expWaitForSingleObject()
arpi_esp
parents:
235
diff
changeset
|
2351 return -1; |
c017b21a1990
added expRegEnumValueA(), fixed expWaitForSingleObject()
arpi_esp
parents:
235
diff
changeset
|
2352 } |
c017b21a1990
added expRegEnumValueA(), fixed expWaitForSingleObject()
arpi_esp
parents:
235
diff
changeset
|
2353 |
128 | 2354 |
2355 | |
2356 | |
2357 | |
2358 | |
1 | 2359 struct exports |
2360 { | |
2361 char name[64]; | |
2362 int id; | |
2363 void* func; | |
2364 }; | |
2365 struct libs | |
2366 { | |
2367 char name[64]; | |
2368 int length; | |
2369 struct exports* exps; | |
2370 }; | |
2371 | |
2372 #define FF(X,Y) \ | |
2373 {#X, Y, (void*)exp##X}, | |
2374 | |
2375 struct exports exp_kernel32[]={ | |
2376 FF(IsBadWritePtr, 357) | |
2377 FF(IsBadReadPtr, 354) | |
2378 FF(IsBadStringPtrW, -1) | |
2379 FF(DisableThreadLibraryCalls, -1) | |
2380 FF(CreateThread, -1) | |
2381 FF(CreateEventA, -1) | |
2382 FF(SetEvent, -1) | |
2383 FF(ResetEvent, -1) | |
2384 FF(WaitForSingleObject, -1) | |
2385 FF(GetSystemInfo, -1) | |
2386 FF(GetVersion, 332) | |
2387 FF(HeapCreate, 461) | |
2388 FF(HeapAlloc, -1) | |
2389 FF(HeapDestroy, -1) | |
2390 FF(HeapFree, -1) | |
2391 FF(HeapSize, -1) | |
2392 FF(GetProcessHeap, -1) | |
2393 FF(VirtualAlloc, -1) | |
2394 FF(VirtualFree, -1) | |
2395 FF(InitializeCriticalSection, -1) | |
2396 FF(EnterCriticalSection, -1) | |
2397 FF(LeaveCriticalSection, -1) | |
2398 FF(DeleteCriticalSection, -1) | |
2399 FF(TlsAlloc, -1) | |
2400 FF(TlsFree, -1) | |
2401 FF(TlsGetValue, -1) | |
2402 FF(TlsSetValue, -1) | |
2403 FF(GetCurrentThreadId, -1) | |
128 | 2404 FF(GetCurrentProcess, -1) |
1 | 2405 FF(LocalAlloc, -1) |
2406 FF(LocalLock, -1) | |
2407 FF(GlobalAlloc, -1) | |
128 | 2408 FF(GlobalReAlloc, -1) |
1 | 2409 FF(GlobalLock, -1) |
2410 FF(MultiByteToWideChar, 427) | |
2411 FF(WideCharToMultiByte, -1) | |
2412 FF(GetVersionExA, -1) | |
2413 FF(CreateSemaphoreA, -1) | |
2414 FF(QueryPerformanceCounter, -1) | |
2415 FF(QueryPerformanceFrequency, -1) | |
2416 FF(LocalHandle, -1) | |
2417 FF(LocalUnlock, -1) | |
2418 FF(LocalFree, -1) | |
2419 FF(GlobalHandle, -1) | |
2420 FF(GlobalUnlock, -1) | |
2421 FF(GlobalFree, -1) | |
2422 FF(LoadResource, -1) | |
2423 FF(ReleaseSemaphore, -1) | |
2424 FF(FindResourceA, -1) | |
2425 FF(LockResource, -1) | |
2426 FF(FreeResource, -1) | |
2427 FF(SizeofResource, -1) | |
2428 FF(CloseHandle, -1) | |
2429 FF(GetCommandLineA, -1) | |
2430 FF(GetEnvironmentStringsW, -1) | |
2431 FF(FreeEnvironmentStringsW, -1) | |
128 | 2432 FF(FreeEnvironmentStringsA, -1) |
1 | 2433 FF(GetEnvironmentStrings, -1) |
2434 FF(GetStartupInfoA, -1) | |
2435 FF(GetStdHandle, -1) | |
2436 FF(GetFileType, -1) | |
2437 FF(SetHandleCount, -1) | |
2438 FF(GetACP, -1) | |
2439 FF(GetModuleFileNameA, -1) | |
2440 FF(SetUnhandledExceptionFilter, -1) | |
2441 FF(LoadLibraryA, -1) | |
2442 FF(GetProcAddress, -1) | |
2443 FF(FreeLibrary, -1) | |
2444 FF(CreateFileMappingA, -1) | |
2445 FF(OpenFileMappingA, -1) | |
2446 FF(MapViewOfFile, -1) | |
2447 FF(UnmapViewOfFile, -1) | |
2448 FF(Sleep, -1) | |
2449 FF(GetModuleHandleA, -1) | |
128 | 2450 FF(GetProfileIntA, -1) |
1 | 2451 FF(GetPrivateProfileIntA, -1) |
2452 FF(GetPrivateProfileStringA, -1) | |
2453 FF(WritePrivateProfileStringA, -1) | |
2454 FF(GetLastError, -1) | |
2455 FF(SetLastError, -1) | |
2456 FF(InterlockedIncrement, -1) | |
2457 FF(InterlockedDecrement, -1) | |
2458 FF(GetTimeZoneInformation, -1) | |
2459 FF(OutputDebugStringA, -1) | |
2460 FF(GetLocalTime, -1) | |
2461 FF(GetSystemTime, -1) | |
2462 FF(GetEnvironmentVariableA, -1) | |
121 | 2463 FF(RtlZeroMemory,-1) |
2464 FF(RtlMoveMemory,-1) | |
2465 FF(RtlFillMemory,-1) | |
128 | 2466 FF(GetTempPathA,-1) |
2467 FF(FindFirstFileA,-1) | |
2468 FF(FindNextFileA,-1) | |
2469 FF(FindClose,-1) | |
2470 FF(FileTimeToLocalFileTime,-1) | |
2471 FF(DeleteFileA,-1) | |
2472 FF(ReadFile,-1) | |
2473 FF(WriteFile,-1) | |
2474 FF(SetFilePointer,-1) | |
2475 FF(GetTempFileNameA,-1) | |
2476 FF(CreateFileA,-1) | |
2477 FF(GetSystemDirectoryA,-1) | |
2478 FF(GetWindowsDirectoryA,-1) | |
2479 FF(SetErrorMode, -1) | |
2480 FF(IsProcessorFeaturePresent, -1) | |
2481 FF(GetProcessAffinityMask, -1) | |
1 | 2482 }; |
2483 | |
2484 struct exports exp_msvcrt[]={ | |
2485 FF(malloc, -1) | |
2486 FF(_initterm, -1) | |
2487 FF(free, -1) | |
2488 {"??3@YAXPAX@Z", -1, expdelete}, | |
2489 {"??2@YAPAXI@Z", -1, expnew}, | |
128 | 2490 {"_adjust_fdiv", -1, (void*)&_adjust_fdiv}, |
1 | 2491 FF(strrchr, -1) |
2492 FF(strchr, -1) | |
128 | 2493 FF(strlen, -1) |
2494 FF(strcpy, -1) | |
2495 FF(strcmp, -1) | |
2496 FF(strcat, -1) | |
2497 FF(memmove, -1) | |
2498 FF(memcmp, -1) | |
130 | 2499 //FF(memcpy, -1) |
128 | 2500 FF(time, -1) |
1 | 2501 }; |
2502 struct exports exp_winmm[]={ | |
2503 FF(GetDriverModuleHandle, -1) | |
2504 FF(timeGetTime, -1) | |
2505 FF(DefDriverProc, -1) | |
128 | 2506 FF(OpenDriverA, -1) |
1 | 2507 FF(OpenDriver, -1) |
2508 }; | |
2509 struct exports exp_user32[]={ | |
2510 FF(LoadStringA, -1) | |
2511 FF(wsprintfA, -1) | |
2512 FF(GetDC, -1) | |
2513 FF(GetDesktopWindow, -1) | |
2514 FF(ReleaseDC, -1) | |
128 | 2515 FF(IsRectEmpty, -1) |
2516 FF(LoadCursorA,-1) | |
2517 FF(SetCursor,-1) | |
1 | 2518 }; |
2519 struct exports exp_advapi32[]={ | |
2520 FF(RegOpenKeyA, -1) | |
2521 FF(RegOpenKeyExA, -1) | |
2522 FF(RegCreateKeyExA, -1) | |
2523 FF(RegQueryValueExA, -1) | |
2524 FF(RegSetValueExA, -1) | |
2525 FF(RegCloseKey, -1) | |
295
c017b21a1990
added expRegEnumValueA(), fixed expWaitForSingleObject()
arpi_esp
parents:
235
diff
changeset
|
2526 //FF(RegEnumValueA, -1) |
1 | 2527 }; |
2528 struct exports exp_gdi32[]={ | |
2529 FF(CreateCompatibleDC, -1) | |
2530 FF(GetDeviceCaps, -1) | |
2531 FF(DeleteDC, -1) | |
2532 FF(GetSystemPaletteEntries, -1) | |
2533 }; | |
2534 struct exports exp_version[]={ | |
2535 FF(GetFileVersionInfoSizeA, -1) | |
2536 }; | |
128 | 2537 struct exports exp_ole32[]={ |
2538 FF(CoTaskMemAlloc, -1) | |
2539 FF(CoTaskMemFree, -1) | |
2540 FF(CoCreateInstance, -1) | |
2541 FF(StringFromGUID2, -1) | |
2542 }; | |
130 | 2543 struct exports exp_crtdll[]={ |
2544 FF(memcpy, -1) | |
2545 }; | |
2546 | |
1 | 2547 #define LL(X) \ |
2548 {#X".dll", sizeof(exp_##X)/sizeof(struct exports), exp_##X}, | |
2549 | |
2550 struct libs libraries[]={ | |
2551 LL(kernel32) | |
2552 LL(msvcrt) | |
2553 LL(winmm) | |
2554 LL(user32) | |
2555 LL(advapi32) | |
2556 LL(gdi32) | |
2557 LL(version) | |
128 | 2558 LL(ole32) |
130 | 2559 LL(crtdll) |
1 | 2560 }; |
2561 | |
2562 void* LookupExternal(const char* library, int ordinal) | |
2563 { | |
2564 char* answ; | |
2565 int i,j; | |
2566 if(library==0) | |
2567 { | |
2568 printf("ERROR: library=0\n"); | |
2569 return (void*)ext_unknown; | |
2570 } | |
2571 printf("External func %s:%d\n", library, ordinal); | |
2572 // printf("%x %x\n", &unk_exp1, &unk_exp2); | |
2573 | |
2574 for(i=0; i<sizeof(libraries)/sizeof(struct libs); i++) | |
2575 { | |
2576 if(strcasecmp(library, libraries[i].name)) | |
2577 continue; | |
2578 for(j=0; j<libraries[i].length; j++) | |
2579 { | |
2580 if(ordinal!=libraries[i].exps[j].id) | |
2581 continue; | |
2582 printf("Hit: 0x%08X\n", libraries[i].exps[j].func); | |
2583 return libraries[i].exps[j].func; | |
2584 } | |
2585 } | |
2586 if(pos>150)return 0; | |
2587 answ=(char*)extcode+pos*0x64; | |
2588 memcpy(answ, &unk_exp1, 0x64); | |
2589 *(int*)(answ+9)=pos; | |
2590 *(int*)(answ+47)-=((int)answ-(int)&unk_exp1); | |
2591 sprintf(export_names[pos], "%s:%d", library, ordinal); | |
2592 pos++; | |
2593 return (void*)answ; | |
2594 } | |
2595 | |
2596 void* LookupExternalByName(const char* library, const char* name) | |
2597 { | |
2598 char* answ; | |
2599 int i,j; | |
2600 // return (void*)ext_unknown; | |
2601 if(library==0) | |
2602 { | |
2603 printf("ERROR: library=0\n"); | |
2604 return (void*)ext_unknown; | |
2605 } | |
2606 if(name==0) | |
2607 { | |
2608 printf("ERROR: name=0\n"); | |
2609 return (void*)ext_unknown; | |
2610 } | |
2611 // printf("External func %s:%s\n", library, name); | |
2612 for(i=0; i<sizeof(libraries)/sizeof(struct libs); i++) | |
2613 { | |
2614 if(strcasecmp(library, libraries[i].name)) | |
2615 continue; | |
2616 for(j=0; j<libraries[i].length; j++) | |
2617 { | |
2618 if(strcmp(name, libraries[i].exps[j].name)) | |
2619 continue; | |
2620 // printf("Hit: 0x%08X\n", libraries[i].exps[j].func); | |
2621 return libraries[i].exps[j].func; | |
2622 } | |
2623 } | |
128 | 2624 // printf("%s %s\n", library, name); |
2625 if(pos>150)return 0; | |
1 | 2626 strcpy(export_names[pos], name); |
2627 answ=(char*)extcode+pos*0x64; | |
2628 memcpy(answ, &unk_exp1, 0x64); | |
2629 *(int*)(answ+9)=pos; | |
2630 *(int*)(answ+47)-=((int)answ-(int)&unk_exp1); | |
2631 pos++; | |
2632 return (void*)answ; | |
2633 // memcpy(extcode, &unk_exp1, 0x64); | |
2634 // *(int*)(extcode+52)-=((int)extcode-(int)&unk_exp1); | |
2635 // return (void*)extcode; | |
2636 // printf("Unknown func %s:%s\n", library, name); | |
2637 // return (void*)ext_unknown; | |
2638 } | |
2639 | |
128 | 2640 int my_garbagecollection() |
2641 { | |
2642 #ifdef GARBAGE | |
2643 alc_list* pp,*ppsv; | |
2644 mutex_list* pm,*pmsv; | |
2645 int unfree,unfreecnt; | |
2646 if (mlist != NULL) { | |
2647 pm=mlist; | |
2648 for(;pm;) { | |
2649 if (pm->prev) pm->prev->next=pm->next; | |
2650 if (pm->next) pm->next->prev=pm->prev; | |
2651 if (pm == mlist) mlist=pm->prev; | |
2652 if (pm->pm) { | |
2653 pthread_mutex_destroy(pm->pm); | |
2654 my_release(pm->pm); | |
2655 } | |
2656 if (pm->pc) { | |
2657 pthread_cond_destroy(pm->pc); | |
2658 my_release(pm->pc); | |
2659 } | |
2660 pmsv = pm; | |
2661 pm=pm->prev; | |
2662 my_release(pmsv); | |
2663 } | |
2664 } | |
2665 | |
2666 if (alclist==NULL) return 0; | |
2667 | |
2668 pp=alclist; | |
2669 unfree=unfreecnt=0; | |
2670 for(;pp;) { | |
2671 unfree+=pp->size; | |
2672 unfreecnt++; | |
2673 if (pp->prev) | |
2674 pp->prev->next=pp->next; | |
2675 if (pp->next) | |
2676 pp->next->prev=pp->prev; | |
2677 if (pp == alclist) | |
2678 alclist=pp->prev; | |
2679 free(pp->addr); | |
2680 ppsv = pp; | |
2681 pp=pp->prev; | |
2682 free(ppsv); | |
2683 alccnt--; | |
2684 } | |
2685 printf("Total Unfree %d bytes cnt %d [%x,%d]\n",unfree,unfreecnt,alclist,alccnt); | |
2686 #endif | |
2687 } |