Leaked source code of windows server 2003
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.
 
 
 
 
 
 

300 lines
6.3 KiB

/*
* LOALLOC.C
*
* Setup, cleanup, and MAPI memory allocation for the low-level
* MAPI utility library.
*/
#include "_apipch.h"
#define LOALLOC_C
#ifdef MAC
#define PvGetInstanceGlobalsEx(_x) PvGetInstanceGlobalsMac(kInstMAPIU)
#define ScSetInstanceGlobalsEx(_pinst, _x) ScSetInstanceGlobalsMac(_pinst, kInstMAPIU)
//STDAPI HrCreateGuidNoNet(GUID FAR *pguid);
#endif
#ifndef STATIC
#ifdef DEBUG
#define STATIC
#else
#define STATIC static
#endif
#endif
#ifdef OLD_STUFF
#pragma SEGMENT(MAPI_Util)
#endif // OLD_STUFF
#if defined(WIN32) && !defined(MAC)
const CHAR szMutexName[] = "MAPI_UIDGEN_MUTEX";
//STDAPI HrCreateGuidNoNet(GUID FAR *pguid);
#endif
typedef SCODE (GENMUIDFN)(MAPIUID *lpMuid);
#if defined (WIN32) && !defined (MAC)
extern CRITICAL_SECTION csMapiInit;
#endif
#ifndef MAC
DefineInstList(lpInstUtil);
#endif
STDAPI_(SCODE)
ScInitMapiUtil(ULONG ulFlags)
{
LPINSTUTIL pinst;
SCODE sc = S_OK;
HLH hlh;
#ifdef WIN16
WORD wSS;
HTASK hTask = GetCurrentTask();
_asm mov wSS, ss
#endif
// Cheesy parameter validation
AssertSz(ulFlags == 0L, TEXT("ScInitMapiUtil: reserved flags used"));
pinst = (LPINSTUTIL) PvGetInstanceGlobalsEx(lpInstUtil);
#ifdef WIN16
{
// Verify that the instance structure is valid because on Win16 the
// stack segment could have been re-used by another task. When this
// happens there is a good chance that PvGetInstanceGlobalsEx will
// return a pinst belongs to the previous task. The memory for that
// pinst may not be valid any more (because the system automatically
// deallocates global memory when the task dies), or it may have been
// allocated by some other task (in which case it is valid but isn't
// a pinst anymore). Here we try our best to determine that the pinst
// is indeed the one we were looking for.
if ( pinst
&& ( IsBadWritePtr(pinst, sizeof(INSTUTIL))
|| pinst->dwBeg != INSTUTIL_SIG_BEG
|| pinst->wSS != wSS
|| pinst->hTask != hTask
|| pinst->pvBeg != pinst
|| pinst->dwEnd != INSTUTIL_SIG_END))
{
TraceSz("MAPI: ScInitMapiUtil: Rejecting orphaned instance globals");
(void) ScSetInstanceGlobalsEx(0, lpInstUtil);
pinst = 0;
}
}
#endif
if (pinst)
{
if (pinst->cRef == 0)
{
Assert(pinst->cRefIdle == 0);
Assert(pinst->hlhClient);
}
++(pinst->cRef);
return S_OK;
}
#if defined (WIN32) && !defined (MAC)
EnterCriticalSection(&csMapiInit);
#endif
// Create local heap for MAPIAllocateBuffer to play in
hlh = LH_Open(0);
if (hlh == 0)
{
sc = MAPI_E_NOT_ENOUGH_MEMORY;
goto ret;
}
LH_SetHeapName(hlh, TEXT("Client MAPIAllocator"));
pinst = (LPINSTUTIL) LH_Alloc(hlh, sizeof(INSTUTIL));
if (!pinst)
{
LH_Close(hlh);
sc = MAPI_E_NOT_ENOUGH_MEMORY;
goto ret;
}
ZeroMemory((LPBYTE) pinst, sizeof(INSTUTIL));
#ifdef WIN16
pinst->dwBeg = INSTUTIL_SIG_BEG;
pinst->wSS = wSS;
pinst->hTask = hTask;
pinst->pvBeg = pinst;
pinst->dwEnd = INSTUTIL_SIG_END;
#endif
// Install the instance data
sc = ScSetInstanceGlobalsEx(pinst, lpInstUtil);
if (sc)
{
LH_Close(hlh);
goto ret;
}
pinst->cRef = 1;
pinst->hlhClient = hlh;
ret:
#if defined (WIN32) && !defined (MAC)
LeaveCriticalSection(&csMapiInit);
#endif
DebugTraceSc(ScInitMapiUtil, sc);
return sc;
}
STDAPI_(void)
DeinitMapiUtil()
{
LPINSTUTIL pinst;
pinst = (LPINSTUTIL) PvGetInstanceGlobalsEx(lpInstUtil);
if (!pinst)
return;
Assert(pinst->cRef);
if (--(pinst->cRef) == 0)
{
#if defined (WIN32) && !defined (MAC)
EnterCriticalSection(&csMapiInit);
#endif
// Idle stuff must already have been cleaned up
Assert(pinst->cRefIdle == 0);
/*
* !!! DO NOT CLOSE THE HEAP OR GET RID OF THE INST !!!
*
* Simple MAPI counts on being able to access and free buffers
* right up until the DLL is unloaded from memory. Therefore we do
* not explicitly close the heap; we count on the OS to make it
* evaporate when the process exits.
* Likewise, MAPIFreeBuffer needs the INSTUTIL to find the heap handle,
* so we never deinstall the INSTUTIL.
*
* // Uninstall the globals.
* (void) ScSetInstanceGlobalsEx(NULL, lpInstUtil);
*
* // Clean up the heap
* hlh = pinst->hlhClient;
* LH_Free(hlh, pinst);
*
* LH_Close(hlh);
*/
#if defined (WIN32) && !defined (MAC)
LeaveCriticalSection(&csMapiInit);
#endif
}
}
HLH
HlhUtilities(VOID)
{
LPINSTUTIL pinst = (LPINSTUTIL) PvGetInstanceGlobalsEx(lpInstUtil);
return pinst ? pinst->hlhClient : (HLH) 0;
}
#ifdef NOTIFICATIONS
#ifdef TABLES
#if defined(WIN16)
STDAPI_(SCODE)
ScGenerateMuid (LPMAPIUID lpMuid)
{
return GetScode(CoCreateGuid((LPGUID)lpMuid));
}
#endif // WIN16
#if (defined(WIN32) && !defined(MAC))
STDAPI_(SCODE)
ScGenerateMuid (LPMAPIUID lpMuid)
{
HRESULT hr;
// validate parameter
AssertSz( !IsBadReadPtr( lpMuid, sizeof( MAPIUID ) ), "lpMuid fails address check" );
#ifdef OLD_STUFF
// WAB won't use this... why bother bringing in RPC when we are local anyway?
if (hMuidMutex == NULL)
{
RPC_STATUS rpc_s;
rpc_s = UuidCreate((UUID __RPC_FAR *) lpMuid);
if (rpc_s == RPC_S_OK)
{
hr = hrSuccess;
goto err;
}
else
{
hMuidMutex = CreateMutex(NULL, FALSE, szMutexName);
if (hMuidMutex == NULL)
{
TraceSz1("MAPIU: ScGenerateMuid: call to CreateMutex failed"
" - error %08lX\n", GetLastError());
hr = ResultFromScode(MAPI_E_CALL_FAILED);
goto err;
}
}
}
WaitForSingleObject(hMuidMutex, INFINITE);
hr = HrCreateGuidNoNet((GUID FAR *) lpMuid);
ReleaseMutex(hMuidMutex);
#endif // OLD_STUFF
//$ Note that we don't call CloseHandle on the mutex anywhere. If we're
//$ really worried about this, we could call CloseHandle in the code that
//$ WIN32 calls when the DLL is being unloaded.
hr = CoCreateGuid((GUID *)lpMuid);
err:
DebugTraceResult(ScGenerateMuid, hr);
return GetScode(hr);
}
#endif /* WIN32 - Mac*/
#ifdef MAC
STDAPI_(SCODE)
ScGenerateMuid (LPMAPIUID lpMuid)
{
HRESULT hr;
// hr = HrCreateGuidNoNet((GUID FAR *) lpMuid);
DebugTraceResult(ScGenerateMuid, hr);
return GetScode(hr);
}
#endif // MAC
#endif //#ifdef TABLES
#endif //#ifdef NOTIFICATIONS