static void MZ_Launch( LPCSTR cmdtail, int length ) { TDB *pTask = GlobalLock16( GetCurrentTask() ); BYTE *psp_start = PTR_REAL_TO_LIN( DOSVM_psp, 0 ); DWORD rv; SYSLEVEL *lock; MZ_FillPSP(psp_start, cmdtail, length); pTask->flags |= TDBF_WINOLDAP; /* DTA is set to PSP:0080h when a program is started. */ pTask->dta = MAKESEGPTR( DOSVM_psp, 0x80 ); GetpWin16Lock( &lock ); _LeaveSysLevel( lock ); ResumeThread(dosvm_thread); rv = DOSVM_Loop(dosvm_thread); CloseHandle(dosvm_thread); dosvm_thread = 0; dosvm_tid = 0; CloseHandle(loop_thread); loop_thread = 0; loop_tid = 0; VGA_Clean(); ExitProcess(rv); }
static DWORD MZ_Launch( LPCSTR cmdtail, int length ) { TDB *pTask = GlobalLock16( GetCurrentTask() ); BYTE *psp_start = PTR_REAL_TO_LIN( DOSVM_psp, 0 ); DWORD rv; SYSLEVEL *lock; MSG msg; MZ_FillPSP(psp_start, cmdtail, length); pTask->flags |= TDBF_WINOLDAP; /* DTA is set to PSP:0080h when a program is started. */ pTask->dta = MAKESEGPTR( DOSVM_psp, 0x80 ); GetpWin16Lock( &lock ); _LeaveSysLevel( lock ); /* force the message queue to be created */ PeekMessageW(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE); ResumeThread(dosvm_thread); rv = DOSVM_Loop(dosvm_thread); CloseHandle(dosvm_thread); dosvm_thread = 0; dosvm_tid = 0; CloseHandle(loop_thread); loop_thread = 0; loop_tid = 0; if (rv) return rv; VGA_Clean(); ExitProcess(0); }
/*********************************************************************** * GDI_ReallocObject * * The object ptr must have been obtained with GDI_GetObjPtr. * The new pointer must be released with GDI_ReleaseObj. */ void *GDI_ReallocObject( WORD size, HGDIOBJ handle, void *object ) { HGDIOBJ new_handle; /* Large handles are done differently */ if( !((UINT_PTR)handle & 2) ) return realloc_large_heap( size, handle ); LOCAL_Unlock( GDI_HeapSel, handle ); if (!(new_handle = LOCAL_ReAlloc( GDI_HeapSel, handle, size, LMEM_MOVEABLE ))) { TRACE_SEC( handle, "leave" ); _LeaveSysLevel( &GDI_level ); return NULL; } assert( new_handle == handle ); /* moveable handle cannot change */ return LOCAL_Lock( GDI_HeapSel, handle ); }
/*********************************************************************** * GDI_GetObjPtr * * Return a pointer to the GDI object associated to the handle. * Return NULL if the object has the wrong magic number. * The object must be released with GDI_ReleaseObj. */ void *GDI_GetObjPtr( HGDIOBJ handle, WORD magic ) { GDIOBJHDR *ptr = NULL; _EnterSysLevel( &GDI_level ); if ((UINT_PTR)handle & 2) /* GDI heap handle */ { ptr = (GDIOBJHDR *)LOCAL_Lock( GDI_HeapSel, handle ); if (ptr) { if (((magic != MAGIC_DONTCARE) && (GDIMAGIC(ptr->wMagic) != magic)) || (GDIMAGIC(ptr->wMagic) < FIRST_MAGIC) || (GDIMAGIC(ptr->wMagic) > LAST_MAGIC)) { LOCAL_Unlock( GDI_HeapSel, handle ); ptr = NULL; } } } else /* large heap handle */ { int i = ((UINT_PTR)handle >> 2) - FIRST_LARGE_HANDLE; if (i >= 0 && i < MAX_LARGE_HANDLES) { ptr = large_handles[i]; if (ptr && (magic != MAGIC_DONTCARE) && (GDIMAGIC(ptr->wMagic) != magic)) ptr = NULL; } } if (!ptr) { _LeaveSysLevel( &GDI_level ); SetLastError( ERROR_INVALID_HANDLE ); WARN( "Invalid handle %x\n", handle ); } else TRACE_SEC( handle, "enter" ); return ptr; }
/*********************************************************************** * GDI_AllocObject */ void *GDI_AllocObject( WORD size, WORD magic, HGDIOBJ *handle ) { GDIOBJHDR *obj; _EnterSysLevel( &GDI_level ); switch(magic) { /* allocate DCs and other large or commonly allocated objects on the larger heap */ case DC_MAGIC: case DISABLED_DC_MAGIC: case META_DC_MAGIC: case METAFILE_MAGIC: case METAFILE_DC_MAGIC: case ENHMETAFILE_MAGIC: case ENHMETAFILE_DC_MAGIC: case BITMAP_MAGIC: case PALETTE_MAGIC: if (!(obj = alloc_large_heap( size, handle ))) goto error; break; default: if (!(*handle = LOCAL_Alloc( GDI_HeapSel, LMEM_MOVEABLE, size ))) goto error; assert( (UINT_PTR)*handle & 2 ); obj = (GDIOBJHDR *)LOCAL_Lock( GDI_HeapSel, *handle ); break; } obj->hNext = 0; obj->wMagic = magic|OBJECT_NOSYSTEM; obj->dwCount = 0; TRACE_SEC( *handle, "enter" ); return obj; error: _LeaveSysLevel( &GDI_level ); *handle = 0; return NULL; }
/*********************************************************************** * GDI_FreeObject */ BOOL GDI_FreeObject( HGDIOBJ handle, void *ptr ) { GDIOBJHDR *object = ptr; object->wMagic = 0; /* Mark it as invalid */ if ((UINT_PTR)handle & 2) /* GDI heap handle */ { LOCAL_Unlock( GDI_HeapSel, handle ); LOCAL_Free( GDI_HeapSel, handle ); } else /* large heap handle */ { int i = ((UINT_PTR)handle >> 2) - FIRST_LARGE_HANDLE; if (i >= 0 && i < MAX_LARGE_HANDLES && large_handles[i]) { HeapFree( GetProcessHeap(), 0, large_handles[i] ); large_handles[i] = NULL; } else ERR( "Invalid handle %x\n", handle ); } TRACE_SEC( handle, "leave" ); _LeaveSysLevel( &GDI_level ); return TRUE; }
/*********************************************************************** * GDI_ReleaseObj * */ void GDI_ReleaseObj( HGDIOBJ handle ) { if ((UINT_PTR)handle & 2) LOCAL_Unlock( GDI_HeapSel, handle ); TRACE_SEC( handle, "leave" ); _LeaveSysLevel( &GDI_level ); }
/*********************************************************************** * USER_Unlock */ void USER_Unlock(void) { _LeaveSysLevel( &USER_SysLevel ); }