void win16_probe_for_wine() { /* Probing for WINE from the Win16 layer */ DWORD callw,retv; if (!genthunk32_init()) return; if (genthunk32w_ntdll == 0) return; callw = __GetProcAddress32W(genthunk32w_ntdll,"wine_get_version"); if (callw == 0) return; retv = __CallProcEx32W(CPEX_DEST_STDCALL/*nothing to convert*/,0/*0 param*/,callw); if (retv == 0) return; windows_emulation = WINEMU_WINE; { /* NTS: We assume that WINE, just like real Windows, will not move or relocate * NTDLL.DLL and will not move the string it just returned. */ /* TODO: You need a function the host program can call to free the selector * you allocated here, in case it wants to reclaim resources */ uint16_t sel; uint16_t myds=0; __asm mov myds,ds sel = AllocSelector(myds); if (sel != 0) { /* the selector is directed at the string, then retained in this * code as a direct FAR pointer to WINE's version string */ SetSelectorBase(sel,retv); SetSelectorLimit(sel,0xFFF); /* WINE's version string is rarely longer than 14 chars */ windows_emulation_comment_str = MK_FP(sel,0); } } }
WORD FAR PASCAL __loadds GetRing0Callgate( DWORD func_address, unsigned cParams ) { CALLGATE_DESCRIPTOR far *callgate_desc; CODE_SEG_DESCRIPTOR far *ring0_desc; unsigned short ldt_alias; unsigned short ring_0_alias; unsigned short callgate_selector; if ( (ldt_alias = GetLDTAlias()) == 0 ) return 0; // // Grab a selector from Windows to use as the CS at ring 0 // if ( !(ring_0_alias = AllocSelector(0)) ) return 0; // // Set up the fields in the descriptor to be a ring 0, flat model seg // ring0_desc = MAKELP( ldt_alias, ring_0_alias & 0xFFF8 ); ring0_desc->limit_0_15 = 0xFFFF; ring0_desc->base_0_15 = 0; ring0_desc->base_16_23 = 0; ring0_desc->readable = 1; ring0_desc->conforming = 0; ring0_desc->code_data = 1; ring0_desc->app_system = 1; ring0_desc->dpl = 0; ring0_desc->present = 1; ring0_desc->limit_16_19 = 0xF; ring0_desc->always_0 = 0; ring0_desc->seg_16_32 = 1; ring0_desc->granularity = 1; ring0_desc->base_24_31 = 0; // // Allocate the selector that'll be used for the call gate // if ( (callgate_selector= AllocSelector(0)) == 0 ) { FreeSelector( ring_0_alias ); return 0; } // // Create a pointer to the call gate descriptor // callgate_desc = MAKELP( ldt_alias, callgate_selector & 0xFFF8 ); // // Fill in the fields of the call gate descriptor with the // appropriate values for a 16 bit callgate. // callgate_desc->offset_0_15 = LOWORD( func_address ); callgate_desc->selector = ring_0_alias; callgate_desc->param_count = cParams; callgate_desc->some_bits = 0; callgate_desc->type = 0xC; // 386 call gate callgate_desc->app_system = 0; // A system descriptor callgate_desc->dpl = 3; // Ring 3 code can call callgate_desc->present = 1; callgate_desc->offset_16_31 = HIWORD(func_address); return callgate_selector; }