729 lines
19 KiB
C
729 lines
19 KiB
C
//
|
|
// OSI.C
|
|
// Operating System Independent DLL
|
|
// * Graphical Output tracking (DDI hook/display driver)
|
|
// * Window/Task tracking (Window hook)
|
|
//
|
|
// Copyright(c) Microsoft 1997-
|
|
//
|
|
|
|
#include <as16.h>
|
|
|
|
#include <version.h>
|
|
#include <ndcgver.h>
|
|
|
|
|
|
|
|
PALETTEENTRY CODESEG g_osiVgaPalette[16] =
|
|
{
|
|
{0x00, 0x00, 0x00, 0x00}, // Black 0x00
|
|
{0x80, 0x00, 0x00, 0x00}, // Dk Red 0x01
|
|
{0x00, 0x80, 0x00, 0x00}, // Dk Green 0x02
|
|
{0x80, 0x80, 0x00, 0x00}, // Dk Yellow 0x03
|
|
{0x00, 0x00, 0x80, 0x00}, // Dk Blue 0x04
|
|
{0x80, 0x00, 0x80, 0x00}, // Dk Purple 0x05
|
|
{0x00, 0x80, 0x80, 0x00}, // Dk Teal 0x06
|
|
{0xC0, 0xC0, 0xC0, 0x00}, // Gray 0x07
|
|
{0x80, 0x80, 0x80, 0x00}, // Dk Gray 0x08 or 0xF8
|
|
{0xFF, 0x00, 0x00, 0x00}, // Red 0x09 or 0xF9
|
|
{0x00, 0xFF, 0x00, 0x00}, // Green 0x0A or 0xFA
|
|
{0xFF, 0xFF, 0x00, 0x00}, // Yellow 0x0B or 0xFB
|
|
{0x00, 0x00, 0xFF, 0x00}, // Blue 0x0C or 0xFC
|
|
{0xFF, 0x00, 0xFF, 0x00}, // Purple 0x0D or 0xFD
|
|
{0x00, 0xFF, 0xFF, 0x00}, // Teal 0x0E or 0xFE
|
|
{0xFF, 0xFF, 0xFF, 0x00} // White 0x0F or 0xFF
|
|
};
|
|
|
|
|
|
|
|
// --------------------------------------------------------------------------
|
|
//
|
|
// DllEntryPoint
|
|
//
|
|
// --------------------------------------------------------------------------
|
|
BOOL WINAPI DllEntryPoint(DWORD dwReason, WORD hInst, WORD wDS,
|
|
WORD wHeapSize, DWORD dwReserved1, WORD wReserved2)
|
|
{
|
|
switch (dwReason)
|
|
{
|
|
case DLL_PROCESS_ATTACH:
|
|
// First app pulled us in
|
|
if (g_cProcesses++ == 0)
|
|
{
|
|
g_hInstAs16 = (HINSTANCE)hInst;
|
|
}
|
|
break;
|
|
|
|
case DLL_PROCESS_DETACH:
|
|
// Last app went away
|
|
if (--g_cProcesses == 0)
|
|
{
|
|
// Clean up anything that got left around
|
|
OSITerm16(TRUE);
|
|
}
|
|
break;
|
|
}
|
|
|
|
return(TRUE);
|
|
}
|
|
|
|
|
|
|
|
//
|
|
// OSILoad16
|
|
// Called on process attach of mnmcpi32.dll, to establish the flat thunks
|
|
// and return back our instance handle
|
|
//
|
|
void WINAPI OSILoad16
|
|
(
|
|
LPDWORD lpdwInstance
|
|
)
|
|
{
|
|
DebugEntry(OSI_Load16);
|
|
|
|
*lpdwInstance = (DWORD)(UINT)g_hInstAs16;
|
|
|
|
DebugExitVOID(OSI_Load16);
|
|
}
|
|
|
|
|
|
|
|
|
|
// --------------------------------------------------------------------------
|
|
//
|
|
// OSIInit16
|
|
//
|
|
// Inits binary patcher, gdi + user patching, windows hooks, etc.
|
|
//
|
|
// --------------------------------------------------------------------------
|
|
BOOL WINAPI OSIInit16
|
|
(
|
|
DWORD version,
|
|
HWND hwndCore,
|
|
LPDWORD ppSharedMem,
|
|
LPDWORD ppoaSharedMem,
|
|
LPDWORD ppimSharedMem,
|
|
LPDWORD lpsbcEnabled,
|
|
LPDWORD ppShuntBuffers,
|
|
LPDWORD pBitmasks
|
|
)
|
|
{
|
|
BOOL rc = FALSE;
|
|
HGLOBAL hMem;
|
|
HMODULE hModDisplay;
|
|
|
|
DebugEntry(OSIInit16);
|
|
|
|
//
|
|
// Fill in our instance handle. We always return this so the 32-bit
|
|
// code can free our library after having loaded it.
|
|
//
|
|
*lpsbcEnabled = FALSE;
|
|
|
|
#ifdef DEBUG
|
|
g_imSharedData.cbSize = sizeof(g_imSharedData);
|
|
#endif
|
|
|
|
*ppimSharedMem = (DWORD)MapSL(&g_imSharedData);
|
|
ASSERT(*ppimSharedMem);
|
|
|
|
if (version != DCS_MAKE_VERSION())
|
|
{
|
|
ERROR_OUT(("OSIInit16: failing, version mismatch 0x%lx (core) 0x%lx (dd)",
|
|
version, DCS_MAKE_VERSION()));
|
|
DC_QUIT;
|
|
}
|
|
|
|
// ONLY ALLOW ONE CLIENT TO INITIALIZE
|
|
if (g_asMainWindow != NULL)
|
|
{
|
|
WARNING_OUT(("OSIInit16: mnmas16.dll was left around last time"));
|
|
|
|
// If this task is no longer valid, then cleanup for it
|
|
if (IsWindow(g_asMainWindow))
|
|
{
|
|
//
|
|
// Uh oh. Somehow a previous version of NM is still around.
|
|
// Do the safest thing--refuse to share.
|
|
//
|
|
ERROR_OUT(("OSIInit16: Another version of NetMeeting is still running!"));
|
|
DC_QUIT;
|
|
}
|
|
|
|
// Cleanup (this is similar to the NT dd code)
|
|
OSITerm16(TRUE);
|
|
ASSERT(!g_asMainWindow);
|
|
}
|
|
|
|
//
|
|
// Clear out shared IM memory.
|
|
//
|
|
g_imSharedData.imSuspended = FALSE;
|
|
g_imSharedData.imControlled = FALSE;
|
|
g_imSharedData.imPaused = FALSE;
|
|
g_imSharedData.imUnattended = FALSE;
|
|
|
|
g_asMainWindow = hwndCore;
|
|
ASSERT(g_asMainWindow);
|
|
g_hCoreTask = GetCurrentTask();
|
|
|
|
g_osiDesktopWindow = GetDesktopWindow();
|
|
ASSERT(g_osiDesktopWindow);
|
|
|
|
//
|
|
// DISPLAY DRIVER STUFF
|
|
//
|
|
hModDisplay = GetModuleHandle("DISPLAY");
|
|
g_lpfnSetCursor = (SETCURSORPROC)GetProcAddress(hModDisplay,
|
|
MAKEINTRESOURCE(ORD_OEMSETCURSOR));
|
|
if (!hModDisplay || !g_lpfnSetCursor)
|
|
{
|
|
ERROR_OUT(("Couldn't find cursor entry points"));
|
|
DC_QUIT;
|
|
}
|
|
|
|
// This doesn't always exist
|
|
g_lpfnSaveBits = (SAVEBITSPROC)GetProcAddress(hModDisplay,
|
|
MAKEINTRESOURCE(ORD_OEMSAVEBITS));
|
|
|
|
//
|
|
// KERNEL16 AND KERNEL32 STUFF
|
|
//
|
|
|
|
//
|
|
// Get KRNL16's instance/module handle
|
|
//
|
|
g_hInstKrnl16 = LoadLibrary("KRNL386.EXE");
|
|
ASSERT(g_hInstKrnl16);
|
|
FreeLibrary(g_hInstKrnl16);
|
|
|
|
g_hModKrnl16 = GetExePtr(g_hInstKrnl16);
|
|
ASSERT(g_hModKrnl16);
|
|
|
|
//
|
|
// Get KERNEL32's instance/module handle
|
|
//
|
|
g_hInstKrnl32 = GetModuleHandle32("KERNEL32.DLL");
|
|
ASSERT(g_hInstKrnl32);
|
|
|
|
//
|
|
// Get mapped 16-bit equivalent of KERNEL32's instance handle
|
|
//
|
|
g_hInstKrnl32MappedTo16 = MapInstance32(g_hInstKrnl32);
|
|
ASSERT(g_hInstKrnl32MappedTo16);
|
|
|
|
//
|
|
// Get hold of MultiByteToWideChar() routine
|
|
//
|
|
g_lpfnAnsiToUni = (ANSITOUNIPROC)GetProcAddress32(g_hInstKrnl32,
|
|
"MultiByteToWideChar");
|
|
ASSERT(g_lpfnAnsiToUni);
|
|
|
|
|
|
//
|
|
// GDI16 AND GDI32 STUFF
|
|
//
|
|
|
|
//
|
|
// Get GDI16's instance/module handle
|
|
//
|
|
g_hInstGdi16 = LoadLibrary("GDI.EXE");
|
|
ASSERT(g_hInstGdi16);
|
|
FreeLibrary(g_hInstGdi16);
|
|
|
|
g_hModGdi16 = GetExePtr(g_hInstGdi16);
|
|
ASSERT(g_hModGdi16);
|
|
|
|
//
|
|
// Get GDI32's instance/module handle
|
|
//
|
|
g_hInstGdi32 = GetModuleHandle32("GDI32.DLL");
|
|
ASSERT(g_hInstGdi32);
|
|
|
|
//
|
|
// Get hold of GDI16 functions not exported but which are the target of
|
|
// public GDI32 functions via flat thunks
|
|
//
|
|
if (!GetGdi32OnlyExport("ExtTextOutW", 0, (FARPROC FAR*)&g_lpfnExtTextOutW) ||
|
|
!GetGdi32OnlyExport("TextOutW", 0, (FARPROC FAR*)&g_lpfnTextOutW) ||
|
|
!GetGdi32OnlyExport("PolylineTo", 0, (FARPROC FAR*)&g_lpfnPolylineTo) ||
|
|
!GetGdi32OnlyExport("PolyPolyline", 18, (FARPROC FAR*)&g_lpfnPolyPolyline))
|
|
{
|
|
ERROR_OUT(("Couldn't get hold of GDI32 routines"));
|
|
DC_QUIT;
|
|
}
|
|
|
|
ASSERT(g_lpfnExtTextOutW);
|
|
ASSERT(g_lpfnTextOutW);
|
|
ASSERT(g_lpfnPolylineTo);
|
|
ASSERT(g_lpfnPolyPolyline);
|
|
|
|
|
|
//
|
|
// USER16 and USER32 STUFF
|
|
//
|
|
|
|
//
|
|
// Get USER16's instance/module handle
|
|
//
|
|
g_hInstUser16 = LoadLibrary("USER.EXE");
|
|
ASSERT(g_hInstUser16);
|
|
FreeLibrary(g_hInstUser16);
|
|
|
|
g_hModUser16 = GetExePtr(g_hInstUser16);
|
|
ASSERT(g_hModUser16);
|
|
|
|
//
|
|
// Get hold of USER32's instance handle. It has functions we
|
|
// want to call which USER16 doesn't export.
|
|
//
|
|
g_hInstUser32 = GetModuleHandle32("USER32.DLL");
|
|
ASSERT(g_hInstUser32);
|
|
|
|
|
|
//
|
|
// Get hold of USER16 functions not exported but which are the target of
|
|
// public USER32 functions via flat thunks
|
|
//
|
|
if (!GetUser32OnlyExport("GetWindowThreadProcessId", (FARPROC FAR*)&g_lpfnGetWindowThreadProcessId))
|
|
{
|
|
ERROR_OUT(("Couldn't get hold of USER32 routines"));
|
|
DC_QUIT;
|
|
}
|
|
|
|
ASSERT(g_lpfnGetWindowThreadProcessId);
|
|
|
|
//
|
|
// This exists in Memphis but not Win95
|
|
//
|
|
g_lpfnCDSEx = (CDSEXPROC)GetProcAddress(g_hModUser16, "ChangeDisplaySettingsEx");
|
|
|
|
|
|
//
|
|
// Allocate the shared memory we use to communicate with the 32-bit
|
|
// share core.
|
|
//
|
|
ASSERT(!g_asSharedMemory);
|
|
ASSERT(!g_poaData[0]);
|
|
ASSERT(!g_poaData[1]);
|
|
|
|
//
|
|
// Allocate our blocks GMEM_SHARE so we aren't bound by the vagaries
|
|
// of process ownership. We want our DLL to control them. Note that
|
|
// we do the same thing with GDI objects we create--our module owns the.
|
|
//
|
|
// We use GMEM_FIXED since we map these to flat addresses for mnmcpi32.dll,
|
|
// and we don't want the linear address of these memory blocks to move
|
|
// afterwards.
|
|
//
|
|
hMem = GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT | GMEM_SHARE, sizeof(SHM_SHARED_MEMORY));
|
|
g_asSharedMemory = MAKELP(hMem, 0);
|
|
|
|
hMem = GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT | GMEM_SHARE, sizeof(OA_SHARED_DATA));
|
|
g_poaData[0] = MAKELP(hMem, 0);
|
|
|
|
hMem = GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT | GMEM_SHARE, sizeof(OA_SHARED_DATA));
|
|
g_poaData[1] = MAKELP(hMem, 0);
|
|
|
|
if (!g_asSharedMemory ||
|
|
!g_poaData[0] ||
|
|
!g_poaData[1])
|
|
{
|
|
ERROR_OUT(("OSIInit16: couldn't allocate shared memory blocks"));
|
|
DC_QUIT;
|
|
}
|
|
|
|
//
|
|
// Get current screen attributes
|
|
//
|
|
|
|
g_oeStockPalette = GetStockObject(DEFAULT_PALETTE);
|
|
|
|
g_osiScreenRect.left = 0;
|
|
g_osiScreenRect.top = 0;
|
|
g_osiScreenRect.right = GetSystemMetrics(SM_CXSCREEN);
|
|
g_osiScreenRect.bottom = GetSystemMetrics(SM_CYSCREEN);
|
|
|
|
g_osiScreenDC = CreateDC("DISPLAY", 0L, 0L, 0L);
|
|
g_osiMemoryDC = CreateCompatibleDC(g_osiScreenDC);
|
|
g_osiMemoryBMP = CreateCompatibleBitmap(g_osiScreenDC, 1, 1);
|
|
|
|
if (!g_osiScreenDC || !g_osiMemoryDC || !g_osiMemoryBMP)
|
|
{
|
|
ERROR_OUT(("Couldn't get screen dc"));
|
|
DC_QUIT;
|
|
}
|
|
|
|
SetObjectOwner(g_osiScreenDC, g_hInstAs16);
|
|
|
|
SetObjectOwner(g_osiMemoryDC, g_hInstAs16);
|
|
|
|
SetObjectOwner(g_osiMemoryBMP, g_hInstAs16);
|
|
MakeObjectPrivate(g_osiMemoryBMP, TRUE);
|
|
|
|
g_osiScreenBitsPlane = GetDeviceCaps(g_osiScreenDC, BITSPIXEL);
|
|
g_osiScreenPlanes = GetDeviceCaps(g_osiScreenDC, PLANES);
|
|
g_osiScreenBPP = (g_osiScreenBitsPlane * g_osiScreenPlanes);
|
|
|
|
|
|
//
|
|
// Get the color masks
|
|
//
|
|
|
|
g_osiScreenRedMask = 0x000000FF;
|
|
g_osiScreenGreenMask = 0x0000FF00;
|
|
g_osiScreenBlueMask = 0x00FF0000;
|
|
|
|
//
|
|
// Only displays with more than 8bpp (palettized) might have color
|
|
// masks. Use our 1 pixel scratch bitmap to get them.
|
|
//
|
|
if (g_osiScreenBPP > 8)
|
|
{
|
|
DIB4 dib4T;
|
|
|
|
//
|
|
// Get the header
|
|
//
|
|
dib4T.bi.biSize = sizeof(BITMAPINFOHEADER);
|
|
dib4T.bi.biBitCount = 0;
|
|
GetDIBits(g_osiScreenDC, g_osiMemoryBMP, 0, 1, NULL, (LPBITMAPINFO)&dib4T.bi,
|
|
DIB_RGB_COLORS);
|
|
|
|
//
|
|
// Get the mask
|
|
//
|
|
GetDIBits(g_osiScreenDC, g_osiMemoryBMP, 0, 1, NULL, (LPBITMAPINFO)&dib4T.bi,
|
|
DIB_RGB_COLORS);
|
|
|
|
if (dib4T.bi.biCompression == BI_BITFIELDS)
|
|
{
|
|
g_osiScreenRedMask = dib4T.ct[0];
|
|
g_osiScreenGreenMask = dib4T.ct[1];
|
|
g_osiScreenBlueMask = dib4T.ct[2];
|
|
}
|
|
}
|
|
|
|
g_osiMemoryOld = SelectBitmap(g_osiMemoryDC, g_osiMemoryBMP);
|
|
|
|
//
|
|
// Initialize the bmiHeader so OEConvertColor() doesn't have to do it
|
|
// over and over, when the header isn't touched by GDI.
|
|
//
|
|
g_osiScreenBMI.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
|
g_osiScreenBMI.bmiHeader.biPlanes = 1;
|
|
g_osiScreenBMI.bmiHeader.biBitCount = g_osiScreenBPP;
|
|
g_osiScreenBMI.bmiHeader.biCompression = BI_RGB;
|
|
g_osiScreenBMI.bmiHeader.biSizeImage = 0;
|
|
g_osiScreenBMI.bmiHeader.biXPelsPerMeter = 1000;
|
|
g_osiScreenBMI.bmiHeader.biYPelsPerMeter = 1000;
|
|
g_osiScreenBMI.bmiHeader.biClrUsed = 0;
|
|
g_osiScreenBMI.bmiHeader.biClrImportant = 0;
|
|
g_osiScreenBMI.bmiHeader.biWidth = 1;
|
|
g_osiScreenBMI.bmiHeader.biHeight = 1;
|
|
|
|
|
|
//
|
|
// Init the various display driver components
|
|
//
|
|
BA_DDInit();
|
|
|
|
if (!CM_DDInit(g_osiScreenDC))
|
|
{
|
|
ERROR_OUT(("CM failed to init"));
|
|
DC_QUIT;
|
|
}
|
|
|
|
if (!SSI_DDInit())
|
|
{
|
|
ERROR_OUT(("SSI failed to init"));
|
|
DC_QUIT;
|
|
}
|
|
|
|
if (!OE_DDInit())
|
|
{
|
|
ERROR_OUT(("OE failed to init"));
|
|
DC_QUIT;
|
|
}
|
|
|
|
if (!IM_DDInit())
|
|
{
|
|
ERROR_OUT(("IM failed to init"));
|
|
DC_QUIT;
|
|
}
|
|
|
|
if (!HET_DDInit())
|
|
{
|
|
ERROR_OUT(("HET failed to init"));
|
|
DC_QUIT;
|
|
}
|
|
|
|
//
|
|
// If we're here, all succeeded initializing
|
|
//
|
|
//
|
|
// Map ptrs to flat addresses so they can be used in 32-bit code. This
|
|
// can't fail unless kernel is so messed up Windows is about to keel
|
|
// over and die.
|
|
//
|
|
ASSERT(ppSharedMem);
|
|
*ppSharedMem = (DWORD)MapSL(g_asSharedMemory);
|
|
ASSERT(*ppSharedMem);
|
|
|
|
ASSERT(ppoaSharedMem);
|
|
ppoaSharedMem[0] = (DWORD)MapSL(g_poaData[0]);
|
|
ASSERT(ppoaSharedMem[0]);
|
|
|
|
ppoaSharedMem[1] = (DWORD)MapSL(g_poaData[1]);
|
|
ASSERT(ppoaSharedMem[1]);
|
|
|
|
rc = TRUE;
|
|
|
|
DC_EXIT_POINT:
|
|
DebugExitBOOL(OSIInit16, rc);
|
|
return(rc);
|
|
}
|
|
|
|
|
|
// --------------------------------------------------------------------------
|
|
//
|
|
// OSITerm16
|
|
// Cleans up binary patcher, gdi + user patching, windows hooks, etc.
|
|
//
|
|
// We do this on normal OSI stop, and on catastrophic failure.
|
|
//
|
|
// --------------------------------------------------------------------------
|
|
void WINAPI OSITerm16(BOOL fUnloading)
|
|
{
|
|
DebugEntry(OSITerm16);
|
|
|
|
if (!g_hCoreTask)
|
|
{
|
|
// Nothing to cleanup.
|
|
DC_QUIT;
|
|
}
|
|
|
|
//
|
|
// Is the task that actually caused us to allocate our resources? In
|
|
// other words, we don't want to clean up if
|
|
// App A loads mnmas16.dll, and gets it inited
|
|
// App B somehow starts up, loads mnmas16.dll, but mnmas16.dll
|
|
// doesn't init for sharing because cProcesses is > 1
|
|
// App B shuts down
|
|
// App B calls OSITerm16
|
|
//
|
|
// So in the 'dll is really about to go away case', we always cleanup.
|
|
// But in normal term of sharing, we cleanup if the current task is the
|
|
// current one.
|
|
//
|
|
if (fUnloading || (g_hCoreTask == GetCurrentTask()))
|
|
{
|
|
//
|
|
// Term other pieces that depend on layout of shared memory
|
|
//
|
|
HET_DDTerm();
|
|
|
|
IM_DDTerm();
|
|
|
|
OE_DDTerm();
|
|
|
|
SSI_DDTerm();
|
|
|
|
CM_DDTerm();
|
|
|
|
//
|
|
// Free memory blocks
|
|
//
|
|
|
|
if (g_poaData[1])
|
|
{
|
|
GlobalFree((HGLOBAL)SELECTOROF(g_poaData[1]));
|
|
g_poaData[1] = NULL;
|
|
}
|
|
|
|
if (g_poaData[0])
|
|
{
|
|
GlobalFree((HGLOBAL)SELECTOROF(g_poaData[0]));
|
|
g_poaData[0] = NULL;
|
|
}
|
|
|
|
if (g_asSharedMemory)
|
|
{
|
|
GlobalFree((HGLOBAL)SELECTOROF(g_asSharedMemory));
|
|
g_asSharedMemory = NULL;
|
|
}
|
|
|
|
if (g_osiMemoryOld)
|
|
{
|
|
SelectBitmap(g_osiMemoryDC, g_osiMemoryOld);
|
|
g_osiMemoryOld = NULL;
|
|
}
|
|
|
|
if (g_osiMemoryBMP)
|
|
{
|
|
SysDeleteObject(g_osiMemoryBMP);
|
|
g_osiMemoryBMP = NULL;
|
|
}
|
|
|
|
if (g_osiMemoryDC)
|
|
{
|
|
DeleteDC(g_osiMemoryDC);
|
|
g_osiMemoryDC = NULL;
|
|
}
|
|
|
|
if (g_osiScreenDC)
|
|
{
|
|
DeleteDC(g_osiScreenDC);
|
|
g_osiScreenDC = NULL;
|
|
}
|
|
|
|
g_asMainWindow = NULL;
|
|
g_hCoreTask = NULL;
|
|
}
|
|
|
|
DC_EXIT_POINT:
|
|
DebugExitVOID(OSITerm16);
|
|
}
|
|
|
|
|
|
|
|
// --------------------------------------------------------------------------
|
|
//
|
|
// OSIFunctionRequest16
|
|
//
|
|
// Communication function with 32-bit MNMCPI32.DLL
|
|
//
|
|
// --------------------------------------------------------------------------
|
|
BOOL WINAPI OSIFunctionRequest16(DWORD fnEscape, LPOSI_ESCAPE_HEADER lpOsiEsc,
|
|
DWORD cbEscInfo)
|
|
{
|
|
|
|
BOOL rc = FALSE;
|
|
|
|
DebugEntry(OSIFunctionRequest16);
|
|
|
|
//
|
|
// Check the data is long enough to store our standard escape header.
|
|
// If it is not big enough this must be an escape request for another
|
|
// driver.
|
|
//
|
|
if (cbEscInfo < sizeof(OSI_ESCAPE_HEADER))
|
|
{
|
|
ERROR_OUT(("Escape block not big enough"));
|
|
DC_QUIT;
|
|
}
|
|
|
|
//
|
|
// Check for our escape ID. If it is not our escape ID this must be an
|
|
// escape request for another driver.
|
|
//
|
|
if (lpOsiEsc->identifier != OSI_ESCAPE_IDENTIFIER)
|
|
{
|
|
ERROR_OUT(("Bogus Escape header ID"));
|
|
DC_QUIT;
|
|
}
|
|
else if (lpOsiEsc->version != DCS_MAKE_VERSION())
|
|
{
|
|
ERROR_OUT(("Mismatched display driver and NetMeeting"));
|
|
DC_QUIT;
|
|
}
|
|
|
|
|
|
if ((fnEscape >= OSI_ESC_FIRST) && (fnEscape <= OSI_ESC_LAST))
|
|
{
|
|
rc = OSI_DDProcessRequest((UINT)fnEscape, lpOsiEsc, cbEscInfo);
|
|
}
|
|
else if ((fnEscape >= OSI_OE_ESC_FIRST) && (fnEscape <= OSI_OE_ESC_LAST))
|
|
{
|
|
rc = OE_DDProcessRequest((UINT)fnEscape, lpOsiEsc, cbEscInfo);
|
|
}
|
|
else if ((fnEscape >= OSI_HET_ESC_FIRST) && (fnEscape <= OSI_HET_ESC_LAST))
|
|
{
|
|
rc = HET_DDProcessRequest((UINT)fnEscape, lpOsiEsc, cbEscInfo);
|
|
}
|
|
else if ((fnEscape >= OSI_SBC_ESC_FIRST) && (fnEscape <= OSI_SBC_ESC_LAST))
|
|
{
|
|
// Do nothing
|
|
}
|
|
else if ((fnEscape >= OSI_SSI_ESC_FIRST) && (fnEscape <= OSI_SSI_ESC_LAST))
|
|
{
|
|
rc = SSI_DDProcessRequest((UINT)fnEscape, lpOsiEsc, cbEscInfo);
|
|
}
|
|
else if ((fnEscape >= OSI_CM_ESC_FIRST) && (fnEscape <= OSI_CM_ESC_LAST))
|
|
{
|
|
rc = CM_DDProcessRequest((UINT)fnEscape, lpOsiEsc, cbEscInfo);
|
|
}
|
|
else if ((fnEscape >= OSI_OA_ESC_FIRST) && (fnEscape <= OSI_OA_ESC_LAST))
|
|
{
|
|
rc = OA_DDProcessRequest((UINT)fnEscape, lpOsiEsc, cbEscInfo);
|
|
}
|
|
else if ((fnEscape >= OSI_BA_ESC_FIRST) && (fnEscape <= OSI_BA_ESC_LAST))
|
|
{
|
|
rc = BA_DDProcessRequest((UINT)fnEscape, lpOsiEsc, cbEscInfo);
|
|
}
|
|
else if ((fnEscape >= OSI_HET_WO_ESC_FIRST) && (fnEscape <= OSI_HET_WO_ESC_LAST))
|
|
{
|
|
rc = HET_DDProcessRequest((UINT)fnEscape, lpOsiEsc, cbEscInfo);
|
|
}
|
|
else
|
|
{
|
|
ERROR_OUT(("Unknown function request"));
|
|
}
|
|
|
|
DC_EXIT_POINT:
|
|
DebugExitBOOL(OSIFunctionRequest16, rc);
|
|
return(rc);
|
|
}
|
|
|
|
|
|
|
|
//
|
|
// OSI_DDProcessRequest()
|
|
// Handles OSI generic escapes
|
|
//
|
|
BOOL OSI_DDProcessRequest
|
|
(
|
|
UINT fnEscape,
|
|
LPOSI_ESCAPE_HEADER pResult,
|
|
DWORD cbResult
|
|
)
|
|
{
|
|
BOOL rc;
|
|
|
|
DebugEntry(OSI_DDProcessRequest);
|
|
|
|
switch (fnEscape)
|
|
{
|
|
case OSI_ESC_SYNC_NOW:
|
|
{
|
|
ASSERT(cbResult == sizeof(OSI_ESCAPE_HEADER));
|
|
|
|
//
|
|
// Resync with the 32-bit ring 3 core. This happens when
|
|
// somebody joins or leaves a share.
|
|
//
|
|
BA_ResetBounds();
|
|
OA_DDSyncUpdatesNow();
|
|
rc = TRUE;
|
|
|
|
}
|
|
break;
|
|
|
|
default:
|
|
{
|
|
ERROR_OUT(("Unrecognized OSI escape"));
|
|
rc = FALSE;
|
|
}
|
|
break;
|
|
}
|
|
|
|
DebugExitBOOL(OSI_DDProcessRequest, rc);
|
|
return(rc);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|