mirror of https://github.com/lianthony/NT4.0
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.
378 lines
10 KiB
378 lines
10 KiB
//+-------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1992 - 1993.
|
|
//
|
|
// File: globals.cxx
|
|
//
|
|
// Contents: Implementation of Class used to encapsulate shared global
|
|
// data structures for DCOM95.
|
|
//
|
|
// History: 13-Feb-96 SatishT Created
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
#include <or.hxx>
|
|
|
|
|
|
//
|
|
// Helper function which initializes local DSA and string of protocol
|
|
// sequences, and as a side effect, starts all remote protocols
|
|
//
|
|
|
|
static CONST PWSTR gpwstrProtocolsPath = L"Software\\Microsoft\\Rpc";
|
|
static CONST PWSTR gpwstrProtocolsValue = L"DCOM Protocols";
|
|
|
|
ORSTATUS
|
|
InitRemoteProtocols(
|
|
OUT PWSTR &pwstrProtseqs,
|
|
OUT DUALSTRINGARRAY * &pdsaProtseqs,
|
|
OUT USHORT &cRemoteProtseqs,
|
|
OUT USHORT * &aRemoteProtseqs
|
|
)
|
|
{
|
|
ORSTATUS status = OR_OK;
|
|
DUALSTRINGARRAY *pdsaPS = NULL;
|
|
pwstrProtseqs = NULL;
|
|
|
|
DWORD dwType;
|
|
DWORD dwLenBuffer = InitialProtseqBufferLength;
|
|
HKEY hKey;
|
|
|
|
status =
|
|
RegOpenKeyEx(HKEY_LOCAL_MACHINE,
|
|
gpwstrProtocolsPath,
|
|
0,
|
|
KEY_READ,
|
|
&hKey);
|
|
|
|
if (status != ERROR_SUCCESS)
|
|
{
|
|
return status;
|
|
}
|
|
|
|
do
|
|
{
|
|
OrMemFree(pwstrProtseqs);
|
|
pwstrProtseqs = (WCHAR*) OrMemAlloc(dwLenBuffer);
|
|
if (pwstrProtseqs)
|
|
{
|
|
status = RegQueryValueEx(hKey,
|
|
gpwstrProtocolsValue,
|
|
0,
|
|
&dwType,
|
|
(PBYTE)pwstrProtseqs,
|
|
&dwLenBuffer
|
|
);
|
|
}
|
|
else
|
|
{
|
|
return OR_NOMEM; // BUGBUG: is OR_NOMEM really likely here??
|
|
}
|
|
}
|
|
while (status == ERROR_MORE_DATA);
|
|
|
|
PWSTR pwstr = pwstrProtseqs;
|
|
|
|
while(*pwstr)
|
|
{
|
|
USHORT id = GetProtseqId(pwstr);
|
|
|
|
if ((0 != id) && (ID_NP != id) && !IsLocal(id))
|
|
{
|
|
status = UseProtseqIfNecessary(id);
|
|
}
|
|
|
|
pwstr = OrStringSearch(pwstr, 0) + 1;
|
|
}
|
|
|
|
RPC_BINDING_VECTOR *pbv;
|
|
PWSTR pwstrT;
|
|
USHORT psaLen = 0;
|
|
DWORD i;
|
|
|
|
|
|
status = RpcServerInqBindings(&pbv);
|
|
|
|
ASSERT(status == RPC_S_NO_BINDINGS || pbv != NULL);
|
|
|
|
if (status == RPC_S_NO_BINDINGS) return status;
|
|
|
|
PWSTR aBindings[MAX_PROTSEQ_IDS];
|
|
PWSTR aAddresses [MAX_PROTSEQ_IDS];
|
|
USHORT aProtseqs[MAX_PROTSEQ_IDS];
|
|
|
|
// Build array of protseqs id's and addresses we're listening to.
|
|
|
|
for(i = 0; i < pbv->Count; i++)
|
|
{
|
|
PWSTR pwstrStringBinding;
|
|
|
|
status = RpcBindingToStringBinding(pbv->BindingH[i], &pwstrStringBinding);
|
|
if (status != RPC_S_OK)
|
|
{
|
|
break;
|
|
}
|
|
|
|
ASSERT(pwstrStringBinding);
|
|
|
|
status = RpcStringBindingParse(pwstrStringBinding,
|
|
0,
|
|
&pwstrT,
|
|
&aAddresses[i],
|
|
0,
|
|
0);
|
|
|
|
if (status != RPC_S_OK)
|
|
{
|
|
break;
|
|
}
|
|
|
|
aProtseqs[i] = GetProtseqId(pwstrT);;
|
|
aBindings[i] = pwstrStringBinding;
|
|
psaLen += OrStringLen(pwstrStringBinding) + 1;
|
|
cRemoteProtseqs++;
|
|
|
|
status = RpcStringFree(&pwstrT);
|
|
ASSERT(status == RPC_S_OK && pwstrT == 0);
|
|
}
|
|
|
|
status = RpcBindingVectorFree(&pbv);
|
|
ASSERT(pbv == 0 && status == RPC_S_OK);
|
|
|
|
if (cRemoteProtseqs == 0)
|
|
{
|
|
// No remote bindings
|
|
psaLen = 1;
|
|
}
|
|
|
|
// string bindings final null, authn and authz service and two final nulls
|
|
|
|
psaLen += 1 + 2 + 2;
|
|
|
|
pdsaPS = new (psaLen * sizeof(WCHAR)) DUALSTRINGARRAY;
|
|
|
|
aRemoteProtseqs = (USHORT *) OrMemAlloc(sizeof(USHORT)*cRemoteProtseqs);
|
|
|
|
if (pdsaPS == NULL || aRemoteProtseqs == NULL)
|
|
{
|
|
for ( i = 0; i < cRemoteProtseqs; i++ )
|
|
{
|
|
status = RpcStringFree(&aBindings[i]);
|
|
ASSERT(status == RPC_S_OK);
|
|
}
|
|
|
|
return OR_NOMEM;
|
|
}
|
|
|
|
pdsaPS->wNumEntries = psaLen;
|
|
pdsaPS->wSecurityOffset = psaLen - 4;
|
|
pwstrT = pdsaPS->aStringArray;
|
|
|
|
for ( i = 0; i < cRemoteProtseqs; i++ )
|
|
{
|
|
OrStringCopy(pwstrT, aBindings[i]);
|
|
pwstrT += OrStringLen(aBindings[i]) + 1;
|
|
aRemoteProtseqs[i] = aProtseqs[i];
|
|
status = RpcStringFree(&aBindings[i]);
|
|
ASSERT(status == RPC_S_OK);
|
|
}
|
|
|
|
if (psaLen == 6)
|
|
{
|
|
// No remote bindings, put in first null.
|
|
pdsaPS->aStringArray[0] = 0;
|
|
pwstrT++;
|
|
}
|
|
|
|
// Zero final terminator
|
|
*pwstrT = 0;
|
|
|
|
// Security authn service
|
|
pwstrT++;
|
|
*pwstrT = RPC_C_AUTHN_WINNT; // BUGBUG: need fix for generality
|
|
|
|
// Authz service, -1 means none // BUGBUG: -1 causes errors
|
|
pwstrT++;
|
|
*pwstrT = 0;
|
|
|
|
// Final, final NULLS
|
|
pwstrT++;
|
|
pwstrT[0] = 0;
|
|
pwstrT[1] = 0;
|
|
|
|
ASSERT(dsaValid(pdsaPS));
|
|
|
|
pdsaProtseqs = CompressStringArray(pdsaPS,TRUE);
|
|
delete pdsaPS;
|
|
|
|
if (pdsaProtseqs == NULL)
|
|
{
|
|
return OR_NOMEM;
|
|
}
|
|
|
|
ASSERT(dsaValid(pdsaProtseqs));
|
|
return status;
|
|
}
|
|
|
|
|
|
|
|
//
|
|
// Helper Macro for constructor below only
|
|
//
|
|
|
|
#define AssignAndAdvance(Var,Type) \
|
|
Type OR_BASED * *Var = (Type OR_BASED **) pb; \
|
|
pb += sizeof(Type OR_BASED *);
|
|
|
|
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Member: CSharedGlobals::CSharedGlobals
|
|
//
|
|
// Synopsis: Create table of globals for DCOM95
|
|
//
|
|
// Arguments: [pwszName] - name for shared memory
|
|
//
|
|
// Algorithm: Create and map in shared memory for the table
|
|
//
|
|
// History: 13-Feb-96 SatishT Created
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
CSharedGlobals::CSharedGlobals(WCHAR *pwszName, ORSTATUS &status)
|
|
/*---
|
|
|
|
NOTE: This constructor uses the shared allocator. Objects of this class
|
|
should not be created before the shared allocator is initialized.
|
|
|
|
---*/
|
|
{
|
|
BOOL fCreated;
|
|
|
|
_hSm = CreateSharedFileMapping(
|
|
pwszName,
|
|
GLOBALS_TABLE_SIZE,
|
|
GLOBALS_TABLE_SIZE,
|
|
NULL,
|
|
NULL,
|
|
PAGE_READWRITE,
|
|
(void **) &_pb,
|
|
&fCreated
|
|
);
|
|
|
|
Win4Assert(_hSm && _pb && "CSharedGlobals create shared file mapping failed");
|
|
|
|
BYTE * pb = _pb;
|
|
|
|
gpIdSequence = (LONG *) pb;
|
|
pb += sizeof(LONG);
|
|
|
|
gpdwLastCrashedProcessCheckTime = (DWORD *) pb;
|
|
pb += sizeof(DWORD);
|
|
|
|
gpNextThreadID = (DWORD *) pb;
|
|
pb += sizeof(DWORD);
|
|
|
|
gpcRemoteProtseqs = (USHORT *) pb;
|
|
pb += sizeof(USHORT);
|
|
|
|
AssignAndAdvance(DCOMProtseqIds,USHORT) // see macro above
|
|
AssignAndAdvance(DCOMProtseqs,WCHAR)
|
|
AssignAndAdvance(LocalDSA,DUALSTRINGARRAY)
|
|
AssignAndAdvance(LocalMid,CMid)
|
|
AssignAndAdvance(PingProcess,CProcess)
|
|
AssignAndAdvance(OidTable,COidTable)
|
|
AssignAndAdvance(OxidTable,COxidTable)
|
|
AssignAndAdvance(MidTable,CMidTable)
|
|
AssignAndAdvance(ProcessTable,CProcessTable)
|
|
|
|
if (fCreated) // if we got here first, so create the tables
|
|
{
|
|
memset(_pb, 0, GLOBALS_TABLE_SIZE);
|
|
|
|
// Initialize the sequence number for AllocateId, the last time crashed
|
|
// processes were detected and the thread ID sequence in shared memory
|
|
*gpIdSequence = 1;
|
|
|
|
*gpdwLastCrashedProcessCheckTime = 0;
|
|
|
|
*gpNextThreadID = 1;
|
|
|
|
// I know this is paranoid but I have been bitten before ..
|
|
gpRemoteProtseqIds = NULL;
|
|
gpwstrProtseqs = NULL;
|
|
gpLocalDSA = NULL;
|
|
gpLocalMid = NULL;
|
|
gpPingProcess = NULL;
|
|
gpOxidTable = NULL;
|
|
gpOidTable = NULL;
|
|
gpMidTable = NULL;
|
|
gpProcessTable = NULL;
|
|
|
|
// initialize remote protocol strings and
|
|
// the DSA bindings of local OR in shared memory
|
|
PWSTR pwstr;
|
|
DUALSTRINGARRAY *pdsa;
|
|
USHORT *aProtseqIds;
|
|
|
|
InitRemoteProtocols(pwstr,pdsa,*gpcRemoteProtseqs,aProtseqIds);
|
|
|
|
*DCOMProtseqIds = OR_BASED_POINTER(WCHAR,aProtseqIds);
|
|
*DCOMProtseqs = OR_BASED_POINTER(WCHAR,pwstr);
|
|
*LocalDSA = OR_BASED_POINTER(DUALSTRINGARRAY,pdsa);
|
|
|
|
// initialize local Mid object in shared memory
|
|
NEW_OR_BASED(*LocalMid,CMid,(OR_FULL_POINTER(DUALSTRINGARRAY,*LocalDSA),status,0));
|
|
if (status != OR_OK)
|
|
{
|
|
DELETE_OR_BASED(CMid,*LocalMid);
|
|
*LocalMid = NULL;
|
|
}
|
|
|
|
// initialize ping thread's process object in shared memory
|
|
NEW_OR_BASED(*PingProcess,CProcess,(0));
|
|
|
|
// Assume 16 exporting processes/threads.
|
|
NEW_OR_BASED(*OxidTable,COxidTable,(OXID_TABLE_SIZE));
|
|
|
|
// Assume 11 exported OIDs per process/thread.
|
|
NEW_OR_BASED(*OidTable,COidTable,(OID_TABLE_SIZE));
|
|
|
|
// Assume 16 machine locations for OXIDs.
|
|
NEW_OR_BASED(*MidTable,CMidTable,(MID_TABLE_SIZE));
|
|
|
|
// Assume 16 simultaneouly active local processes.
|
|
NEW_OR_BASED(*ProcessTable,CProcessTable,(PROCESS_TABLE_SIZE));
|
|
|
|
// Add local CMid object to global shared table
|
|
if (*LocalMid && *MidTable)
|
|
status = (*MidTable)->Add(OR_FULL_POINTER(CMid,*LocalMid));
|
|
}
|
|
|
|
gpRemoteProtseqIds = OR_FULL_POINTER(USHORT,*DCOMProtseqIds);
|
|
gpwstrProtseqs = OR_FULL_POINTER(WCHAR,*DCOMProtseqs);
|
|
gpLocalDSA = OR_FULL_POINTER(DUALSTRINGARRAY,*LocalDSA);
|
|
gpLocalMid = OR_FULL_POINTER(CMid,*LocalMid);
|
|
gpPingProcess = OR_FULL_POINTER(CProcess,*PingProcess);
|
|
gpOxidTable = OR_FULL_POINTER(COxidTable,*OxidTable);
|
|
gpOidTable = OR_FULL_POINTER(COidTable,*OidTable);
|
|
gpMidTable = OR_FULL_POINTER(CMidTable,*MidTable);
|
|
gpProcessTable = OR_FULL_POINTER(CProcessTable,*ProcessTable);
|
|
}
|
|
|
|
|
|
#ifndef _CHICAGO_
|
|
|
|
/* MIDL allocate and free */
|
|
|
|
void __RPC_FAR * __RPC_API midl_user_allocate(size_t len)
|
|
{
|
|
return(PrivMemAlloc(len));
|
|
}
|
|
|
|
void __RPC_API midl_user_free(void __RPC_FAR * ptr)
|
|
{
|
|
PrivMemFree(ptr);
|
|
}
|
|
|
|
#endif // _CHICAGO_
|