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
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
|