1 /********************************************************
4 * Stub functions for Wine module
7 ********************************************************/
10 * Modified for use with MPlayer, detailed changelog at
11 * http://svn.mplayerhq.hu/mplayer/trunk/
21 #ifdef HAVE_SYS_MMAN_H
24 #include "osdep/mmap.h"
32 #include "osdep/mmap_anon.h"
33 #include "wine/windef.h"
34 #include "wine/winbase.h"
35 #include "wine/debugtools.h"
36 #include "wine/heap.h"
41 static void* mymalloc(unsigned int size
)
43 printf("malloc %d\n", size
);
48 #define malloc mymalloc
51 int dbg_header_err( const char *dbg_channel
, const char *func
)
55 int dbg_header_warn( const char *dbg_channel
, const char *func
)
59 int dbg_header_fixme( const char *dbg_channel
, const char *func
)
63 int dbg_header_trace( const char *dbg_channel
, const char *func
)
67 int dbg_vprintf( const char *format
, va_list args
)
71 int __vprintf( const char *format
, ... )
82 HANDLE WINAPI
GetProcessHeap(void)
87 LPVOID WINAPI
HeapAlloc(HANDLE heap
, DWORD flags
, DWORD size
)
90 void* m
= (flags
& 0x8) ? calloc(size
, 1) : malloc(size
);
91 //printf("HeapAlloc %p %d (%d)\n", m, size, flags);
97 WIN_BOOL WINAPI
HeapFree(HANDLE heap
, DWORD flags
, LPVOID mem
)
100 //printf("HeapFree %p\n", mem);
106 static int last_error
;
108 DWORD WINAPI
GetLastError(void)
113 VOID WINAPI
SetLastError(DWORD error
)
118 WIN_BOOL WINAPI
ReadFile(HANDLE handle
, LPVOID mem
, DWORD size
, LPDWORD result
, LPOVERLAPPED flags
)
120 *result
=read(handle
, mem
, size
);
123 INT WINAPI
lstrcmpiA(LPCSTR c1
, LPCSTR c2
)
125 return strcasecmp(c1
,c2
);
127 LPSTR WINAPI
lstrcpynA(LPSTR dest
, LPCSTR src
, INT num
)
129 return strncpy(dest
,src
,num
);
131 INT WINAPI
lstrlenA(LPCSTR s
)
135 INT WINAPI
lstrlenW(LPCWSTR s
)
145 LPSTR WINAPI
lstrcpynWtoA(LPSTR dest
, LPCWSTR src
, INT count
)
149 if((dest
==0) || (src
==0))
162 /* i stands here for ignore case! */
163 int wcsnicmp(const unsigned short* s1
, const unsigned short* s2
, int n
)
173 if (((*s1
| *s2
) & 0xff00) || toupper((char)*s1
) != toupper((char)*s2
))
192 WIN_BOOL WINAPI
IsBadReadPtr(LPCVOID data
, UINT size
)
200 LPSTR
HEAP_strdupA(HANDLE heap
, DWORD flags
, LPCSTR string
)
202 // return strdup(string);
203 char* answ
= (char*) malloc(strlen(string
) + 1);
204 strcpy(answ
, string
);
207 LPWSTR
HEAP_strdupAtoW(HANDLE heap
, DWORD flags
, LPCSTR string
)
214 answer
= (WCHAR
*) malloc(sizeof(WCHAR
) * (size
+ 1));
215 for(i
=0; i
<=size
; i
++)
216 answer
[i
]=(short)string
[i
];
219 LPSTR
HEAP_strdupWtoA(HANDLE heap
, DWORD flags
, LPCWSTR string
)
228 answer
= (char*) malloc(size
+ 2);
229 for(i
=0; i
<=size
; i
++)
230 answer
[i
]=(char)string
[i
];
234 /***********************************************************************
238 //#define MAP_PRIVATE
240 LPVOID
FILE_dommap( int unix_handle
, LPVOID start
,
241 DWORD size_high
, DWORD size_low
,
242 DWORD offset_high
, DWORD offset_low
,
243 int prot
, int flags
)
249 if (size_high
|| offset_high
)
250 printf("offsets larger than 4Gb not supported\n");
252 if (unix_handle
== -1)
254 ret
= mmap_anon( start
, size_low
, prot
, flags
, offset_low
);
259 ret
= mmap( start
, size_low
, prot
, flags
, fd
, offset_low
);
262 if (ret
!= (LPVOID
)-1)
264 // printf("address %08x\n", *(int*)ret);
265 // printf("%x\n", ret);
269 // printf("mmap %d\n", errno);
271 /* mmap() failed; if this is because the file offset is not */
272 /* page-aligned (EINVAL), or because the underlying filesystem */
273 /* does not support mmap() (ENOEXEC), we do it by hand. */
275 if (unix_handle
== -1) return ret
;
276 if ((errno
!= ENOEXEC
) && (errno
!= EINVAL
)) return ret
;
277 if (prot
& PROT_WRITE
)
279 /* We cannot fake shared write mappings */
281 if (flags
& MAP_SHARED
) return ret
;
284 if (!(flags
& MAP_PRIVATE
)) return ret
;
287 /* printf( "FILE_mmap: mmap failed (%d), faking it\n", errno );*/
288 /* Reserve the memory with an anonymous mmap */
289 ret
= FILE_dommap( -1, start
, size_high
, size_low
, 0, 0,
290 PROT_READ
| PROT_WRITE
, flags
);
291 if (ret
== (LPVOID
)-1)
295 /* Now read in the file */
296 if ((pos
= lseek( fd
, offset_low
, SEEK_SET
)) == -1)
298 FILE_munmap( ret
, size_high
, size_low
);
299 // printf("lseek\n");
302 read( fd
, ret
, size_low
);
303 lseek( fd
, pos
, SEEK_SET
); /* Restore the file pointer */
304 mprotect( ret
, size_low
, prot
); /* Set the right protection */
305 // printf("address %08x\n", *(int*)ret);
310 /***********************************************************************
313 int FILE_munmap( LPVOID start
, DWORD size_high
, DWORD size_low
)
316 printf("offsets larger than 4Gb not supported\n");
317 return munmap( start
, size_low
);
320 struct file_mapping_s
;
321 typedef struct file_mapping_s
326 struct file_mapping_s
* next
;
327 struct file_mapping_s
* prev
;
329 static file_mapping
* fm
=0;
333 #define PAGE_NOACCESS 0x01
334 #define PAGE_READONLY 0x02
335 #define PAGE_READWRITE 0x04
336 #define PAGE_WRITECOPY 0x08
337 #define PAGE_EXECUTE 0x10
338 #define PAGE_EXECUTE_READ 0x20
339 #define PAGE_EXECUTE_READWRITE 0x40
340 #define PAGE_EXECUTE_WRITECOPY 0x80
341 #define PAGE_GUARD 0x100
342 #define PAGE_NOCACHE 0x200
344 HANDLE WINAPI
CreateFileMappingA(HANDLE handle
, LPSECURITY_ATTRIBUTES lpAttr
,
346 DWORD dwMaxHigh
, DWORD dwMaxLow
,
349 int hFile
= (int)handle
;
359 len
=lseek(hFile
, 0, SEEK_END
);
360 lseek(hFile
, 0, SEEK_SET
);
364 if(flProtect
& PAGE_READONLY
)
365 mmap_access
|=PROT_READ
;
367 mmap_access
|=PROT_READ
|PROT_WRITE
;
370 answer
=mmap_anon(NULL
, len
, mmap_access
, MAP_PRIVATE
, 0);
372 answer
=mmap(NULL
, len
, mmap_access
, MAP_PRIVATE
, hFile
, 0);
374 if(answer
!=(LPVOID
)-1)
378 fm
= (file_mapping
*) malloc(sizeof(file_mapping
));
383 fm
->next
= (file_mapping
*) malloc(sizeof(file_mapping
));
391 fm
->name
= (char*) malloc(strlen(name
)+1);
392 strcpy(fm
->name
, name
);
396 fm
->mapping_size
=len
;
398 return (HANDLE
)answer
;
402 WIN_BOOL WINAPI
UnmapViewOfFile(LPVOID handle
)
408 for(p
=fm
; p
; p
=p
->next
)
410 if(p
->handle
==handle
)
412 result
=munmap((void*)handle
, p
->mapping_size
);
413 if(p
->next
)p
->next
->prev
=p
->prev
;
414 if(p
->prev
)p
->prev
->next
=p
->next
;
425 //static int va_size=0;
427 typedef struct virt_alloc_s
431 struct virt_alloc_s
* next
;
432 struct virt_alloc_s
* prev
;
435 static virt_alloc
* vm
=0;
436 #define MEM_COMMIT 0x00001000
437 #define MEM_RESERVE 0x00002000
439 LPVOID WINAPI
VirtualAlloc(LPVOID address
, DWORD size
, DWORD type
, DWORD protection
)
444 //printf("VirtualAlloc(0x%08X, %u, 0x%08X, 0x%08X)\n", (unsigned)address, size, type, protection);
446 if ((type
&(MEM_RESERVE
|MEM_COMMIT
)) == 0) return NULL
;
448 if (type
&MEM_RESERVE
&& (unsigned)address
&0xffff) {
449 size
+= (unsigned)address
&0xffff;
450 address
= (unsigned)address
&~0xffff;
452 pgsz
= sysconf(_SC_PAGESIZE
);
453 if (type
&MEM_COMMIT
&& (unsigned)address
%pgsz
) {
454 size
+= (unsigned)address
%pgsz
;
455 address
-= (unsigned)address
%pgsz
;
458 if (type
&MEM_RESERVE
&& size
<0x10000) size
= 0x10000;
459 if (size
%pgsz
) size
+= pgsz
- size
%pgsz
;
463 //check whether we can allow to allocate this
467 if((unsigned)address
>=(unsigned)str
->address
+str
->mapping_size
)
472 if((unsigned)address
+size
<=(unsigned)str
->address
)
480 if( ((unsigned)address
>= (unsigned)str
->address
)
481 && ((unsigned)address
+size
<=(unsigned)str
->address
+str
->mapping_size
)
482 && (type
& MEM_COMMIT
))
484 return address
; //returning previously reserved memory
486 //printf(" VirtualAlloc(...) does not commit or not entirely within reserved, and\n");
488 /*printf(" VirtualAlloc(...) (0x%08X, %u) overlaps with (0x%08X, %u, state=%d)\n",
489 (unsigned)address, size, (unsigned)str->address, str->mapping_size, str->state);*/
494 answer
=mmap_anon(address
, size
, PROT_READ
| PROT_WRITE
| PROT_EXEC
,
496 // answer=FILE_dommap(-1, address, 0, size, 0, 0,
497 // PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE);
499 if (answer
!= (void *)-1 && address
&& answer
!= address
) {
500 /* It is dangerous to try mmap() with MAP_FIXED since it does not
501 always detect conflicts or non-allocation and chaos ensues after
502 a successful call but an overlapping or non-allocated region. */
503 munmap(answer
, size
);
504 answer
= (void *) -1;
506 //printf(" VirtualAlloc(...) cannot satisfy requested address but address=NULL would work.\n");
508 if(answer
==(void*)-1)
510 /*printf(" VirtualAlloc(...) mmap(0x%08X, %u, ...) failed with errno=%d (\"%s\")\n",
511 (unsigned)address, size, errno, strerror(errno));*/
516 virt_alloc
*new_vm
= (virt_alloc
*) malloc(sizeof(virt_alloc
));
517 new_vm
->mapping_size
=size
;
518 new_vm
->address
=(char*)answer
;
520 if(type
== MEM_RESERVE
)
529 // printf("Multiple VirtualAlloc!\n");
530 //printf(" VirtualAlloc(...) provides (0x%08X, %u)\n", (unsigned)answer, size);
535 WIN_BOOL WINAPI
VirtualFree(LPVOID address
, SIZE_T dwSize
, DWORD dwFreeType
)//not sure
540 //printf("VirtualFree(0x%08X, %d, 0x%08X)\n", (unsigned)address, dwSize, dwFreeType);
543 if(address
!=str
->address
)
548 //printf(" VirtualFree(...) munmap(0x%08X, %d)\n", (unsigned)str->address, str->mapping_size);
549 answer
=munmap(str
->address
, str
->mapping_size
);
550 if(str
->next
)str
->next
->prev
=str
->prev
;
551 if(str
->prev
)str
->prev
->next
=str
->next
;
552 if(vm
==str
)vm
=str
->prev
;
559 INT WINAPI
WideCharToMultiByte(UINT codepage
, DWORD flags
, LPCWSTR src
,
560 INT srclen
,LPSTR dest
, INT destlen
, LPCSTR defch
, WIN_BOOL
* used_defch
)
563 if(srclen
==-1){srclen
=0; while(src
[srclen
++]);}
568 for(i
=0; i
<min(srclen
, destlen
); i
++)
569 *dest
++=(char)*src
++;
570 return min(srclen
, destlen
);
572 INT WINAPI
MultiByteToWideChar(UINT codepage
,DWORD flags
, LPCSTR src
, INT srclen
,
573 LPWSTR dest
, INT destlen
)
576 if(srclen
==-1){srclen
=0; while(src
[srclen
++]);}
579 for(i
=0; i
<min(srclen
, destlen
); i
++)
580 *dest
++=(WCHAR
)*src
++;
581 return min(srclen
, destlen
);
583 HANDLE WINAPI
OpenFileMappingA(DWORD access
, WIN_BOOL prot
, LPCSTR name
)
590 for(p
=fm
; p
; p
=p
->prev
)
594 if(strcmp(p
->name
, name
)==0)
595 return (HANDLE
)p
->handle
;