Mercurial > mplayer.hg
comparison loader/win32.c @ 7386:174e2a58b4cd
avifile sync - 95% cosmetics 5% bug
author | arpi |
---|---|
date | Fri, 13 Sep 2002 19:43:17 +0000 |
parents | 1e47c2e7aa8e |
children | 05ded2e1327a |
comparison
equal
deleted
inserted
replaced
7385:e2fcdd7608b1 | 7386:174e2a58b4cd |
---|---|
185 fclose(f); | 185 fclose(f); |
186 } | 186 } |
187 va_end(va); | 187 va_end(va); |
188 } | 188 } |
189 #endif | 189 #endif |
190 #undef MPLAYER | 190 //#undef MPLAYER |
191 #ifdef MPLAYER | 191 #ifdef MPLAYER |
192 #include "../mp_msg.h" | 192 #include "../mp_msg.h" |
193 if (verbose > 2) | 193 if (verbose > 2) |
194 { | 194 { |
195 va_list va; | 195 va_list va; |
249 } | 249 } |
250 #undef MEMORY_DEBUG | 250 #undef MEMORY_DEBUG |
251 | 251 |
252 #ifdef MEMORY_DEBUG | 252 #ifdef MEMORY_DEBUG |
253 | 253 |
254 void* my_mreq(int size, int to_zero) | 254 static void* my_mreq(int size, int to_zero) |
255 { | 255 { |
256 static int test=0; | 256 static int test=0; |
257 test++; | 257 test++; |
258 if(test%10==0)printf("Memory: %d bytes allocated\n", heap_counter); | 258 if(test%10==0)printf("Memory: %d bytes allocated\n", heap_counter); |
259 // test_heap(); | 259 // test_heap(); |
282 else | 282 else |
283 memset(heap+heap_counter, 0xcc, size); // make crash reproducable | 283 memset(heap+heap_counter, 0xcc, size); // make crash reproducable |
284 heap_counter+=size; | 284 heap_counter+=size; |
285 return heap+heap_counter-size; | 285 return heap+heap_counter-size; |
286 } | 286 } |
287 int my_release(char* memory) | 287 static int my_release(char* memory) |
288 { | 288 { |
289 // test_heap(); | 289 // test_heap(); |
290 if(memory==NULL) | 290 if(memory==NULL) |
291 { | 291 { |
292 printf("ERROR: free(0)\n"); | 292 printf("ERROR: free(0)\n"); |
340 | 340 |
341 void* mreq_private(int size, int to_zero, int type); | 341 void* mreq_private(int size, int to_zero, int type); |
342 void* mreq_private(int size, int to_zero, int type) | 342 void* mreq_private(int size, int to_zero, int type) |
343 { | 343 { |
344 int nsize = size + sizeof(alloc_header); | 344 int nsize = size + sizeof(alloc_header); |
345 alloc_header* header = malloc(nsize); | 345 alloc_header* header = (alloc_header* ) malloc(nsize); |
346 if (!header) | 346 if (!header) |
347 return 0; | 347 return 0; |
348 if (to_zero) | 348 if (to_zero) |
349 memset(header, 0, nsize); | 349 memset(header, 0, nsize); |
350 #ifdef GARBAGE | 350 #ifdef GARBAGE |
371 | 371 |
372 //if (alccnt < 40000) printf("MY_REQ: %p\t%d t:%d (cnt:%d)\n", header, size, type, alccnt); | 372 //if (alccnt < 40000) printf("MY_REQ: %p\t%d t:%d (cnt:%d)\n", header, size, type, alccnt); |
373 return header + 1; | 373 return header + 1; |
374 } | 374 } |
375 | 375 |
376 int my_release(void* memory) | 376 static int my_release(void* memory) |
377 { | 377 { |
378 alloc_header* header = (alloc_header*) memory - 1; | 378 alloc_header* header = (alloc_header*) memory - 1; |
379 #ifdef GARBAGE | 379 #ifdef GARBAGE |
380 alloc_header* prevmem; | 380 alloc_header* prevmem; |
381 alloc_header* nextmem; | 381 alloc_header* nextmem; |
382 | 382 |
383 if (memory == 0) | 383 if (memory == 0) |
384 return 0; | 384 return 0; |
385 | 385 |
386 if (header->deadbeef != 0xdeadbeef) | 386 if (header->deadbeef != (long) 0xdeadbeef) |
387 { | 387 { |
388 printf("FATAL releasing corrupted memory! %p 0x%lx (%d)\n", header, header->deadbeef, alccnt); | 388 printf("FATAL releasing corrupted memory! %p 0x%lx (%d)\n", header, header->deadbeef, alccnt); |
389 return 0; | 389 return 0; |
390 } | 390 } |
391 | 391 |
438 free(header); | 438 free(header); |
439 return 0; | 439 return 0; |
440 } | 440 } |
441 #endif | 441 #endif |
442 | 442 |
443 inline void* my_mreq(int size, int to_zero) | 443 static inline void* my_mreq(int size, int to_zero) |
444 { | 444 { |
445 return mreq_private(size, to_zero, AREATYPE_CLIENT); | 445 return mreq_private(size, to_zero, AREATYPE_CLIENT); |
446 } | 446 } |
447 | 447 |
448 static /*inline*/ int my_size(void* memory) | 448 static int my_size(void* memory) |
449 { | 449 { |
450 if(!memory) return 0; | 450 if(!memory) return 0; |
451 return ((alloc_header*)memory)[-1].size; | 451 return ((alloc_header*)memory)[-1].size; |
452 } | 452 } |
453 | 453 |
538 void* lpStartAddress, void* lpParameter, | 538 void* lpStartAddress, void* lpParameter, |
539 long dwFlags, long* dwThreadId) | 539 long dwFlags, long* dwThreadId) |
540 { | 540 { |
541 pthread_t *pth; | 541 pthread_t *pth; |
542 // printf("CreateThread:"); | 542 // printf("CreateThread:"); |
543 pth=my_mreq(sizeof(pthread_t), 0); | 543 pth = (pthread_t*) my_mreq(sizeof(pthread_t), 0); |
544 pthread_create(pth, NULL, (void*(*)(void*))lpStartAddress, lpParameter); | 544 pthread_create(pth, NULL, (void*(*)(void*))lpStartAddress, lpParameter); |
545 if(dwFlags) | 545 if(dwFlags) |
546 printf( "WARNING: CreateThread flags not supported\n"); | 546 printf( "WARNING: CreateThread flags not supported\n"); |
547 if(dwThreadId) | 547 if(dwThreadId) |
548 *dwThreadId=(long)pth; | 548 *dwThreadId=(long)pth; |
785 return (void *)ret; | 785 return (void *)ret; |
786 } | 786 } |
787 | 787 |
788 static int pf_set = 0; | 788 static int pf_set = 0; |
789 static BYTE PF[64] = {0,}; | 789 static BYTE PF[64] = {0,}; |
790 | |
791 static void WINAPI expGetSystemInfo(SYSTEM_INFO* si); /* forward declaration */ | |
792 | |
793 static WIN_BOOL WINAPI expIsProcessorFeaturePresent(DWORD v) | |
794 { | |
795 WIN_BOOL result; | |
796 if(v>63)result=0; | |
797 if (!pf_set) | |
798 { | |
799 SYSTEM_INFO si; | |
800 expGetSystemInfo(&si); | |
801 } | |
802 else result=PF[v]; | |
803 dbgprintf("IsProcessorFeaturePresent(0x%x) => 0x%x\n", v, result); | |
804 return result; | |
805 } | |
806 | 790 |
807 static void DumpSystemInfo(const SYSTEM_INFO* si) | 791 static void DumpSystemInfo(const SYSTEM_INFO* si) |
808 { | 792 { |
809 dbgprintf(" Processor architecture %d\n", si->u.s.wProcessorArchitecture); | 793 dbgprintf(" Processor architecture %d\n", si->u.s.wProcessorArchitecture); |
810 dbgprintf(" Page size: %d\n", si->dwPageSize); | 794 dbgprintf(" Page size: %d\n", si->dwPageSize); |
1004 | 988 |
1005 continue; | 989 continue; |
1006 } | 990 } |
1007 if (!lstrncmpiA(line,"processor",strlen("processor"))) { | 991 if (!lstrncmpiA(line,"processor",strlen("processor"))) { |
1008 /* processor number counts up...*/ | 992 /* processor number counts up...*/ |
1009 int x; | 993 unsigned int x; |
1010 | 994 |
1011 if (sscanf(value,"%d",&x)) | 995 if (sscanf(value,"%d",&x)) |
1012 if (x+1>cachedsi.dwNumberOfProcessors) | 996 if (x+1>cachedsi.dwNumberOfProcessors) |
1013 cachedsi.dwNumberOfProcessors=x+1; | 997 cachedsi.dwNumberOfProcessors=x+1; |
1014 | 998 |
1052 cache = 1; | 1036 cache = 1; |
1053 memcpy(si,&cachedsi,sizeof(*si)); | 1037 memcpy(si,&cachedsi,sizeof(*si)); |
1054 DumpSystemInfo(si); | 1038 DumpSystemInfo(si); |
1055 } | 1039 } |
1056 | 1040 |
1041 // avoid undefined expGetSystemInfo | |
1042 static WIN_BOOL WINAPI expIsProcessorFeaturePresent(DWORD v) | |
1043 { | |
1044 WIN_BOOL result = 0; | |
1045 if (!pf_set) | |
1046 { | |
1047 SYSTEM_INFO si; | |
1048 expGetSystemInfo(&si); | |
1049 } | |
1050 if(v<64) result=PF[v]; | |
1051 dbgprintf("IsProcessorFeaturePresent(0x%x) => 0x%x\n", v, result); | |
1052 return result; | |
1053 } | |
1054 | |
1055 | |
1057 static long WINAPI expGetVersion() | 1056 static long WINAPI expGetVersion() |
1058 { | 1057 { |
1059 dbgprintf("GetVersion() => 0xC0000004\n"); | 1058 dbgprintf("GetVersion() => 0xC0000004\n"); |
1060 return 0xC0000004;//Windows 95 | 1059 return 0xC0000004;//Windows 95 |
1061 } | 1060 } |
1104 } | 1103 } |
1105 | 1104 |
1106 static long WINAPI expHeapFree(HANDLE heap, DWORD dwFlags, LPVOID lpMem) | 1105 static long WINAPI expHeapFree(HANDLE heap, DWORD dwFlags, LPVOID lpMem) |
1107 { | 1106 { |
1108 dbgprintf("HeapFree(0x%x, 0x%x, pointer 0x%x) => 1\n", heap, dwFlags, lpMem); | 1107 dbgprintf("HeapFree(0x%x, 0x%x, pointer 0x%x) => 1\n", heap, dwFlags, lpMem); |
1109 if (heapfreehack != lpMem && lpMem != (void*)0xffffffff) | 1108 if (heapfreehack != lpMem && lpMem != (void*)0xffffffff |
1109 && lpMem != (void*)0xbdbdbdbd) | |
1110 // 0xbdbdbdbd is for i263_drv.drv && libefence | |
1111 // it seems to be reading from relased memory | |
1112 // EF_PROTECT_FREE doens't show any probleme | |
1110 my_release(lpMem); | 1113 my_release(lpMem); |
1111 else | 1114 else |
1112 { | 1115 { |
1113 if (!heapfreehackshown++) | 1116 if (!heapfreehackshown++) |
1114 printf("Info: HeapFree deallocating same memory twice! (%p)\n", lpMem); | 1117 printf("Info: HeapFree deallocating same memory twice! (%p)\n", lpMem); |
1334 { | 1337 { |
1335 dbgprintf("GetCurrentProcess() => %d\n", getpid()); | 1338 dbgprintf("GetCurrentProcess() => %d\n", getpid()); |
1336 return getpid(); | 1339 return getpid(); |
1337 } | 1340 } |
1338 | 1341 |
1339 extern void* fs_seg; | 1342 #if 0 |
1340 | |
1341 #if 1 | |
1342 // this version is required for Quicktime codecs (.qtx/.qts) to work. | 1343 // this version is required for Quicktime codecs (.qtx/.qts) to work. |
1343 // (they assume some pointers at FS: segment) | 1344 // (they assume some pointers at FS: segment) |
1345 | |
1346 extern void* fs_seg; | |
1344 | 1347 |
1345 //static int tls_count; | 1348 //static int tls_count; |
1346 static int tls_use_map[64]; | 1349 static int tls_use_map[64]; |
1347 static int WINAPI expTlsAlloc() | 1350 static int WINAPI expTlsAlloc() |
1348 { | 1351 { |
1394 struct tls_s* next; | 1397 struct tls_s* next; |
1395 }; | 1398 }; |
1396 | 1399 |
1397 static void* WINAPI expTlsAlloc() | 1400 static void* WINAPI expTlsAlloc() |
1398 { | 1401 { |
1399 if(g_tls==NULL) | 1402 if (g_tls == NULL) |
1400 { | 1403 { |
1401 g_tls=my_mreq(sizeof(tls_t), 0); | 1404 g_tls=my_mreq(sizeof(tls_t), 0); |
1402 g_tls->next=g_tls->prev=NULL; | 1405 g_tls->next=g_tls->prev=NULL; |
1403 } | 1406 } |
1404 else | 1407 else |
1449 { | 1452 { |
1450 if(index->next) | 1453 if(index->next) |
1451 index->next->prev=index->prev; | 1454 index->next->prev=index->prev; |
1452 if(index->prev) | 1455 if(index->prev) |
1453 index->prev->next=index->next; | 1456 index->prev->next=index->next; |
1457 if (g_tls == index) | |
1458 g_tls = index->prev; | |
1454 my_release((void*)index); | 1459 my_release((void*)index); |
1455 result=1; | 1460 result=1; |
1456 } | 1461 } |
1457 dbgprintf("TlsFree(index 0x%x) => %d\n", index, result); | 1462 dbgprintf("TlsFree(index 0x%x) => %d\n", index, result); |
1458 return result; | 1463 return result; |
2694 systime->wYear, systime->wMonth, systime->wDayOfWeek, systime->wDay, | 2699 systime->wYear, systime->wMonth, systime->wDayOfWeek, systime->wDay, |
2695 systime->wHour, systime->wMinute, systime->wSecond, systime->wMilliseconds); | 2700 systime->wHour, systime->wMinute, systime->wSecond, systime->wMilliseconds); |
2696 return 0; | 2701 return 0; |
2697 } | 2702 } |
2698 | 2703 |
2704 #define SECS_1601_TO_1970 ((369 * 365 + 89) * 86400ULL) | |
2705 static void WINAPI expGetSystemTimeAsFileTime(FILETIME* systime) | |
2706 { | |
2707 struct tm *local_tm; | |
2708 struct timeval tv; | |
2709 unsigned long long secs; | |
2710 | |
2711 dbgprintf("GetSystemTime(0x%x)\n", systime); | |
2712 gettimeofday(&tv, NULL); | |
2713 secs = (tv.tv_sec + SECS_1601_TO_1970) * 10000000; | |
2714 secs += tv.tv_usec * 10; | |
2715 systime->dwLowDateTime = secs & 0xffffffff; | |
2716 systime->dwHighDateTime = (secs >> 32); | |
2717 } | |
2718 | |
2699 static int WINAPI expGetEnvironmentVariableA(const char* name, char* field, int size) | 2719 static int WINAPI expGetEnvironmentVariableA(const char* name, char* field, int size) |
2700 { | 2720 { |
2701 char *p; | 2721 char *p; |
2702 // printf("%s %x %x\n", name, field, size); | 2722 // printf("%s %x %x\n", name, field, size); |
2703 if(field)field[0]=0; | 2723 if(field)field[0]=0; |
2739 } | 2759 } |
2740 | 2760 |
2741 struct COM_OBJECT_INFO | 2761 struct COM_OBJECT_INFO |
2742 { | 2762 { |
2743 GUID clsid; | 2763 GUID clsid; |
2744 long (*GetClassObject) (GUID* clsid, GUID* iid, void** ppv); | 2764 long (*GetClassObject) (GUID* clsid, const GUID* iid, void** ppv); |
2745 }; | 2765 }; |
2746 | 2766 |
2747 static struct COM_OBJECT_INFO* com_object_table=0; | 2767 static struct COM_OBJECT_INFO* com_object_table=0; |
2748 static int com_object_size=0; | 2768 static int com_object_size=0; |
2749 int RegisterComClass(GUID* clsid, GETCLASSOBJECT gcs) | 2769 int RegisterComClass(const GUID* clsid, GETCLASSOBJECT gcs) |
2750 { | 2770 { |
2751 if(!clsid || !gcs) | 2771 if(!clsid || !gcs) |
2752 return -1; | 2772 return -1; |
2753 com_object_table=realloc(com_object_table, sizeof(struct COM_OBJECT_INFO)*(++com_object_size)); | 2773 com_object_table=realloc(com_object_table, sizeof(struct COM_OBJECT_INFO)*(++com_object_size)); |
2754 com_object_table[com_object_size-1].clsid=*clsid; | 2774 com_object_table[com_object_size-1].clsid=*clsid; |
2755 com_object_table[com_object_size-1].GetClassObject=gcs; | 2775 com_object_table[com_object_size-1].GetClassObject=gcs; |
2756 return 0; | 2776 return 0; |
2757 } | 2777 } |
2758 | 2778 |
2759 int UnregisterComClass(GUID* clsid, GETCLASSOBJECT gcs) | 2779 int UnregisterComClass(const GUID* clsid, GETCLASSOBJECT gcs) |
2760 { | 2780 { |
2761 int found = 0; | 2781 int found = 0; |
2762 int i = 0; | 2782 int i = 0; |
2763 if(!clsid || !gcs) | 2783 if(!clsid || !gcs) |
2764 return -1; | 2784 return -1; |
2791 } | 2811 } |
2792 return 0; | 2812 return 0; |
2793 } | 2813 } |
2794 | 2814 |
2795 | 2815 |
2796 GUID IID_IUnknown = | 2816 const GUID IID_IUnknown = |
2797 { | 2817 { |
2798 0x00000000, 0x0000, 0x0000, | 2818 0x00000000, 0x0000, 0x0000, |
2799 {0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46} | 2819 {0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46} |
2800 }; | 2820 }; |
2801 GUID IID_IClassFactory = | 2821 const GUID IID_IClassFactory = |
2802 { | 2822 { |
2803 0x00000001, 0x0000, 0x0000, | 2823 0x00000001, 0x0000, 0x0000, |
2804 {0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46} | 2824 {0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46} |
2805 }; | 2825 }; |
2806 | 2826 |
2807 static long WINAPI expCoCreateInstance(GUID* rclsid, struct IUnknown* pUnkOuter, | 2827 static long WINAPI expCoCreateInstance(GUID* rclsid, struct IUnknown* pUnkOuter, |
2808 long dwClsContext, GUID* riid, void** ppv) | 2828 long dwClsContext, const GUID* riid, void** ppv) |
2809 { | 2829 { |
2810 int i; | 2830 int i; |
2811 struct COM_OBJECT_INFO* ci=0; | 2831 struct COM_OBJECT_INFO* ci=0; |
2812 for(i=0; i<com_object_size; i++) | 2832 for(i=0; i<com_object_size; i++) |
2813 if(!memcmp(rclsid, &com_object_table[i].clsid, sizeof(GUID))) | 2833 if(!memcmp(rclsid, &com_object_table[i].clsid, sizeof(GUID))) |
2817 i=ci->GetClassObject(rclsid, riid, ppv); | 2837 i=ci->GetClassObject(rclsid, riid, ppv); |
2818 return i; | 2838 return i; |
2819 } | 2839 } |
2820 | 2840 |
2821 long CoCreateInstance(GUID* rclsid, struct IUnknown* pUnkOuter, | 2841 long CoCreateInstance(GUID* rclsid, struct IUnknown* pUnkOuter, |
2822 long dwClsContext, GUID* riid, void** ppv) | 2842 long dwClsContext, const GUID* riid, void** ppv) |
2823 { | 2843 { |
2824 return expCoCreateInstance(rclsid, pUnkOuter, dwClsContext, riid, ppv); | 2844 return expCoCreateInstance(rclsid, pUnkOuter, dwClsContext, riid, ppv); |
2825 } | 2845 } |
2826 | 2846 |
2827 static int WINAPI expIsRectEmpty(CONST RECT *lprc) | 2847 static int WINAPI expIsRectEmpty(CONST RECT *lprc) |
2828 { | 2848 { |
2829 int r = 0; | 2849 int r = 0; |
2830 // int r = (!lprc || (lprc->right == lprc->left) || (lprc->top == lprc->bottom)); | 2850 // int r = (!lprc || (lprc->right == lprc->left) || (lprc->top == lprc->bottom)); |
2831 int w,h; | 2851 int w,h; |
2832 | 2852 |
2833 if (lprc) | 2853 if (lprc) |
2834 { | 2854 { |
2835 w = lprc->right - lprc->left; | 2855 w = lprc->right - lprc->left; |
2836 h = lprc->bottom - lprc->top; | 2856 h = lprc->bottom - lprc->top; |
2837 if (w <= 0 || h <= 0) | 2857 if (w <= 0 || h <= 0) |
2986 free(tmp); | 3006 free(tmp); |
2987 return r; | 3007 return r; |
2988 } | 3008 } |
2989 | 3009 |
2990 #if 0 | 3010 #if 0 |
2991 /* we need this for some virtualdub filters */ | 3011 /* we need this for some virtualdub filters */ |
2992 { | 3012 { |
2993 int r; | 3013 int r; |
2994 int flg = 0; | 3014 int flg = 0; |
2995 if (GENERIC_READ & i1) | 3015 if (GENERIC_READ & i1) |
2996 flg |= O_RDONLY; | 3016 flg |= O_RDONLY; |
2999 flg |= O_WRONLY; | 3019 flg |= O_WRONLY; |
3000 printf("Warning: openning filename %s %d (flags; 0x%x) for write\n", cs1, r, flg); | 3020 printf("Warning: openning filename %s %d (flags; 0x%x) for write\n", cs1, r, flg); |
3001 } | 3021 } |
3002 r=open(cs1, flg); | 3022 r=open(cs1, flg); |
3003 return r; | 3023 return r; |
3004 } | 3024 } |
3005 #endif | 3025 #endif |
3006 | 3026 |
3007 return atoi(cs1+2); | 3027 return atoi(cs1+2); |
3008 } | 3028 } |
3009 static UINT WINAPI expGetSystemDirectoryA( | 3029 static UINT WINAPI expGetSystemDirectoryA( |
3047 if(!longpath) return 0; | 3067 if(!longpath) return 0; |
3048 dbgprintf("GetShortPathNameA('%s',%p,%d)\n",longpath,shortpath,shortlen); | 3068 dbgprintf("GetShortPathNameA('%s',%p,%d)\n",longpath,shortpath,shortlen); |
3049 strcpy(shortpath,longpath); | 3069 strcpy(shortpath,longpath); |
3050 return strlen(shortpath); | 3070 return strlen(shortpath); |
3051 } | 3071 } |
3052 | 3072 |
3053 static WIN_BOOL WINAPI expReadFile(HANDLE h,LPVOID pv,DWORD size,LPDWORD rd,LPOVERLAPPED unused) | 3073 static WIN_BOOL WINAPI expReadFile(HANDLE h,LPVOID pv,DWORD size,LPDWORD rd,LPOVERLAPPED unused) |
3054 { | 3074 { |
3055 int result; | 3075 int result; |
3056 dbgprintf("ReadFile(%d, 0x%x, %d -> 0x%x)\n", h, pv, size, rd); | 3076 dbgprintf("ReadFile(%d, 0x%x, %d -> 0x%x)\n", h, pv, size, rd); |
3057 result=read(h, pv, size); | 3077 result=read(h, pv, size); |
3272 { | 3292 { |
3273 dbgprintf("delete(%p)\n", memory); | 3293 dbgprintf("delete(%p)\n", memory); |
3274 my_release(memory); | 3294 my_release(memory); |
3275 return 0; | 3295 return 0; |
3276 } | 3296 } |
3277 #if 1 | 3297 #if 0 |
3278 static int exp_initterm(int v1, int v2) | 3298 static int exp_initterm(int v1, int v2) |
3279 { | 3299 { |
3280 dbgprintf("_initterm(0x%x, 0x%x) => 0\n", v1, v2); | 3300 dbgprintf("_initterm(0x%x, 0x%x) => 0\n", v1, v2); |
3281 return 0; | 3301 return 0; |
3282 } | 3302 } |
3283 #else | 3303 #else |
3284 /* merged from wine - 2002.04.21 */ | 3304 /* merged from wine - 2002.04.21 */ |
3285 typedef void (*_INITTERMFUNC)(void); | 3305 typedef void (*_INITTERMFUNC)(); |
3286 static int exp_initterm(_INITTERMFUNC *start, _INITTERMFUNC *end) | 3306 static int exp_initterm(_INITTERMFUNC *start, _INITTERMFUNC *end) |
3287 { | 3307 { |
3288 _INITTERMFUNC *current = start; | 3308 dbgprintf("_initterm(0x%x, 0x%x) %p\n", start, end, *start); |
3289 | 3309 while (start < end) |
3290 dbgprintf("_initterm(0x%x, 0x%x)\n", start, end); | 3310 { |
3291 while (current < end) | 3311 if (*start) |
3292 { | |
3293 if (*current) | |
3294 { | 3312 { |
3295 printf("call init func: %p\n", *current); | 3313 //printf("call _initfunc: from: %p %d\n", *start); |
3296 (**current)(); | 3314 // ok this trick with push/pop is necessary as otherwice |
3315 // edi/esi registers are being trashed | |
3316 void* p = *start; | |
3317 __asm__ __volatile__ | |
3318 ( | |
3319 "pushl %%ebx \n\t" | |
3320 "pushl %%ecx \n\t" | |
3321 "pushl %%edx \n\t" | |
3322 "pushl %%edi \n\t" | |
3323 "pushl %%esi \n\t" | |
3324 "call *%%eax \n\t" | |
3325 "popl %%esi \n\t" | |
3326 "popl %%edi \n\t" | |
3327 "popl %%edx \n\t" | |
3328 "popl %%ecx \n\t" | |
3329 "popl %%ebx \n\t" | |
3330 : | |
3331 : "a"(p) | |
3332 : "memory" | |
3333 ); | |
3334 //printf("done %p %d:%d\n", end); | |
3297 } | 3335 } |
3298 current++; | 3336 start++; |
3299 } | 3337 } |
3300 return 0; | 3338 return 0; |
3301 } | 3339 } |
3302 #endif | 3340 #endif |
3341 | |
3342 static void* exp__dllonexit() | |
3343 { | |
3344 // FIXME extract from WINE | |
3345 return NULL; | |
3346 } | |
3303 | 3347 |
3304 static int expwsprintfA(char* string, char* format, ...) | 3348 static int expwsprintfA(char* string, char* format, ...) |
3305 { | 3349 { |
3306 va_list va; | 3350 va_list va; |
3307 int result; | 3351 int result; |
3427 return result; | 3471 return result; |
3428 } | 3472 } |
3429 static char* exp_strdup(const char* str1) | 3473 static char* exp_strdup(const char* str1) |
3430 { | 3474 { |
3431 int l = strlen(str1); | 3475 int l = strlen(str1); |
3432 char* result = my_mreq(l + 1,0); | 3476 char* result = (char*) my_mreq(l + 1,0); |
3433 if (result) | 3477 if (result) |
3434 strcpy(result, str1); | 3478 strcpy(result, str1); |
3435 dbgprintf("_strdup(0x%x='%s') => %p\n", str1, str1, result); | 3479 dbgprintf("_strdup(0x%x='%s') => %p\n", str1, str1, result); |
3436 return result; | 3480 return result; |
3437 } | 3481 } |
3608 | 3652 |
3609 "movl $0x56433230, 32(%%edx) \n\t" // VC20 ?? | 3653 "movl $0x56433230, 32(%%edx) \n\t" // VC20 ?? |
3610 "movl $0, 36(%%edx) \n\t" | 3654 "movl $0, 36(%%edx) \n\t" |
3611 : // output | 3655 : // output |
3612 : "d"(jmpbuf) // input | 3656 : "d"(jmpbuf) // input |
3657 : "eax" | |
3613 ); | 3658 ); |
3614 #if 1 | 3659 #if 1 |
3615 __asm__ __volatile__ | 3660 __asm__ __volatile__ |
3616 ( | 3661 ( |
3617 "mov %%fs:0, %%eax \n\t" // unsure | 3662 "mov %%fs:0, %%eax \n\t" // unsure |
3620 "jnz l1 \n\t" | 3665 "jnz l1 \n\t" |
3621 "mov %%eax, 28(%%edx) \n\t" | 3666 "mov %%eax, 28(%%edx) \n\t" |
3622 "l1: \n\t" | 3667 "l1: \n\t" |
3623 : | 3668 : |
3624 : | 3669 : |
3670 : "eax" | |
3625 ); | 3671 ); |
3626 #endif | 3672 #endif |
3627 | 3673 |
3628 return 0; | 3674 return 0; |
3629 } | 3675 } |
3788 | 3834 |
3789 static WINAPI inline unsigned long int expntohl(unsigned long int netlong) | 3835 static WINAPI inline unsigned long int expntohl(unsigned long int netlong) |
3790 { | 3836 { |
3791 // dbgprintf("ntohl(%x) => %x\n", netlong, ntohl(netlong)); | 3837 // dbgprintf("ntohl(%x) => %x\n", netlong, ntohl(netlong)); |
3792 return ntohl(netlong); | 3838 return ntohl(netlong); |
3839 } | |
3840 static void WINAPI expVariantInit(void* p) | |
3841 { | |
3842 printf("InitCommonControls called!\n"); | |
3843 return; | |
3793 } | 3844 } |
3794 | 3845 |
3795 int expRegisterClassA(const void/*WNDCLASSA*/ *wc) | 3846 int expRegisterClassA(const void/*WNDCLASSA*/ *wc) |
3796 { | 3847 { |
3797 dbgprintf("RegisterClassA(%p) => random id\n", wc); | 3848 dbgprintf("RegisterClassA(%p) => random id\n", wc); |
3910 FF(InterlockedDecrement, -1) | 3961 FF(InterlockedDecrement, -1) |
3911 FF(GetTimeZoneInformation, -1) | 3962 FF(GetTimeZoneInformation, -1) |
3912 FF(OutputDebugStringA, -1) | 3963 FF(OutputDebugStringA, -1) |
3913 FF(GetLocalTime, -1) | 3964 FF(GetLocalTime, -1) |
3914 FF(GetSystemTime, -1) | 3965 FF(GetSystemTime, -1) |
3966 FF(GetSystemTimeAsFileTime, -1) | |
3915 FF(GetEnvironmentVariableA, -1) | 3967 FF(GetEnvironmentVariableA, -1) |
3916 FF(SetEnvironmentVariableA, -1) | 3968 FF(SetEnvironmentVariableA, -1) |
3917 FF(RtlZeroMemory,-1) | 3969 FF(RtlZeroMemory,-1) |
3918 FF(RtlMoveMemory,-1) | 3970 FF(RtlMoveMemory,-1) |
3919 FF(RtlFillMemory,-1) | 3971 FF(RtlFillMemory,-1) |
3958 }; | 4010 }; |
3959 | 4011 |
3960 struct exports exp_msvcrt[]={ | 4012 struct exports exp_msvcrt[]={ |
3961 FF(malloc, -1) | 4013 FF(malloc, -1) |
3962 FF(_initterm, -1) | 4014 FF(_initterm, -1) |
4015 FF(__dllonexit, -1) | |
3963 FF(free, -1) | 4016 FF(free, -1) |
3964 {"??3@YAXPAX@Z", -1, expdelete}, | 4017 {"??3@YAXPAX@Z", -1, expdelete}, |
3965 {"??2@YAPAXI@Z", -1, expnew}, | 4018 {"??2@YAPAXI@Z", -1, expnew}, |
3966 {"_adjust_fdiv", -1, (void*)&_adjust_fdiv}, | 4019 {"_adjust_fdiv", -1, (void*)&_adjust_fdiv}, |
3967 FF(strrchr, -1) | 4020 FF(strrchr, -1) |
4073 FF(htonl,8) | 4126 FF(htonl,8) |
4074 FF(ntohl,14) | 4127 FF(ntohl,14) |
4075 }; | 4128 }; |
4076 struct exports exp_msdmo[]={ | 4129 struct exports exp_msdmo[]={ |
4077 FF(memcpy, -1) // just test | 4130 FF(memcpy, -1) // just test |
4131 /* | |
4132 FF(MoCopyMediaType) | |
4133 FF(MoCreateMediaType) | |
4134 FF(MoDeleteMediaType) | |
4135 FF(MoDuplicateMediaType) | |
4136 FF(MoFreeMediaType) | |
4137 FF(MoInitMediaType) | |
4138 */ | |
4139 }; | |
4140 struct exports exp_oleaut32[]={ | |
4141 FF(VariantInit, 8) | |
4078 }; | 4142 }; |
4079 | 4143 |
4080 /* realplayer8: | 4144 /* realplayer8: |
4081 DLL Name: PNCRT.dll | 4145 DLL Name: PNCRT.dll |
4082 vma: Hint/Ord Member-Name | 4146 vma: Hint/Ord Member-Name |
4090 22ffc 176 _beginthreadex | 4154 22ffc 176 _beginthreadex |
4091 23036 284 _iob | 4155 23036 284 _iob |
4092 2300e 85 __CxxFrameHandler | 4156 2300e 85 __CxxFrameHandler |
4093 23022 411 _purecall | 4157 23022 411 _purecall |
4094 */ | 4158 */ |
4159 #ifdef MPLAYER | |
4095 struct exports exp_pncrt[]={ | 4160 struct exports exp_pncrt[]={ |
4096 FF(malloc, -1) // just test | 4161 FF(malloc, -1) // just test |
4097 FF(free, -1) // just test | 4162 FF(free, -1) // just test |
4098 FF(fprintf, -1) // just test | 4163 FF(fprintf, -1) // just test |
4099 {"_adjust_fdiv", -1, (void*)&_adjust_fdiv}, | 4164 {"_adjust_fdiv", -1, (void*)&_adjust_fdiv}, |
4100 FF(_ftol,-1) | 4165 FF(_ftol,-1) |
4101 FF(_initterm, -1) | 4166 FF(_initterm, -1) |
4102 }; | 4167 }; |
4103 | 4168 #endif |
4104 /* needed for Morgand MJPEG */ | |
4105 struct exports exp_msvfw32[]={ | |
4106 {"ICOpen", -1, (void *)&ICOpen}, | |
4107 {"ICClose", -1, (void *)&ICClose}, | |
4108 {"ICDecompress", -1, (void *)&ICDecompress}, | |
4109 {"ICSendMessage", -1, (void *)&ICSendMessage} | |
4110 }; | |
4111 | 4169 |
4112 #define LL(X) \ | 4170 #define LL(X) \ |
4113 {#X".dll", sizeof(exp_##X)/sizeof(struct exports), exp_##X}, | 4171 {#X".dll", sizeof(exp_##X)/sizeof(struct exports), exp_##X}, |
4114 | 4172 |
4115 struct libs libraries[]={ | 4173 struct libs libraries[]={ |
4119 LL(user32) | 4177 LL(user32) |
4120 LL(advapi32) | 4178 LL(advapi32) |
4121 LL(gdi32) | 4179 LL(gdi32) |
4122 LL(version) | 4180 LL(version) |
4123 LL(ole32) | 4181 LL(ole32) |
4182 LL(oleaut32) | |
4124 LL(crtdll) | 4183 LL(crtdll) |
4125 LL(comctl32) | 4184 LL(comctl32) |
4126 LL(wsock32) | 4185 LL(wsock32) |
4127 LL(msdmo) | 4186 LL(msdmo) |
4128 LL(msvfw32) | 4187 #ifdef MPLAYER |
4129 LL(pncrt) | 4188 LL(pncrt) |
4189 #endif | |
4130 }; | 4190 }; |
4131 #include "mangle.h" | 4191 |
4132 static char* called_unk = "Called unk_%s\n"; | |
4133 static void ext_stubs(void) | 4192 static void ext_stubs(void) |
4134 { | 4193 { |
4135 // expects: | 4194 // expects: |
4136 // ax position index | 4195 // ax position index |
4137 // cx address of printf function | 4196 // cx address of printf function |
4197 #if 1 | |
4138 __asm__ __volatile__ | 4198 __asm__ __volatile__ |
4139 ( | 4199 ( |
4140 "push %edx \n\t" | 4200 "push %%edx \n\t" |
4141 "movl $0, %eax \n\t" | 4201 "movl $0xdeadbeef, %%eax \n\t" |
4142 "movl $0, %edx \n\t" | 4202 "movl $0xdeadbeef, %%edx \n\t" |
4143 "shl $5,%eax \n\t" // ax * 32 | 4203 "shl $5, %%eax \n\t" // ax * 32 |
4144 "addl $"MANGLE(export_names)",%eax \n\t" | 4204 "addl $0xdeadbeef, %%eax \n\t" // overwrite export_names |
4145 "pushl %eax \n\t" | 4205 "pushl %%eax \n\t" |
4146 "pushl "MANGLE(called_unk)" \n\t" | 4206 "pushl $0xdeadbeef \n\t" // overwrite called_unk |
4147 "call *%edx \n\t" // printf (via dx) | 4207 "call *%%edx \n\t" // printf (via dx) |
4148 "addl $8,%esp \n\t" | 4208 "addl $8, %%esp \n\t" |
4149 "xorl %eax,%eax \n\t" | 4209 "xorl %%eax, %%eax \n\t" |
4150 "pop %edx \n\t" | 4210 "pop %%edx \n\t" |
4211 : | |
4212 : | |
4213 : "eax" | |
4151 ); | 4214 ); |
4215 #else | |
4216 __asm__ __volatile__ | |
4217 ( | |
4218 "push %%edx \n\t" | |
4219 "movl $0, %%eax \n\t" | |
4220 "movl $0, %%edx \n\t" | |
4221 "shl $5, %%eax \n\t" // ax * 32 | |
4222 "addl %0, %%eax \n\t" | |
4223 "pushl %%eax \n\t" | |
4224 "pushl %1 \n\t" | |
4225 "call *%%edx \n\t" // printf (via dx) | |
4226 "addl $8, %%esp \n\t" | |
4227 "xorl %%eax, %%eax \n\t" | |
4228 "pop %%edx \n\t" | |
4229 ::"m"(*export_names), "m"(*called_unk) | |
4230 : "memory", "edx", "eax" | |
4231 ); | |
4232 #endif | |
4233 | |
4152 } | 4234 } |
4153 | 4235 |
4154 //static void add_stub(int pos) | 4236 //static void add_stub(int pos) |
4155 | 4237 |
4156 extern int unk_exp1; | 4238 extern int unk_exp1; |
4239 static int pos=0; | |
4157 static char extcode[20000];// place for 200 unresolved exports | 4240 static char extcode[20000];// place for 200 unresolved exports |
4158 static int pos=0; | 4241 static const char* called_unk = "Called unk_%s\n"; |
4159 | 4242 |
4160 static void* add_stub() | 4243 static void* add_stub() |
4161 { | 4244 { |
4245 // generated code in runtime! | |
4162 char* answ = (char*)extcode+pos*0x30; | 4246 char* answ = (char*)extcode+pos*0x30; |
4163 #if 0 | 4247 #if 0 |
4164 memcpy(answ, &unk_exp1, 0x64); | 4248 memcpy(answ, &unk_exp1, 0x64); |
4165 *(int*)(answ+9)=pos; | 4249 *(int*)(answ+9)=pos; |
4166 *(int*)(answ+47)-=((int)answ-(int)&unk_exp1); | 4250 *(int*)(answ+47)-=((int)answ-(int)&unk_exp1); |
4167 #endif | 4251 #endif |
4168 memcpy(answ, ext_stubs, 0x2f); // 0x2c is current size | 4252 memcpy(answ, ext_stubs, 0x2f); // 0x2c is current size |
4169 //answ[0] = 0xb8; // movl $0, eax (0xb8 0x00000000) | 4253 //answ[4] = 0xb8; // movl $0, eax (0xb8 0x00000000) |
4170 *((int*) (answ + 5)) = pos; | 4254 *((int*) (answ + 5)) = pos; |
4171 //answ[5] = 0xb9; // movl $0, edx (0xb9 0x00000000) | 4255 //answ[9] = 0xba; // movl $0, edx (0xba 0x00000000) |
4172 *((int*) (answ + 10)) = (int) printf; | 4256 *((long*) (answ + 10)) = (long)printf; |
4257 //answ[17] = 0x05; // addl $0, eax (0x05 0x00000000) | |
4258 *((long*) (answ + 18)) = (long)export_names; | |
4259 //answ[23] = 0x68; // pushl $0 (0x68 0x00000000) | |
4260 *((long*) (answ + 24)) = (long)called_unk; | |
4173 pos++; | 4261 pos++; |
4174 return (void*)answ; | 4262 return (void*)answ; |
4175 } | 4263 } |
4176 | 4264 |
4177 void* LookupExternal(const char* library, int ordinal) | 4265 void* LookupExternal(const char* library, int ordinal) |
4199 } | 4287 } |
4200 } | 4288 } |
4201 | 4289 |
4202 /* ok, this is a hack, and a big memory leak. should be fixed. - alex */ | 4290 /* ok, this is a hack, and a big memory leak. should be fixed. - alex */ |
4203 { | 4291 { |
4204 HMODULE hand; | 4292 int hand; |
4205 WINE_MODREF *wm; | 4293 WINE_MODREF *wm; |
4206 void *func; | 4294 void *func; |
4207 | 4295 |
4208 hand = LoadLibraryA(library); | 4296 hand = LoadLibraryA(library); |
4209 if (!hand) | 4297 if (!hand) |
4212 if (!wm) | 4300 if (!wm) |
4213 { | 4301 { |
4214 FreeLibrary(hand); | 4302 FreeLibrary(hand); |
4215 goto no_dll; | 4303 goto no_dll; |
4216 } | 4304 } |
4217 func = PE_FindExportedFunction(wm, ordinal, 0); | 4305 func = PE_FindExportedFunction(wm, (LPCSTR) ordinal, 0); |
4218 if (!func) | 4306 if (!func) |
4219 { | 4307 { |
4220 printf("No such ordinal in external dll\n"); | 4308 printf("No such ordinal in external dll\n"); |
4221 FreeLibrary(hand); | 4309 FreeLibrary((int)hand); |
4222 goto no_dll; | 4310 goto no_dll; |
4223 } | 4311 } |
4224 | 4312 |
4225 printf("External dll loaded (offset: %p, func: %p)\n", | 4313 printf("External dll loaded (offset: 0x%x, func: %p)\n", |
4226 hand, func); | 4314 hand, func); |
4227 return func; | 4315 return func; |
4228 } | 4316 } |
4229 | 4317 |
4230 no_dll: | 4318 no_dll: |
4231 if(pos>150)return 0; | 4319 if(pos>150)return 0; |
4232 sprintf(export_names[pos], "%s:%d", library, ordinal); | 4320 sprintf(export_names[pos], "%s:%d", library, ordinal); |
4233 return add_stub(pos); | 4321 return add_stub(); |
4234 } | 4322 } |
4235 | 4323 |
4236 void* LookupExternalByName(const char* library, const char* name) | 4324 void* LookupExternalByName(const char* library, const char* name) |
4237 { | 4325 { |
4238 char* answ; | 4326 char* answ; |
4261 return libraries[i].exps[j].func; | 4349 return libraries[i].exps[j].func; |
4262 } | 4350 } |
4263 } | 4351 } |
4264 if(pos>150)return 0;// to many symbols | 4352 if(pos>150)return 0;// to many symbols |
4265 strcpy(export_names[pos], name); | 4353 strcpy(export_names[pos], name); |
4266 return add_stub(pos); | 4354 return add_stub(); |
4267 } | 4355 } |
4268 | 4356 |
4269 void my_garbagecollection(void) | 4357 void my_garbagecollection(void) |
4270 { | 4358 { |
4271 #ifdef GARBAGE | 4359 #ifdef GARBAGE |
4272 int unfree = 0, unfreecnt = 0; | 4360 int unfree = 0, unfreecnt = 0; |
4273 | 4361 |
4362 int max_fatal = 8; | |
4274 free_registry(); | 4363 free_registry(); |
4275 while (last_alloc) | 4364 while (last_alloc) |
4276 { | 4365 { |
4277 alloc_header* mem = last_alloc + 1; | 4366 alloc_header* mem = last_alloc + 1; |
4278 unfree += my_size(mem); | 4367 unfree += my_size(mem); |
4279 unfreecnt++; | 4368 unfreecnt++; |
4280 my_release(mem); | 4369 if (my_release(mem) != 0) |
4281 } | 4370 // avoid endless loop when memory is trashed |
4282 dbgprintf("Total Unfree %d bytes cnt %d [%p,%d]\n",unfree, unfreecnt, last_alloc, alccnt); | 4371 if (--max_fatal < 0) |
4372 break; | |
4373 } | |
4374 printf("Total Unfree %d bytes cnt %d [%p,%d]\n",unfree, unfreecnt, last_alloc, alccnt); | |
4283 #endif | 4375 #endif |
4284 g_tls = NULL; | 4376 g_tls = NULL; |
4285 list = NULL; | 4377 list = NULL; |
4286 } | 4378 } |