1 /********************************************************
4 * Stub functions for Wine module
7 ********************************************************/
10 * Modified for use with MPlayer, detailed changelog at
11 * http://svn.mplayerhq.hu/mplayer/trunk/
18 #ifdef HAVE_SYS_MMAN_H
21 #include "osdep/mmap.h"
29 #include "osdep/mmap_anon.h"
30 #include "wine/windef.h"
31 #include "wine/winbase.h"
32 #include "wine/debugtools.h"
33 #include "wine/heap.h"
38 static void* mymalloc(unsigned int size
)
40 printf("malloc %d\n", size
);
45 #define malloc mymalloc
48 int dbg_header_err( const char *dbg_channel
, const char *func
)
52 int dbg_header_warn( const char *dbg_channel
, const char *func
)
56 int dbg_header_fixme( const char *dbg_channel
, const char *func
)
60 int dbg_header_trace( const char *dbg_channel
, const char *func
)
64 int dbg_vprintf( const char *format
, va_list args
)
68 int __vprintf( const char *format
, ... )
79 HANDLE WINAPI
GetProcessHeap(void)
84 LPVOID WINAPI
HeapAlloc(HANDLE heap
, DWORD flags
, DWORD size
)
87 void* m
= (flags
& 0x8) ? calloc(size
, 1) : malloc(size
);
88 //printf("HeapAlloc %p %d (%d)\n", m, size, flags);
94 WIN_BOOL WINAPI
HeapFree(HANDLE heap
, DWORD flags
, LPVOID mem
)
97 //printf("HeapFree %p\n", mem);
103 static int last_error
;
105 DWORD WINAPI
GetLastError(void)
110 VOID WINAPI
SetLastError(DWORD error
)
115 WIN_BOOL WINAPI
ReadFile(HANDLE handle
, LPVOID mem
, DWORD size
, LPDWORD result
, LPOVERLAPPED flags
)
117 *result
=read(handle
, mem
, size
);
120 INT WINAPI
lstrcmpiA(LPCSTR c1
, LPCSTR c2
)
122 return strcasecmp(c1
,c2
);
124 LPSTR WINAPI
lstrcpynA(LPSTR dest
, LPCSTR src
, INT num
)
126 return strncpy(dest
,src
,num
);
128 INT WINAPI
lstrlenA(LPCSTR s
)
132 INT WINAPI
lstrlenW(LPCWSTR s
)
142 LPSTR WINAPI
lstrcpynWtoA(LPSTR dest
, LPCWSTR src
, INT count
)
146 if((dest
==0) || (src
==0))
159 /* i stands here for ignore case! */
160 int wcsnicmp(const unsigned short* s1
, const unsigned short* s2
, int n
)
170 if (((*s1
| *s2
) & 0xff00) || toupper((char)*s1
) != toupper((char)*s2
))
189 WIN_BOOL WINAPI
IsBadReadPtr(LPCVOID data
, UINT size
)
197 LPSTR
HEAP_strdupA(HANDLE heap
, DWORD flags
, LPCSTR string
)
199 // return strdup(string);
200 char* answ
= malloc(strlen(string
) + 1);
201 strcpy(answ
, string
);
204 LPWSTR
HEAP_strdupAtoW(HANDLE heap
, DWORD flags
, LPCSTR string
)
211 answer
= malloc(sizeof(WCHAR
) * (size
+ 1));
212 for(i
=0; i
<=size
; i
++)
213 answer
[i
]=(short)string
[i
];
216 LPSTR
HEAP_strdupWtoA(HANDLE heap
, DWORD flags
, LPCWSTR string
)
225 answer
= malloc(size
+ 2);
226 for(i
=0; i
<=size
; i
++)
227 answer
[i
]=(char)string
[i
];
231 /***********************************************************************
235 //#define MAP_PRIVATE
237 LPVOID
FILE_dommap( int unix_handle
, LPVOID start
,
238 DWORD size_high
, DWORD size_low
,
239 DWORD offset_high
, DWORD offset_low
,
240 int prot
, int flags
)
246 if (size_high
|| offset_high
)
247 printf("offsets larger than 4Gb not supported\n");
249 if (unix_handle
== -1)
251 ret
= mmap_anon( start
, size_low
, prot
, flags
, offset_low
);
256 ret
= mmap( start
, size_low
, prot
, flags
, fd
, offset_low
);
259 if (ret
!= (LPVOID
)-1)
261 // printf("address %08x\n", *(int*)ret);
262 // printf("%x\n", ret);
266 // printf("mmap %d\n", errno);
268 /* mmap() failed; if this is because the file offset is not */
269 /* page-aligned (EINVAL), or because the underlying filesystem */
270 /* does not support mmap() (ENOEXEC), we do it by hand. */
272 if (unix_handle
== -1) return ret
;
273 if ((errno
!= ENOEXEC
) && (errno
!= EINVAL
)) return ret
;
274 if (prot
& PROT_WRITE
)
276 /* We cannot fake shared write mappings */
278 if (flags
& MAP_SHARED
) return ret
;
281 if (!(flags
& MAP_PRIVATE
)) return ret
;
284 /* printf( "FILE_mmap: mmap failed (%d), faking it\n", errno );*/
285 /* Reserve the memory with an anonymous mmap */
286 ret
= FILE_dommap( -1, start
, size_high
, size_low
, 0, 0,
287 PROT_READ
| PROT_WRITE
, flags
);
288 if (ret
== (LPVOID
)-1)
292 /* Now read in the file */
293 if ((pos
= lseek( fd
, offset_low
, SEEK_SET
)) == -1)
295 FILE_munmap( ret
, size_high
, size_low
);
296 // printf("lseek\n");
299 read( fd
, ret
, size_low
);
300 lseek( fd
, pos
, SEEK_SET
); /* Restore the file pointer */
301 mprotect( ret
, size_low
, prot
); /* Set the right protection */
302 // printf("address %08x\n", *(int*)ret);
307 /***********************************************************************
310 int FILE_munmap( LPVOID start
, DWORD size_high
, DWORD size_low
)
313 printf("offsets larger than 4Gb not supported\n");
314 return munmap( start
, size_low
);
317 struct file_mapping_s
;
318 typedef struct file_mapping_s
323 struct file_mapping_s
* next
;
324 struct file_mapping_s
* prev
;
326 static file_mapping
* fm
=0;
330 #define PAGE_NOACCESS 0x01
331 #define PAGE_READONLY 0x02
332 #define PAGE_READWRITE 0x04
333 #define PAGE_WRITECOPY 0x08
334 #define PAGE_EXECUTE 0x10
335 #define PAGE_EXECUTE_READ 0x20
336 #define PAGE_EXECUTE_READWRITE 0x40
337 #define PAGE_EXECUTE_WRITECOPY 0x80
338 #define PAGE_GUARD 0x100
339 #define PAGE_NOCACHE 0x200
341 HANDLE WINAPI
CreateFileMappingA(HANDLE handle
, LPSECURITY_ATTRIBUTES lpAttr
,
343 DWORD dwMaxHigh
, DWORD dwMaxLow
,
346 int hFile
= (int)handle
;
356 len
=lseek(hFile
, 0, SEEK_END
);
357 lseek(hFile
, 0, SEEK_SET
);
361 if(flProtect
& PAGE_READONLY
)
362 mmap_access
|=PROT_READ
;
364 mmap_access
|=PROT_READ
|PROT_WRITE
;
367 answer
=mmap_anon(NULL
, len
, mmap_access
, MAP_PRIVATE
, 0);
369 answer
=mmap(NULL
, len
, mmap_access
, MAP_PRIVATE
, hFile
, 0);
371 if(answer
!=(LPVOID
)-1)
375 fm
= malloc(sizeof(file_mapping
));
380 fm
->next
= malloc(sizeof(file_mapping
));
388 fm
->name
= malloc(strlen(name
)+1);
389 strcpy(fm
->name
, name
);
393 fm
->mapping_size
=len
;
395 return (HANDLE
)answer
;
399 WIN_BOOL WINAPI
UnmapViewOfFile(LPVOID handle
)
405 for(p
=fm
; p
; p
=p
->next
)
407 if(p
->handle
==handle
)
409 result
=munmap((void*)handle
, p
->mapping_size
);
410 if(p
->next
)p
->next
->prev
=p
->prev
;
411 if(p
->prev
)p
->prev
->next
=p
->next
;
422 //static int va_size=0;
424 typedef struct virt_alloc_s
428 struct virt_alloc_s
* next
;
429 struct virt_alloc_s
* prev
;
432 static virt_alloc
* vm
=0;
433 #define MEM_COMMIT 0x00001000
434 #define MEM_RESERVE 0x00002000
436 LPVOID WINAPI
VirtualAlloc(LPVOID address
, DWORD size
, DWORD type
, DWORD protection
)
441 //printf("VirtualAlloc(0x%08X, %u, 0x%08X, 0x%08X)\n", (unsigned)address, size, type, protection);
443 if ((type
&(MEM_RESERVE
|MEM_COMMIT
)) == 0) return NULL
;
445 if (type
&MEM_RESERVE
&& (unsigned)address
&0xffff) {
446 size
+= (unsigned)address
&0xffff;
447 address
= (unsigned)address
&~0xffff;
449 pgsz
= sysconf(_SC_PAGESIZE
);
450 if (type
&MEM_COMMIT
&& (unsigned)address
%pgsz
) {
451 size
+= (unsigned)address
%pgsz
;
452 address
-= (unsigned)address
%pgsz
;
455 if (type
&MEM_RESERVE
&& size
<0x10000) size
= 0x10000;
456 if (size
%pgsz
) size
+= pgsz
- size
%pgsz
;
460 //check whether we can allow to allocate this
464 if((unsigned)address
>=(unsigned)str
->address
+str
->mapping_size
)
469 if((unsigned)address
+size
<=(unsigned)str
->address
)
477 if( ((unsigned)address
>= (unsigned)str
->address
)
478 && ((unsigned)address
+size
<=(unsigned)str
->address
+str
->mapping_size
)
479 && (type
& MEM_COMMIT
))
481 return address
; //returning previously reserved memory
483 //printf(" VirtualAlloc(...) does not commit or not entirely within reserved, and\n");
485 /*printf(" VirtualAlloc(...) (0x%08X, %u) overlaps with (0x%08X, %u, state=%d)\n",
486 (unsigned)address, size, (unsigned)str->address, str->mapping_size, str->state);*/
491 answer
=mmap_anon(address
, size
, PROT_READ
| PROT_WRITE
| PROT_EXEC
,
493 // answer=FILE_dommap(-1, address, 0, size, 0, 0,
494 // PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE);
496 if (answer
!= (void *)-1 && address
&& answer
!= address
) {
497 /* It is dangerous to try mmap() with MAP_FIXED since it does not
498 always detect conflicts or non-allocation and chaos ensues after
499 a successful call but an overlapping or non-allocated region. */
500 munmap(answer
, size
);
501 answer
= (void *) -1;
503 //printf(" VirtualAlloc(...) cannot satisfy requested address but address=NULL would work.\n");
505 if(answer
==(void*)-1)
507 /*printf(" VirtualAlloc(...) mmap(0x%08X, %u, ...) failed with errno=%d (\"%s\")\n",
508 (unsigned)address, size, errno, strerror(errno));*/
513 virt_alloc
*new_vm
= malloc(sizeof(virt_alloc
));
514 new_vm
->mapping_size
=size
;
515 new_vm
->address
=(char*)answer
;
517 if(type
== MEM_RESERVE
)
526 // printf("Multiple VirtualAlloc!\n");
527 //printf(" VirtualAlloc(...) provides (0x%08X, %u)\n", (unsigned)answer, size);
532 WIN_BOOL WINAPI
VirtualFree(LPVOID address
, SIZE_T dwSize
, DWORD dwFreeType
)//not sure
537 //printf("VirtualFree(0x%08X, %d, 0x%08X)\n", (unsigned)address, dwSize, dwFreeType);
540 if(address
!=str
->address
)
545 //printf(" VirtualFree(...) munmap(0x%08X, %d)\n", (unsigned)str->address, str->mapping_size);
546 answer
=munmap(str
->address
, str
->mapping_size
);
547 if(str
->next
)str
->next
->prev
=str
->prev
;
548 if(str
->prev
)str
->prev
->next
=str
->next
;
549 if(vm
==str
)vm
=str
->prev
;
556 INT WINAPI
WideCharToMultiByte(UINT codepage
, DWORD flags
, LPCWSTR src
,
557 INT srclen
,LPSTR dest
, INT destlen
, LPCSTR defch
, WIN_BOOL
* used_defch
)
560 if(srclen
==-1){srclen
=0; while(src
[srclen
++]);}
565 for(i
=0; i
<min(srclen
, destlen
); i
++)
566 *dest
++=(char)*src
++;
567 return min(srclen
, destlen
);
569 INT WINAPI
MultiByteToWideChar(UINT codepage
,DWORD flags
, LPCSTR src
, INT srclen
,
570 LPWSTR dest
, INT destlen
)
573 if(srclen
==-1){srclen
=0; while(src
[srclen
++]);}
576 for(i
=0; i
<min(srclen
, destlen
); i
++)
577 *dest
++=(WCHAR
)*src
++;
578 return min(srclen
, destlen
);
580 HANDLE WINAPI
OpenFileMappingA(DWORD access
, WIN_BOOL prot
, LPCSTR name
)
587 for(p
=fm
; p
; p
=p
->prev
)
591 if(strcmp(p
->name
, name
)==0)
592 return (HANDLE
)p
->handle
;