Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

325 lines
9.0 KiB

/***************************************************************************\
* Module Name: subutil.c
*
* Section initialization code for client/server batching.
*
* Copyright (c) 1993 Microsoft Corporation *
\***************************************************************************/
#include "precomp.h"
#pragma hdrstop
#include <ntcsrdll.h> // CSR declarations and data structures.
#include <ntcsrsrv.h>
#include "glgdimsg.h"
static void APIENTRY glsbsrvCloseAndDestroySection(void);
/******************************Public*Routine******************************\
* glsrvThreadExit
*
* This function is called when a server thread using OpenGL exits.
* It is currently called from UserException in usersrv.
*
* History:
* Mon Dec 27 12:01:22 1993 -by- Hock San Lee [hockl]
* Rewrote it.
\**************************************************************************/
void APIENTRY glsrvThreadExit(void)
{
__GLGENcontext *gengc;
DBGENTRY("glsrvThreadExit\n");
ASSERTOPENGL(GLTEB_SRVSHAREDSECTIONINFO() && GLTEB_SRVSHAREDMEMORYSECTION(),
"Section does not exist!\n");
// XXX Release the RC
GLTEB_SET_SRVCURRENTRC(NULL);
GLTEB_SET_SRVPROCTABLE((__GLdispatchState *)NULL,FALSE);
// Global semaphores are released by the usersrv exception cleanup code,
// but the per-WNDOBJ semaphore will have to be cleaned up by us.
if ( (gengc = GLTEB_SRVCONTEXT()) != (__GLGENcontext *) NULL )
{
if (gengc->pwo != NULL && gengc->iDCType != DCTYPE_INFO)
{
wglReleaseWndobjLock((PVOID) gengc->pwo);
}
#ifdef NT_SERVER_SHARE_LISTS
__glDlistThreadCleanup((__GLcontext *)gengc);
#endif
}
// XXX Cleanup Context
GLTEB_SET_SRVCONTEXT(NULL);
// Free the section
glsbsrvCloseAndDestroySection();
}
/******************************Public*Routine******************************\
* glsrvDuplicateSection
*
* This function is called only once per thread to create and duplicate
* a shared section between the client and server generic driver.
*
* The shared section is destroyed independently by the client and the server
* when the thread terminates.
*
* This function updates GLTEB_SRVSHAREDSECTIONINFO and
* GLTEB_SRVSHAREDMEMORYSECTION.
*
* History:
* Mon Dec 27 12:01:22 1993 -by- Hock San Lee [hockl]
* Rewrote it.
\**************************************************************************/
BOOL APIENTRY glsrvDuplicateSection(ULONG ulSectionSize, HANDLE hFileMapClient)
{
BOOL bRet = FALSE;
HANDLE hFileMapServer = NULL;
HANDLE hSection = NULL;
PGLSRVSHAREDSECTIONINFO pSectionInfo = NULL;
PCSR_THREAD thread = CSR_SERVER_QUERYCLIENTTHREAD();
DBGENTRY("glsrvDuplicateSection\n");
ASSERTOPENGL(!GLTEB_SRVSHAREDSECTIONINFO() && !GLTEB_SRVSHAREDMEMORYSECTION(),
"Section already exists!\n");
// Duplicate the file mapping object for the shared memory section.
if (!DuplicateHandle(thread->Process->ProcessHandle,
hFileMapClient,
NtCurrentProcess(),
&hFileMapServer,
0,
FALSE,
DUPLICATE_SAME_ACCESS))
{
DBGERROR("DuplicateHandle failed\n");
goto glsrvDuplicateSection_exit;
}
if (!(hSection = MapViewOfFile(hFileMapServer, FILE_MAP_WRITE, 0, 0, ulSectionSize)))
{
DBGERROR("MapViewOfFile failed\n");
goto glsrvDuplicateSection_exit;
}
// Allocate and initialize the shared section info structure.
if (!(pSectionInfo = (PGLSRVSHAREDSECTIONINFO) GenMalloc(sizeof(*pSectionInfo))))
{
DBGERROR("GenMalloc failed\n");
goto glsrvDuplicateSection_exit;
}
pSectionInfo->ulSectionSize = ulSectionSize;
pSectionInfo->hFileMap = hFileMapServer;
pSectionInfo->pvSharedMemory = (PVOID) hSection;
bRet = TRUE;
glsrvDuplicateSection_exit:
if (bRet)
{
// Everything is golden. Update the TEB gl structure for the thread once!
DBGLEVEL2(LEVEL_INFO,
"glsrvDuplicateSection: ServerSharedMemory 0x%lx, ServerSectionHandle 0x%lx\n",
hSection, pSectionInfo);
GLTEB_SET_SRVSHAREDSECTIONINFO(pSectionInfo);
GLTEB_SET_SRVSHAREDMEMORYSECTION(hSection);
GLTEB_SET_SRVCURRENTRC(NULL); // first time initialization for thread
GLTEB_SET_SRVPROCTABLE((__GLdispatchState *)NULL,FALSE);
// first time initialization for thread
GLTEB_SET_SRVCONTEXT(NULL); // first time initialization for thread
}
else
{
// Error cleanup.
WARNING("glsrvDuplicateSection failed\n");
if (hSection)
if (!UnmapViewOfFile(hSection))
ASSERTOPENGL(FALSE, "UmmapViewOfFile failed");
if (hFileMapServer)
if (!CloseHandle(hFileMapServer))
ASSERTOPENGL(FALSE, "CloseHandle failed");
if (pSectionInfo)
GenFree(pSectionInfo);
}
return(bRet);
}
/******************************Public*Routine******************************\
* glsbsrvCloseAndDestroySection
*
* This function is called to cleanup the server OpenGL when a thread terminates.
* The server generic driver performs cleanup on its own without being called by
* the client side driver.
*
* Note that all unflushed calls are lost here.
*
* History:
* Mon Dec 27 12:01:22 1993 -by- Hock San Lee [hockl]
* Wrote it.
\**************************************************************************/
static void APIENTRY glsbsrvCloseAndDestroySection(void)
{
DBGENTRY("glsbsrvCloseAndDestroySection\n");
ASSERTOPENGL(GLTEB_SRVSHAREDSECTIONINFO() && GLTEB_SRVSHAREDMEMORYSECTION(),
"Section does not exist!\n");
// Clean up the server side.
if (!UnmapViewOfFile(GLTEB_SRVSHAREDMEMORYSECTION()))
ASSERTOPENGL(FALSE, "UmmapViewOfFile failed");
if (!CloseHandle(GLTEB_SRVSHAREDSECTIONINFO()->hFileMap))
ASSERTOPENGL(FALSE, "CloseHandle failed");
GenFree(GLTEB_SRVSHAREDSECTIONINFO());
GLTEB_SET_SRVSHAREDSECTIONINFO(NULL);
GLTEB_SET_SRVSHAREDMEMORYSECTION(NULL);
}
#if 0
// REWRITE THIS IF NEEDED
#ifdef DOGLMSGBATCHSTATS
BOOL APIENTRY glsrvMsgStats( MSG_GLMSGBATCHSTATS *pMsg )
{
GLMSGBATCHINFO *pMsgBatchInfo;
GLMSGBATCHSTATS *pBatchStats;
pMsgBatchInfo = (GLMSGBATCHINFO *)GLTEB_SRVSHAREDSECTIONINFO()->
SharedSectionInfo.ServerSharedMemory;
pBatchStats = &pMsgBatchInfo->BatchStats;
switch (pMsg->Action)
{
case GLMSGBATCHSTATS_CLEAR:
pBatchStats->ServerTrips = 0;
pBatchStats->ServerCalls = 0;
break;
case GLMSGBATCHSTATS_GETSTATS:
pMsg->BatchStats.ServerTrips = pBatchStats->ServerTrips;
pMsg->BatchStats.ServerCalls = pBatchStats->ServerCalls;
break;
default:
#if DBG
DBGBEGIN(LEVEL_ERROR)
DbgPrint("%s(%d) Unknown action: %d\n",
__FILE__, __LINE__, pMsg->Action );
DBGEND
#endif
return(FALSE);
break;
}
return(TRUE);
}
#else
BOOL APIENTRY glsrvMsgStats( void *pMsg )
{
return(FALSE);
}
#endif /* DOGLMSGBATCHSTATS */
#else
BOOL APIENTRY glsrvMsgStats( void *pMsg )
{
return(FALSE);
}
#endif /* 0 */
#ifndef _CLIENTSIDE_
/*
* Code to transfer data that will not fit in shared section
*
* This code was stolen from \nt\private\windows\gdi\gre\server.c
* (See bCopyClientData() & bSetClientData())
*
* The functions don't set any error flags, so that they can be used
* with gdibatching and subbatching.
*
*/
BOOL
glsrvuCopyClientData( VOID *Server, VOID *Client, ULONG Size )
{
ULONG Count;
HANDLE Handle;
DBGENTRY("glsrvuCopyClientData\n");
if ( Size )
{
if ( NULL == Server )
return( FALSE );
Handle = CSR_SERVER_QUERYCLIENTTHREAD()->Process->ProcessHandle;
if ( STATUS_SUCCESS != NtReadVirtualMemory( Handle,
Client,
Server,
Size,
&Count)
)
{
return( FALSE );
}
}
return( TRUE );
}
BOOL
glsrvuSetClientData( VOID *Client, VOID *Server, ULONG Size )
{
ULONG Count;
HANDLE Handle;
DBGENTRY("glsrvuSetClientData\n");
if ( Size )
{
if ( NULL == Server )
return( FALSE );
Handle = CSR_SERVER_QUERYCLIENTTHREAD()->Process->ProcessHandle;
if ( STATUS_SUCCESS != NtWriteVirtualMemory( Handle,
Client,
Server,
Size,
&Count)
)
{
return( FALSE );
}
}
return( TRUE );
}
#endif //_CLIENTSIDE_