mirror of
https://github.com/dgis/emu48android
synced 2024-12-26 09:58:49 +01:00
This commit is contained in:
parent
0ad2d47f21
commit
807502a10c
2 changed files with 150 additions and 263 deletions
|
@ -2,6 +2,8 @@
|
|||
//#include <mach/mach_time.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
HANDLE hWnd;
|
||||
LPTSTR szTitle;
|
||||
|
@ -46,24 +48,24 @@ HANDLE CreateFile(LPCTSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode,
|
|||
}
|
||||
|
||||
fd = open(lpFileName, flags, perm);
|
||||
// if (-1 != fd && 0 != dwShareMode)
|
||||
// {
|
||||
// // Not specifiying shared write means non-shared (exclusive) write
|
||||
// if (0 == (dwShareMode & FILE_SHARE_WRITE))
|
||||
// lock.l_type = F_WRLCK;
|
||||
// else if (0 != (dwShareMode & FILE_SHARE_READ))
|
||||
// lock.l_type = F_RDLCK;
|
||||
//
|
||||
// // Lock entire file
|
||||
// lock.l_len = lock.l_start = 0;
|
||||
// lock.l_whence = SEEK_SET;
|
||||
//
|
||||
// if (-1 == fcntl(fd, F_SETLK, &lock) && (EACCES == errno || EAGAIN == errno))
|
||||
// {
|
||||
// close(fd);
|
||||
// return -1;
|
||||
// }
|
||||
// }
|
||||
if (-1 != fd && 0 != dwShareMode)
|
||||
{
|
||||
// Not specifiying shared write means non-shared (exclusive) write
|
||||
if (0 == (dwShareMode & FILE_SHARE_WRITE))
|
||||
lock.l_type = F_WRLCK;
|
||||
else if (0 != (dwShareMode & FILE_SHARE_READ))
|
||||
lock.l_type = F_RDLCK;
|
||||
|
||||
// Lock entire file
|
||||
lock.l_len = lock.l_start = 0;
|
||||
lock.l_whence = SEEK_SET;
|
||||
|
||||
if (-1 == fcntl(fd, F_SETLK, &lock) && (EACCES == errno || EAGAIN == errno))
|
||||
{
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
HANDLE result = malloc(sizeof(_HANDLE));
|
||||
result->handleType = HANDLE_TYPE_FILE;
|
||||
|
@ -114,15 +116,30 @@ DWORD GetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh) {
|
|||
//https://www.ibm.com/developerworks/systems/library/es-win32linux.html
|
||||
//https://www.ibm.com/developerworks/systems/library/es-win32linux-sem.html
|
||||
HANDLE CreateFileMapping(HANDLE hFile, LPSECURITY_ATTRIBUTES lpFileMappingAttributes, DWORD flProtect, DWORD dwMaximumSizeHigh, DWORD dwMaximumSizeLow, LPCSTR lpName) {
|
||||
return NULL;
|
||||
HANDLE result = malloc(sizeof(_HANDLE));
|
||||
result->handleType = HANDLE_TYPE_FILE_MAPPING;
|
||||
result->fileDescriptor = hFile->fileDescriptor;
|
||||
result->fileMappingSize = (dwMaximumSizeHigh << 32) & dwMaximumSizeLow;
|
||||
result->fileMappingAddress = NULL;
|
||||
return result;
|
||||
}
|
||||
|
||||
LPVOID MapViewOfFile(HANDLE hFileMappingObject,DWORD dwDesiredAccess, DWORD dwFileOffsetHigh,DWORD dwFileOffsetLow, SIZE_T dwNumberOfBytesToMap) {
|
||||
return NULL;
|
||||
//https://msdn.microsoft.com/en-us/library/Aa366761(v=VS.85).aspx
|
||||
LPVOID MapViewOfFile(HANDLE hFileMappingObject, DWORD dwDesiredAccess, DWORD dwFileOffsetHigh, DWORD dwFileOffsetLow, SIZE_T dwNumberOfBytesToMap) {
|
||||
int prot = PROT_NONE;
|
||||
if(dwDesiredAccess & FILE_MAP_READ)
|
||||
prot |= PROT_READ;
|
||||
if(dwDesiredAccess & FILE_MAP_WRITE)
|
||||
prot |= PROT_WRITE;
|
||||
off_t __offset = (dwFileOffsetHigh << 32) & dwFileOffsetLow;
|
||||
hFileMappingObject->fileMappingAddress = mmap(NULL, hFileMappingObject->fileMappingSize, prot, MAP_PRIVATE, hFileMappingObject->fileDescriptor, __offset);
|
||||
return hFileMappingObject->fileMappingAddress;
|
||||
}
|
||||
|
||||
// https://msdn.microsoft.com/en-us/library/aa366882(v=vs.85).aspx
|
||||
BOOL UnmapViewOfFile(LPCVOID lpBaseAddress) {
|
||||
return NULL;
|
||||
int result = munmap(lpBaseAddress, -1);
|
||||
return result == 0;
|
||||
}
|
||||
|
||||
// https://github.com/NeoSmart/PEvents
|
||||
|
@ -208,12 +225,34 @@ DWORD WaitForSingleObject(HANDLE eventId, int timeout)
|
|||
return result;
|
||||
}
|
||||
|
||||
#include <pthread.h>
|
||||
HANDLE WINAPI CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId) {
|
||||
//TODO
|
||||
pthread_t *threadId;
|
||||
pthread_attr_t attr;
|
||||
pthread_attr_init(&attr);
|
||||
if(dwStackSize)
|
||||
pthread_attr_setstacksize(&attr, dwStackSize);
|
||||
//Suspended
|
||||
//https://stackoverflow.com/questions/3140867/suspend-pthreads-without-using-condition
|
||||
//https://stackoverflow.com/questions/7953917/create-thread-in-suspended-mode-using-pthreads
|
||||
//http://man7.org/linux/man-pages/man3/pthread_create.3.html
|
||||
int pthreadResult = pthread_create(threadId, &attr, /*(void*(*)(void*))*/lpStartAddress, lpParameter);
|
||||
if(pthreadResult == 0) {
|
||||
HANDLE result = malloc(sizeof(_HANDLE));
|
||||
result->handleType = HANDLE_TYPE_THREAD;
|
||||
result->threadId = *threadId;
|
||||
return result;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DWORD ResumeThread(HANDLE hThread) {
|
||||
//TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
BOOL WINAPI CloseHandle(HANDLE hObject) {
|
||||
//https://msdn.microsoft.com/en-us/9b84891d-62ca-4ddc-97b7-c4c79482abd9
|
||||
// Can be a thread/event/file handle!
|
||||
switch(hObject->handleType) {
|
||||
case HANDLE_TYPE_FILE: {
|
||||
|
@ -225,11 +264,23 @@ BOOL WINAPI CloseHandle(HANDLE hObject) {
|
|||
}
|
||||
break;
|
||||
}
|
||||
case HANDLE_TYPE_FILE_MAPPING: {
|
||||
int closeResult = UnmapViewOfFile(hObject->fileMappingAddress);
|
||||
if(closeResult == TRUE) {
|
||||
hObject->fileDescriptor = 0;
|
||||
hObject->fileMappingSize = 0;
|
||||
hObject->fileMappingAddress = NULL;
|
||||
free(hObject);
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case HANDLE_TYPE_EVENT:
|
||||
//free(hObject);
|
||||
return TRUE;
|
||||
case HANDLE_TYPE_THREAD:
|
||||
//free(hObject);
|
||||
hObject->threadId = 0;
|
||||
free(hObject);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
|
@ -237,181 +288,61 @@ BOOL WINAPI CloseHandle(HANDLE hObject) {
|
|||
|
||||
void Sleep(int ms)
|
||||
{
|
||||
// [[NSRunLoop currentRunLoop] runUntilDate: [NSDate dateWithTimeIntervalSinceNow: (ms / 1000.0)]];
|
||||
//// [NSThread sleepUntilDate: [NSDate dateWithTimeIntervalSinceNow: (ms / 1000.0)]];
|
||||
struct timespec timeOut,remains;
|
||||
timeOut.tv_sec = 0;
|
||||
timeOut.tv_nsec = ms * 1000000; /* 50 milliseconds */
|
||||
nanosleep(&timeOut, &remains);
|
||||
}
|
||||
|
||||
BOOL QueryPerformanceFrequency(PLARGE_INTEGER l) {
|
||||
//https://msdn.microsoft.com/en-us/library/windows/desktop/ms644904(v=vs.85).aspx
|
||||
// static struct mach_timebase_info timebase = { 0, 0 };
|
||||
// if (0 == timebase.denom)
|
||||
// mach_timebase_info(&timebase);
|
||||
//// l->LowPart = 1e9 * timebase.denom / timebase.numer;
|
||||
l->QuadPart = 1000000;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL QueryPerformanceCounter(PLARGE_INTEGER l)
|
||||
{
|
||||
struct timespec {
|
||||
time_t tv_sec; /* seconds */
|
||||
long tv_nsec; /* nanoseconds */
|
||||
} time;
|
||||
int clock_gettime(CLOCK_MONOTONIC, &time);
|
||||
l->QuadPart = time.tv_nsec;
|
||||
return TRUE;
|
||||
}
|
||||
void EnterCriticalSection(CRITICAL_SECTION *lock)
|
||||
{
|
||||
pthread_mutex_lock(lock);
|
||||
}
|
||||
|
||||
void LeaveCriticalSection(CRITICAL_SECTION *lock)
|
||||
{
|
||||
pthread_mutex_unlock(lock);
|
||||
}
|
||||
|
||||
DWORD GetPrivateProfileString(LPCTSTR lpAppName, LPCTSTR lpKeyName, LPCTSTR lpDefault, LPTSTR lpReturnedString, DWORD nSize, LPCTSTR lpFileName) {
|
||||
//TODO
|
||||
#ifdef UNICODE
|
||||
wcsncpy(lpReturnedString, lpDefault, nSize);
|
||||
#else
|
||||
strncpy(lpReturnedString, lpDefault, nSize);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
UINT GetPrivateProfileInt(LPCTSTR lpAppName, LPCTSTR lpKeyName, INT nDefault, LPCTSTR lpFileName) {
|
||||
//TODO
|
||||
return nDefault;
|
||||
}
|
||||
BOOL WritePrivateProfileString(LPCTSTR lpAppName, LPCTSTR lpKeyName, LPCTSTR lpString, LPCTSTR lpFileName) {
|
||||
//TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
OSErr ReadFile(FSPtr &file, void *buf, SInt64 size, void *, void *)
|
||||
{
|
||||
OSErr e;
|
||||
short filenum = *file;
|
||||
if(filenum==0) // file needs to be open first
|
||||
return -1;
|
||||
|
||||
SInt64 tot_read = 0;
|
||||
ByteCount bytesread;
|
||||
// Align read on 4K boundary if possible
|
||||
const SInt64 bufsize = (size<4096) ? size : 4096;
|
||||
while(noErr==(e = FSReadFork(filenum, fsAtMark|noCacheMask, 0, bufsize, buf+tot_read, &bytesread))) {
|
||||
tot_read += bytesread;
|
||||
if(tot_read>=size)
|
||||
break;
|
||||
}
|
||||
|
||||
if(e==eofErr)
|
||||
tot_read += bytesread;
|
||||
|
||||
if(tot_read != size)
|
||||
return -1;
|
||||
|
||||
// EOF is not an error, just a sign that the file was read successfully
|
||||
return (e==eofErr) ? noErr : e;
|
||||
}
|
||||
|
||||
|
||||
OSErr WriteFile(FSPtr &file, void *buf, SInt64 size, void *, void *)
|
||||
{
|
||||
short filenum = *file;
|
||||
if(filenum==0) // file needs to be open first
|
||||
return -1;
|
||||
|
||||
FSRef fref = *file;
|
||||
FSPtr tempfile = FSPtr(new FSFile());
|
||||
UInt32 currentTime;
|
||||
ProcessSerialNumber pid; // 64-bit data
|
||||
DCFStringPtr tempFileName;
|
||||
FSRef tempfolder;
|
||||
OSErr e;
|
||||
|
||||
FSCatalogInfo inf;
|
||||
|
||||
// If destination is different volume, save the temp file there
|
||||
// (since FSExchange only works inside the same volume)
|
||||
if((e=FSFindFolder(kLocalDomain, kTemporaryFolderType, TRUE, &tempfolder))==noErr) {
|
||||
if((e=FSGetCatalogInfo(&fref, kFSCatInfoVolume, &inf, NULL, NULL, NULL))==noErr) {
|
||||
FSVolumeRefNum origvol = inf.volume;
|
||||
// Get the actual vol number of the temp folder
|
||||
e = FSGetCatalogInfo(&tempfolder, kFSCatInfoVolume, &inf, NULL, NULL, NULL);
|
||||
if(e==noErr) {
|
||||
if(origvol != inf.volume)// on different volumes
|
||||
tempfolder = file->parent; // force use of same volume
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(e!=noErr)
|
||||
tempfolder = file->parent; // try a sensible alternative
|
||||
|
||||
// Generate tempfile name based on current time and process pid
|
||||
GetDateTime(¤tTime);
|
||||
e = GetCurrentProcess(&pid);
|
||||
tempFileName = MakeCFObject(
|
||||
(e==noErr) ?
|
||||
CFStringCreateWithFormat(NULL, NULL, CFSTR("%lu%lu%@%lu"), pid.highLongOfPSN, pid.lowLongOfPSN, file->filename, currentTime) :
|
||||
CFStringCreateWithFormat(NULL, NULL, CFSTR("JFCd%@%d"), file->filename, currentTime)
|
||||
);
|
||||
if(tempFileName.get()==NULL)
|
||||
return -1;
|
||||
|
||||
tempfile->parent = tempfolder;
|
||||
tempfile->filename = CFRetain(*tempFileName);
|
||||
e = tempfile->open(fsRdWrPerm, false, FOUR_CHAR_CODE('trsh'));
|
||||
|
||||
if(e==noErr) {
|
||||
// write data here
|
||||
SInt64 tot_written = 0;
|
||||
ByteCount bytes_written;
|
||||
short temprefnum = *tempfile;
|
||||
const SInt64 bufsize = (size<4096) ? size : 4096;
|
||||
while(noErr==(e = FSWriteFork(temprefnum,
|
||||
fsAtMark|noCacheMask, // os keeps track of file pointer
|
||||
0, // ignored
|
||||
bufsize, buf+tot_written, &bytes_written))) {
|
||||
tot_written += bytes_written;
|
||||
if(tot_written>=size)
|
||||
break;
|
||||
}
|
||||
|
||||
if(tot_written < size) { // disk full? couldn't complete write
|
||||
FSRef tempref = *tempfile;
|
||||
tempfile.reset();
|
||||
FSDeleteObject(&tempref);
|
||||
return (e==noErr) ? -1 : e; // error no matter what
|
||||
}
|
||||
}
|
||||
|
||||
if(e == noErr) {
|
||||
FSRef tempref = *tempfile;
|
||||
FSRef finalsrc, finaldest;
|
||||
// Must close the files early before deleting
|
||||
tempfile.reset(); // calls ~FSFile(), which calls FSCloseFork()
|
||||
file.reset();
|
||||
e = FSExchangeObjectsCompat(&tempref, &fref, &finalsrc, &finaldest);
|
||||
if(e == noErr)
|
||||
FSDeleteObject(&finalsrc);
|
||||
}
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
|
||||
UInt64 GetFileSize(FSPtr &file, void *)
|
||||
{
|
||||
FSRef fref = *file;
|
||||
FSCatalogInfo info;
|
||||
|
||||
OSErr e = FSGetCatalogInfo(
|
||||
&fref,
|
||||
kFSCatInfoDataSizes,
|
||||
&info,
|
||||
NULL, NULL, NULL);
|
||||
|
||||
return (e==noErr) ? info.dataLogicalSize : 0;
|
||||
}
|
||||
|
||||
|
||||
int CompareFileTime(FILETIME *a, FILETIME *b)
|
||||
{
|
||||
int result = 0;
|
||||
if(a->dwHighDateTime > b->dwHighDateTime) // guaranteed a > b
|
||||
result = 1;
|
||||
else if(a->dwHighDateTime < b->dwHighDateTime) // guaranteed a < b
|
||||
result = -1;
|
||||
else {
|
||||
if(a->dwLowDateTime > b->dwLowDateTime)
|
||||
result = 1;
|
||||
else if(a->dwLowDateTime < b->dwLowDateTime)
|
||||
result = -1;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
long SetFilePointer(FSPtr &file, long offset, void *, FilePointerType startpoint)
|
||||
{
|
||||
SInt16 forknum = *file;
|
||||
SInt64 updatedpos = 0;
|
||||
|
||||
UInt16 mode;
|
||||
switch(startpoint) {
|
||||
case FILE_BEGIN: mode = fsFromStart; break; // offset must be +ve
|
||||
case FILE_CURRENT: mode = fsFromMark; break;
|
||||
case FILE_END: mode = fsFromLEOF; break; // offset must be -ve
|
||||
default:
|
||||
return INVALID_SET_FILE_POINTER;
|
||||
}
|
||||
|
||||
OSErr e = FSSetForkPosition(forknum, mode, offset);
|
||||
// Duplicate behaviour of Win32 call by returning the updated position
|
||||
if(e==noErr)
|
||||
e = FSGetForkPosition(forknum, &updatedpos);
|
||||
|
||||
return (e==noErr) ? (long)updatedpos : INVALID_SET_FILE_POINTER;
|
||||
}
|
||||
|
||||
|
||||
void SetTimer(void *, TimerType id, int msec, void *)
|
||||
{
|
||||
switch(id) {
|
||||
|
@ -425,6 +356,26 @@ void SetTimer(void *, TimerType id, int msec, void *)
|
|||
}
|
||||
*/
|
||||
|
||||
|
||||
HGLOBAL WINAPI GlobalAlloc(UINT uFlags, SIZE_T dwBytes) {
|
||||
//TODO
|
||||
return NULL;
|
||||
}
|
||||
LPVOID WINAPI GlobalLock (HGLOBAL hMem) {
|
||||
//TODO
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BOOL WINAPI GlobalUnlock(HGLOBAL hMem) {
|
||||
//TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
HGLOBAL WINAPI GlobalFree(HGLOBAL hMem) {
|
||||
//TODO
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BOOL GetOpenFileName(LPOPENFILENAME openFilename) {
|
||||
//TODO
|
||||
return FALSE;
|
||||
|
@ -486,38 +437,12 @@ int MessageBox(HANDLE h, LPCTSTR szMessage, LPCTSTR title, int flags)
|
|||
return result;
|
||||
}
|
||||
|
||||
BOOL QueryPerformanceFrequency(PLARGE_INTEGER l)
|
||||
{
|
||||
// static struct mach_timebase_info timebase = { 0, 0 };
|
||||
// if (0 == timebase.denom)
|
||||
// mach_timebase_info(&timebase);
|
||||
//// l->LowPart = 1e9 * timebase.denom / timebase.numer;
|
||||
// l->QuadPart=1000000;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL QueryPerformanceCounter(PLARGE_INTEGER l)
|
||||
{
|
||||
// l->QuadPart = mach_absolute_time() / 1000;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
DWORD timeGetTime(void)
|
||||
{
|
||||
time_t t = time(NULL);
|
||||
return (DWORD)(t * 1000);
|
||||
}
|
||||
|
||||
void EnterCriticalSection(CRITICAL_SECTION *lock)
|
||||
{
|
||||
pthread_mutex_lock(lock);
|
||||
}
|
||||
|
||||
void LeaveCriticalSection(CRITICAL_SECTION *lock)
|
||||
{
|
||||
pthread_mutex_unlock(lock);
|
||||
}
|
||||
|
||||
BOOL GetSystemPowerStatus(LPSYSTEM_POWER_STATUS status)
|
||||
{
|
||||
status->ACLineStatus = AC_LINE_ONLINE;
|
||||
|
@ -534,10 +459,6 @@ BOOL GetWindowPlacement(HWND hWnd, WINDOWPLACEMENT *lpwndpl) { return 0; }
|
|||
BOOL SetWindowPlacement(HWND hWnd, CONST WINDOWPLACEMENT *lpwndpl) { return 0; }
|
||||
BOOL InvalidateRect(HWND hWnd, CONST RECT *lpRect, BOOL bErase) { return 0; }
|
||||
|
||||
DWORD ResumeThread(HANDLE hThread) {
|
||||
//TODO
|
||||
return 0;
|
||||
}
|
||||
int GetObject(HANDLE h, int c, LPVOID pv) {
|
||||
//TODO
|
||||
return 0;
|
||||
|
@ -645,20 +566,6 @@ BOOL WINAPI MessageBeep(UINT uType) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
HGLOBAL WINAPI GlobalAlloc(UINT uFlags, SIZE_T dwBytes) {
|
||||
//TODO
|
||||
return NULL;
|
||||
}
|
||||
LPVOID WINAPI GlobalLock (HGLOBAL hMem) {
|
||||
//TODO
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BOOL WINAPI GlobalUnlock(HGLOBAL hMem) {
|
||||
//TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
BOOL WINAPI OpenClipboard(HWND hWndNewOwner) {
|
||||
//TODO
|
||||
return 0;
|
||||
|
@ -688,29 +595,6 @@ HANDLE WINAPI GetClipboardData(UINT uFormat) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
HGLOBAL WINAPI GlobalFree(HGLOBAL hMem) {
|
||||
//TODO
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DWORD GetPrivateProfileString(LPCTSTR lpAppName, LPCTSTR lpKeyName, LPCTSTR lpDefault, LPTSTR lpReturnedString, DWORD nSize, LPCTSTR lpFileName) {
|
||||
//TODO
|
||||
#ifdef UNICODE
|
||||
wcsncpy(lpReturnedString, lpDefault, nSize);
|
||||
#else
|
||||
strncpy(lpReturnedString, lpDefault, nSize);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
UINT GetPrivateProfileInt(LPCTSTR lpAppName, LPCTSTR lpKeyName, INT nDefault, LPCTSTR lpFileName) {
|
||||
//TODO
|
||||
return nDefault;
|
||||
}
|
||||
BOOL WritePrivateProfileString(LPCTSTR lpAppName, LPCTSTR lpKeyName, LPCTSTR lpString, LPCTSTR lpFileName) {
|
||||
//TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
MMRESULT timeSetEvent(UINT uDelay, UINT uResolution, LPTIMECALLBACK fptc, DWORD_PTR dwUser, UINT fuEvent) {
|
||||
//TODO
|
||||
return 0; //No error
|
||||
|
|
|
@ -59,6 +59,9 @@ enum HANDLE_TYPE {
|
|||
typedef struct {
|
||||
int handleType;
|
||||
int fileDescriptor;
|
||||
size_t fileMappingSize;
|
||||
void* fileMappingAddress;
|
||||
pthread_t threadId;
|
||||
} _HANDLE;
|
||||
typedef _HANDLE * HANDLE;
|
||||
typedef HANDLE HPALETTE;
|
||||
|
|
Loading…
Reference in a new issue