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.
715 lines
23 KiB
715 lines
23 KiB
/*++
|
|
|
|
Copyright (C) Microsoft Corporation, 1996 - 1999
|
|
|
|
Module Name:
|
|
|
|
DbgSvr.cxx
|
|
|
|
Abstract:
|
|
|
|
The debugging support interfaces in RPCSS
|
|
|
|
Author:
|
|
|
|
Kamen Moutafov [KamenM]
|
|
|
|
|
|
Revision History:
|
|
|
|
KamenM Dec 99 Creation
|
|
|
|
--*/
|
|
|
|
#include <sysinc.h>
|
|
|
|
#include <wincrypt.h>
|
|
#include <wtypes.h>
|
|
#include <rpc.h>
|
|
#include <rpcdcep.h>
|
|
#include <rpcerrp.h>
|
|
#include <rpctrans.hxx>
|
|
#include <objidl.h>
|
|
#include <CellDef.hxx>
|
|
#include <DbgIdl.h>
|
|
|
|
START_C_EXTERN
|
|
|
|
RPC_STATUS RPC_ENTRY
|
|
DebugServerSecurityCallback (
|
|
IN RPC_IF_HANDLE InterfaceUuid,
|
|
IN void *Context
|
|
)
|
|
{
|
|
RPC_STATUS Status, TempStatus;
|
|
HANDLE TempHandle;
|
|
PVOID SectionPointer;
|
|
|
|
// Context is an SCALL
|
|
Status = RpcImpersonateClient(Context);
|
|
if (Status != RPC_S_OK)
|
|
{
|
|
return Status;
|
|
}
|
|
|
|
// try to open our own section - this is protected by ACL for admins & local system
|
|
// only, so this should filter out unauthorized access
|
|
Status = OpenDbgSection(&TempHandle, &SectionPointer, GetCurrentProcessId(), NULL);
|
|
if (Status == RPC_S_OK)
|
|
{
|
|
CloseDbgSection(TempHandle, SectionPointer);
|
|
}
|
|
|
|
TempStatus = RpcRevertToSelfEx(Context);
|
|
ASSERT(TempStatus == RPC_S_OK);
|
|
return Status;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
/// Local representation to wire representation translation routines
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
void TranslateLocalCallInfoToRemoteCallInfo(IN DebugCallInfo *LocalDebugInfo,
|
|
OUT RemoteDebugCallInfo *RemoteCallInfo)
|
|
{
|
|
RemoteCallInfo->Type = LocalDebugInfo->Type;
|
|
RemoteCallInfo->Status = LocalDebugInfo->Status;
|
|
RemoteCallInfo->ProcNum = LocalDebugInfo->ProcNum;
|
|
RemoteCallInfo->InterfaceUUIDStart = LocalDebugInfo->InterfaceUUIDStart;
|
|
RemoteCallInfo->ServicingTID = LocalDebugInfo->ServicingTID;
|
|
RemoteCallInfo->CallFlags = LocalDebugInfo->CallFlags;
|
|
RemoteCallInfo->CallID = LocalDebugInfo->CallID;
|
|
RemoteCallInfo->LastUpdateTime = LocalDebugInfo->LastUpdateTime;
|
|
if (LocalDebugInfo->CallFlags & DBGCELL_LRPC_CALL)
|
|
{
|
|
RemoteCallInfo->ConnectionType = crtLrpcConnection;
|
|
RemoteCallInfo->connInfo.Connection = LocalDebugInfo->Connection;
|
|
}
|
|
else
|
|
{
|
|
RemoteCallInfo->ConnectionType = crtOsfConnection;
|
|
RemoteCallInfo->connInfo.Caller.PID = LocalDebugInfo->PID;
|
|
RemoteCallInfo->connInfo.Caller.TID = LocalDebugInfo->TID;
|
|
}
|
|
}
|
|
|
|
void TranslateLocalEndpointInfoToRemoteEndpointInfo(IN DebugEndpointInfo *LocalDebugInfo,
|
|
OUT RemoteDebugEndpointInfo *RemoteEndpointInfo)
|
|
{
|
|
RemoteEndpointInfo->Type = LocalDebugInfo->Type;
|
|
RemoteEndpointInfo->ProtseqType = LocalDebugInfo->ProtseqType;
|
|
RemoteEndpointInfo->Status = LocalDebugInfo->Status;
|
|
|
|
// the endpoint name in the debug cell is not null terminated - process it specially
|
|
RemoteEndpointInfo->EndpointNameLength = 0;
|
|
RemoteEndpointInfo->EndpointName
|
|
= (unsigned char *)MIDL_user_allocate(DebugEndpointNameLength + 1);
|
|
if (RemoteEndpointInfo->EndpointName != NULL)
|
|
{
|
|
memcpy(RemoteEndpointInfo->EndpointName,
|
|
LocalDebugInfo->EndpointName, DebugEndpointNameLength);
|
|
RemoteEndpointInfo->EndpointName[DebugEndpointNameLength] = 0;
|
|
RemoteEndpointInfo->EndpointNameLength
|
|
= strlen((const char *) RemoteEndpointInfo->EndpointName) + 1;
|
|
}
|
|
}
|
|
|
|
void TranslateLocalThreadInfoToRemoteThreadInfo(IN DebugThreadInfo *LocalDebugInfo,
|
|
OUT RemoteDebugThreadInfo *RemoteThreadInfo)
|
|
{
|
|
RemoteThreadInfo->Type = LocalDebugInfo->Type;
|
|
RemoteThreadInfo->Status = LocalDebugInfo->Status;
|
|
RemoteThreadInfo->LastUpdateTime = LocalDebugInfo->LastUpdateTime;
|
|
RemoteThreadInfo->TID = LocalDebugInfo->TID;
|
|
RemoteThreadInfo->Endpoint = LocalDebugInfo->Endpoint;
|
|
}
|
|
|
|
void TranslateLocalClientCallInfoToRemoteClientCallInfo(IN DebugClientCallInfo *LocalDebugInfo,
|
|
OUT RemoteDebugClientCallInfo *RemoteClientCallInfo)
|
|
{
|
|
RemoteClientCallInfo->Type = LocalDebugInfo->Type;
|
|
RemoteClientCallInfo->ProcNum = LocalDebugInfo->ProcNum;
|
|
RemoteClientCallInfo->ServicingThread = LocalDebugInfo->ServicingThread;
|
|
RemoteClientCallInfo->IfStart = LocalDebugInfo->IfStart;
|
|
RemoteClientCallInfo->CallID = LocalDebugInfo->CallID;
|
|
RemoteClientCallInfo->CallTargetID = LocalDebugInfo->CallTargetID;
|
|
|
|
// the endpoint in the debug cell is not null terminated - process it specially
|
|
RemoteClientCallInfo->EndpointLength = 0;
|
|
RemoteClientCallInfo->Endpoint
|
|
= (unsigned char *)MIDL_user_allocate(ClientCallEndpointLength + 1);
|
|
if (RemoteClientCallInfo->Endpoint != NULL)
|
|
{
|
|
memcpy(RemoteClientCallInfo->Endpoint,
|
|
LocalDebugInfo->Endpoint, ClientCallEndpointLength);
|
|
RemoteClientCallInfo->Endpoint[ClientCallEndpointLength] = 0;
|
|
RemoteClientCallInfo->EndpointLength
|
|
= strlen((const char *) RemoteClientCallInfo->Endpoint) + 1;
|
|
}
|
|
}
|
|
|
|
void TranslateLocalConnectionInfoToRemoteConnectionInfo(IN DebugConnectionInfo *LocalDebugInfo,
|
|
OUT RemoteDebugConnectionInfo *RemoteConnectionInfo)
|
|
{
|
|
RemoteConnectionInfo->Type = LocalDebugInfo->Type;
|
|
RemoteConnectionInfo->Flags = LocalDebugInfo->Flags;
|
|
RemoteConnectionInfo->LastTransmitFragmentSize
|
|
= LocalDebugInfo->LastTransmitFragmentSize;
|
|
RemoteConnectionInfo->Endpoint = LocalDebugInfo->Endpoint;
|
|
RemoteConnectionInfo->ConnectionID[0]
|
|
= HandleToUlong(LocalDebugInfo->ConnectionID[0]);
|
|
RemoteConnectionInfo->ConnectionID[1]
|
|
= HandleToUlong(LocalDebugInfo->ConnectionID[1]);
|
|
RemoteConnectionInfo->LastSendTime = LocalDebugInfo->LastSendTime;
|
|
RemoteConnectionInfo->LastReceiveTime = LocalDebugInfo->LastReceiveTime;
|
|
}
|
|
|
|
void TranslateLocalCallTargetInfoToRemoteCallTargetInfo(IN DebugCallTargetInfo *LocalDebugInfo,
|
|
OUT RemoteDebugCallTargetInfo *RemoteCallTargetInfo)
|
|
{
|
|
RemoteCallTargetInfo->Type = LocalDebugInfo->Type;
|
|
RemoteCallTargetInfo->ProtocolSequence = LocalDebugInfo->ProtocolSequence;
|
|
RemoteCallTargetInfo->LastUpdateTime = LocalDebugInfo->LastUpdateTime;
|
|
|
|
// the target server name in the debug cell is not null terminated - process it specially
|
|
RemoteCallTargetInfo->TargetServerLength = 0;
|
|
RemoteCallTargetInfo->TargetServer
|
|
= (unsigned char *)MIDL_user_allocate(TargetServerNameLength + 1);
|
|
if (RemoteCallTargetInfo->TargetServer != NULL)
|
|
{
|
|
memcpy(RemoteCallTargetInfo->TargetServer,
|
|
LocalDebugInfo->TargetServer, TargetServerNameLength);
|
|
RemoteCallTargetInfo->TargetServer[TargetServerNameLength] = 0;
|
|
RemoteCallTargetInfo->TargetServerLength
|
|
= strlen((const char *) RemoteCallTargetInfo->TargetServer) + 1;
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
/// Remote get cell info routine
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
/* [fault_status][comm_status] */ error_status_t RemoteGetCellByDebugCellID(
|
|
/* [in] */ handle_t IDL_handle,
|
|
/* [in] */ DWORD ProcessID,
|
|
/* [in] */ DebugCellID CellID,
|
|
/* [in, out, unique] */ RemoteDebugCellUnion __RPC_FAR *__RPC_FAR *debugInfo)
|
|
{
|
|
DebugCellUnion Container;
|
|
RemoteDebugCellUnion *ActualDebugInfo;
|
|
RPC_STATUS Status;
|
|
|
|
if (debugInfo == NULL)
|
|
RpcRaiseException(ERROR_INVALID_PARAMETER);
|
|
|
|
*debugInfo = NULL;
|
|
ActualDebugInfo = (RemoteDebugCellUnion *) MIDL_user_allocate(sizeof(RemoteDebugCellUnion));
|
|
|
|
if (ActualDebugInfo == NULL)
|
|
return RPC_S_OUT_OF_MEMORY;
|
|
|
|
Status = GetCellByDebugCellID(ProcessID, CellID, &Container);
|
|
if (Status != RPC_S_OK)
|
|
{
|
|
MIDL_user_free(ActualDebugInfo);
|
|
return Status;
|
|
}
|
|
|
|
ActualDebugInfo->UnionType = Container.callInfo.Type;
|
|
if ((ActualDebugInfo->UnionType < dctFirstEntry) || (ActualDebugInfo->UnionType > dctLastEntry)
|
|
|| (ActualDebugInfo->UnionType == dctInvalid) || (ActualDebugInfo->UnionType == dctFree)
|
|
|| (ActualDebugInfo->UnionType == dctUsedGeneric))
|
|
{
|
|
MIDL_user_free(ActualDebugInfo);
|
|
return RPC_S_OBJECT_NOT_FOUND;
|
|
}
|
|
|
|
switch(ActualDebugInfo->UnionType)
|
|
{
|
|
case dctCallInfo:
|
|
TranslateLocalCallInfoToRemoteCallInfo(&Container.callInfo,
|
|
&ActualDebugInfo->debugInfo.callInfo);
|
|
break;
|
|
|
|
case dctThreadInfo:
|
|
TranslateLocalThreadInfoToRemoteThreadInfo(&Container.threadInfo,
|
|
&ActualDebugInfo->debugInfo.threadInfo);
|
|
break;
|
|
|
|
case dctEndpointInfo:
|
|
TranslateLocalEndpointInfoToRemoteEndpointInfo(&Container.endpointInfo,
|
|
&ActualDebugInfo->debugInfo.endpointInfo);
|
|
break;
|
|
|
|
case dctClientCallInfo:
|
|
TranslateLocalClientCallInfoToRemoteClientCallInfo(&Container.clientCallInfo,
|
|
&ActualDebugInfo->debugInfo.clientCallInfo);
|
|
break;
|
|
|
|
case dctConnectionInfo:
|
|
TranslateLocalConnectionInfoToRemoteConnectionInfo(&Container.connectionInfo,
|
|
&ActualDebugInfo->debugInfo.connectionInfo);
|
|
break;
|
|
|
|
case dctCallTargetInfo:
|
|
TranslateLocalCallTargetInfoToRemoteCallTargetInfo(&Container.callTargetInfo,
|
|
&ActualDebugInfo->debugInfo.callTargetInfo);
|
|
break;
|
|
|
|
default:
|
|
ASSERT(0);
|
|
|
|
}
|
|
*debugInfo = ActualDebugInfo;
|
|
return RPC_S_OK;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
/// Remote call enumeration routines
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
typedef enum tagRemoteEnumerationHandleType
|
|
{
|
|
rehtCallInfo,
|
|
rehtEndpointInfo,
|
|
rehtThreadInfo,
|
|
rehtClientCallInfo
|
|
} RemoteEnumerationHandleType;
|
|
|
|
typedef struct tagRemoteCallInfoEnumerationHandle
|
|
{
|
|
RemoteEnumerationHandleType ThisHandleType;
|
|
CallInfoEnumerationHandle h;
|
|
} RemoteCallInfoEnumerationHandle;
|
|
|
|
error_status_t RemoteOpenRPCDebugCallInfoEnumeration(
|
|
/* [in] */ handle_t IDL_handle,
|
|
/* [out] */ DbgCallEnumHandle __RPC_FAR *h,
|
|
/* [in] */ DWORD CallID,
|
|
/* [in] */ DWORD IfStart,
|
|
/* [in] */ int ProcNum,
|
|
/* [in] */ DWORD ProcessID)
|
|
{
|
|
RemoteCallInfoEnumerationHandle *rh;
|
|
RPC_STATUS Status;
|
|
|
|
*h = NULL;
|
|
|
|
rh = new RemoteCallInfoEnumerationHandle;
|
|
if (rh == NULL)
|
|
return RPC_S_OUT_OF_MEMORY;
|
|
|
|
rh->ThisHandleType = rehtCallInfo;
|
|
Status = OpenRPCDebugCallInfoEnumeration(CallID, IfStart, ProcNum, ProcessID, &rh->h);
|
|
if (Status != RPC_S_OK)
|
|
{
|
|
delete rh;
|
|
return Status;
|
|
}
|
|
|
|
*h = rh;
|
|
|
|
return RPC_S_OK;
|
|
}
|
|
|
|
error_status_t RemoteGetNextRPCDebugCallInfo(
|
|
/* [in] */ DbgCallEnumHandle h,
|
|
/* [unique][out][in] */ RemoteDebugCallInfo __RPC_FAR *__RPC_FAR *debugInfo,
|
|
/* [out] */ DebugCellID __RPC_FAR *CellID,
|
|
/* [out] */ DWORD __RPC_FAR *ProcessID)
|
|
{
|
|
RemoteCallInfoEnumerationHandle *rh;
|
|
RPC_STATUS Status;
|
|
DebugCallInfo *NextCall;
|
|
|
|
if (debugInfo == NULL)
|
|
RpcRaiseException(ERROR_INVALID_PARAMETER);
|
|
|
|
*debugInfo = NULL;
|
|
CellID->SectionID = 0;
|
|
CellID->CellID = 0;
|
|
|
|
rh = (RemoteCallInfoEnumerationHandle *)h;
|
|
if (rh->ThisHandleType != rehtCallInfo)
|
|
return ERROR_INVALID_HANDLE;
|
|
|
|
Status = GetNextRPCDebugCallInfo(rh->h, &NextCall, CellID, ProcessID);
|
|
if (Status == RPC_S_OK)
|
|
{
|
|
*debugInfo = (RemoteDebugCallInfo *) MIDL_user_allocate(sizeof(RemoteDebugCallInfo));
|
|
if (*debugInfo != NULL)
|
|
{
|
|
TranslateLocalCallInfoToRemoteCallInfo(NextCall, *debugInfo);
|
|
}
|
|
else
|
|
Status = RPC_S_OUT_OF_MEMORY;
|
|
}
|
|
return Status;
|
|
}
|
|
|
|
error_status_t RemoteFinishRPCDebugCallInfoEnumeration(
|
|
/* [out][in] */ DbgCallEnumHandle __RPC_FAR *h)
|
|
{
|
|
RemoteCallInfoEnumerationHandle *rh;
|
|
|
|
rh = (RemoteCallInfoEnumerationHandle *)*h;
|
|
|
|
if (rh == NULL)
|
|
RpcRaiseException(ERROR_INVALID_PARAMETER);
|
|
|
|
if (rh->ThisHandleType != rehtCallInfo)
|
|
return ERROR_INVALID_HANDLE;
|
|
|
|
DbgCallEnumHandle_rundown(*h);
|
|
|
|
*h = NULL;
|
|
return RPC_S_OK;
|
|
}
|
|
|
|
void __RPC_USER DbgCallEnumHandle_rundown(DbgCallEnumHandle h)
|
|
{
|
|
RemoteCallInfoEnumerationHandle *rh;
|
|
|
|
rh = (RemoteCallInfoEnumerationHandle *)h;
|
|
|
|
FinishRPCDebugCallInfoEnumeration(&rh->h);
|
|
delete rh;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
/// Remote endpoint enumeration routines
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
typedef struct tagRemoteEndpointInfoEnumerationHandle
|
|
{
|
|
RemoteEnumerationHandleType ThisHandleType;
|
|
EndpointInfoEnumerationHandle h;
|
|
} RemoteEndpointInfoEnumerationHandle;
|
|
|
|
error_status_t RemoteOpenRPCDebugEndpointInfoEnumeration(
|
|
/* [in] */ handle_t IDL_handle,
|
|
/* [out] */ DbgEndpointEnumHandle __RPC_FAR *h,
|
|
/* [in] */ short EndpointSize,
|
|
/* [size_is][in] */ unsigned char __RPC_FAR *Endpoint)
|
|
{
|
|
RemoteEndpointInfoEnumerationHandle *rh;
|
|
RPC_STATUS Status;
|
|
|
|
*h = NULL;
|
|
|
|
rh = new RemoteEndpointInfoEnumerationHandle;
|
|
if (rh == NULL)
|
|
return RPC_S_OUT_OF_MEMORY;
|
|
|
|
rh->ThisHandleType = rehtEndpointInfo;
|
|
Status = OpenRPCDebugEndpointInfoEnumeration((EndpointSize > 0) ? (char *)Endpoint : NULL, &rh->h);
|
|
if (Status != RPC_S_OK)
|
|
{
|
|
delete rh;
|
|
return Status;
|
|
}
|
|
|
|
*h = rh;
|
|
|
|
return RPC_S_OK;
|
|
}
|
|
|
|
error_status_t RemoteGetNextRPCDebugEndpointInfo(
|
|
/* [in] */ DbgEndpointEnumHandle h,
|
|
/* [unique][out][in] */ RemoteDebugEndpointInfo __RPC_FAR *__RPC_FAR *debugInfo,
|
|
/* [out] */ DebugCellID __RPC_FAR *CellID,
|
|
/* [out] */ DWORD __RPC_FAR *ProcessID)
|
|
{
|
|
RemoteEndpointInfoEnumerationHandle *rh;
|
|
RPC_STATUS Status;
|
|
DebugEndpointInfo *NextEndpoint;
|
|
|
|
if (debugInfo == NULL)
|
|
RpcRaiseException(ERROR_INVALID_PARAMETER);
|
|
|
|
*debugInfo = NULL;
|
|
CellID->SectionID = 0;
|
|
CellID->CellID = 0;
|
|
|
|
rh = (RemoteEndpointInfoEnumerationHandle *)h;
|
|
if (rh->ThisHandleType != rehtEndpointInfo)
|
|
return ERROR_INVALID_HANDLE;
|
|
|
|
Status = GetNextRPCDebugEndpointInfo(rh->h, &NextEndpoint, CellID, ProcessID);
|
|
if (Status == RPC_S_OK)
|
|
{
|
|
*debugInfo = (RemoteDebugEndpointInfo *) MIDL_user_allocate(sizeof(RemoteDebugEndpointInfo));
|
|
if (*debugInfo != NULL)
|
|
{
|
|
TranslateLocalEndpointInfoToRemoteEndpointInfo(NextEndpoint, *debugInfo);
|
|
}
|
|
else
|
|
Status = RPC_S_OUT_OF_MEMORY;
|
|
}
|
|
return Status;
|
|
}
|
|
|
|
error_status_t RemoteFinishRPCDebugEndpointInfoEnumeration(
|
|
/* [out][in] */ DbgEndpointEnumHandle __RPC_FAR *h)
|
|
{
|
|
RemoteEndpointInfoEnumerationHandle *rh;
|
|
|
|
rh = (RemoteEndpointInfoEnumerationHandle *)*h;
|
|
|
|
if (rh == NULL)
|
|
RpcRaiseException(ERROR_INVALID_PARAMETER);
|
|
|
|
if (rh->ThisHandleType != rehtEndpointInfo)
|
|
return ERROR_INVALID_HANDLE;
|
|
|
|
DbgEndpointEnumHandle_rundown(*h);
|
|
|
|
*h = NULL;
|
|
return RPC_S_OK;
|
|
}
|
|
|
|
void __RPC_USER DbgEndpointEnumHandle_rundown(DbgEndpointEnumHandle h)
|
|
{
|
|
RemoteEndpointInfoEnumerationHandle *rh;
|
|
|
|
rh = (RemoteEndpointInfoEnumerationHandle *)h;
|
|
|
|
FinishRPCDebugEndpointInfoEnumeration(&rh->h);
|
|
delete rh;
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
/// Remote thread enumeration routines
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
typedef struct tagRemoteThreadInfoEnumerationHandle
|
|
{
|
|
RemoteEnumerationHandleType ThisHandleType;
|
|
ThreadInfoEnumerationHandle h;
|
|
} RemoteThreadInfoEnumerationHandle;
|
|
|
|
error_status_t RemoteOpenRPCDebugThreadInfoEnumeration(
|
|
/* [in] */ handle_t IDL_handle,
|
|
/* [out] */ DbgThreadEnumHandle __RPC_FAR *h,
|
|
/* [in] */ DWORD ProcessID,
|
|
/* [in] */ DWORD ThreadID)
|
|
{
|
|
RemoteThreadInfoEnumerationHandle *rh;
|
|
RPC_STATUS Status;
|
|
|
|
*h = NULL;
|
|
|
|
rh = new RemoteThreadInfoEnumerationHandle;
|
|
if (rh == NULL)
|
|
return RPC_S_OUT_OF_MEMORY;
|
|
|
|
rh->ThisHandleType = rehtThreadInfo;
|
|
Status = OpenRPCDebugThreadInfoEnumeration(ProcessID, ThreadID, &rh->h);
|
|
if (Status != RPC_S_OK)
|
|
{
|
|
delete rh;
|
|
return Status;
|
|
}
|
|
|
|
*h = rh;
|
|
|
|
return RPC_S_OK;
|
|
}
|
|
|
|
error_status_t RemoteGetNextRPCDebugThreadInfo(
|
|
/* [in] */ DbgThreadEnumHandle h,
|
|
/* [unique][out][in] */ RemoteDebugThreadInfo __RPC_FAR *__RPC_FAR *debugInfo,
|
|
/* [out] */ DebugCellID __RPC_FAR *CellID,
|
|
/* [out] */ DWORD __RPC_FAR *ProcessID)
|
|
{
|
|
RemoteThreadInfoEnumerationHandle *rh;
|
|
RPC_STATUS Status;
|
|
DebugThreadInfo *NextThread;
|
|
|
|
if (debugInfo == NULL)
|
|
RpcRaiseException(ERROR_INVALID_PARAMETER);
|
|
|
|
*debugInfo = NULL;
|
|
CellID->SectionID = 0;
|
|
CellID->CellID = 0;
|
|
|
|
rh = (RemoteThreadInfoEnumerationHandle *)h;
|
|
if (rh->ThisHandleType != rehtThreadInfo)
|
|
return ERROR_INVALID_HANDLE;
|
|
|
|
Status = GetNextRPCDebugThreadInfo(rh->h, &NextThread, CellID, ProcessID);
|
|
if (Status == RPC_S_OK)
|
|
{
|
|
*debugInfo = (RemoteDebugThreadInfo *) MIDL_user_allocate(sizeof(RemoteDebugThreadInfo));
|
|
if (*debugInfo != NULL)
|
|
{
|
|
TranslateLocalThreadInfoToRemoteThreadInfo(NextThread, *debugInfo);
|
|
}
|
|
else
|
|
Status = RPC_S_OUT_OF_MEMORY;
|
|
}
|
|
return Status;
|
|
}
|
|
|
|
error_status_t RemoteFinishRPCDebugThreadInfoEnumeration(
|
|
/* [out][in] */ DbgThreadEnumHandle __RPC_FAR *h)
|
|
{
|
|
RemoteThreadInfoEnumerationHandle *rh;
|
|
|
|
rh = (RemoteThreadInfoEnumerationHandle *)*h;
|
|
|
|
if (rh == NULL)
|
|
RpcRaiseException(ERROR_INVALID_PARAMETER);
|
|
|
|
if (rh->ThisHandleType != rehtThreadInfo)
|
|
return ERROR_INVALID_HANDLE;
|
|
|
|
DbgThreadEnumHandle_rundown(*h);
|
|
|
|
*h = NULL;
|
|
return RPC_S_OK;
|
|
}
|
|
|
|
void __RPC_USER DbgThreadEnumHandle_rundown(DbgThreadEnumHandle h)
|
|
{
|
|
RemoteThreadInfoEnumerationHandle *rh;
|
|
|
|
rh = (RemoteThreadInfoEnumerationHandle *)h;
|
|
|
|
FinishRPCDebugThreadInfoEnumeration(&rh->h);
|
|
delete rh;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
/// Remote client call enumeration routines
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
typedef struct tagRemoteClientCallInfoEnumerationHandle
|
|
{
|
|
RemoteEnumerationHandleType ThisHandleType;
|
|
ClientCallInfoEnumerationHandle h;
|
|
} RemoteClientCallInfoEnumerationHandle;
|
|
|
|
error_status_t RemoteOpenRPCDebugClientCallInfoEnumeration(
|
|
/* [in] */ handle_t IDL_handle,
|
|
/* [out] */ DbgClientCallEnumHandle __RPC_FAR *h,
|
|
/* [in] */ DWORD CallID,
|
|
/* [in] */ DWORD IfStart,
|
|
/* [in] */ int ProcNum,
|
|
/* [in] */ DWORD ProcessID)
|
|
{
|
|
RemoteClientCallInfoEnumerationHandle *rh;
|
|
RPC_STATUS Status;
|
|
|
|
*h = NULL;
|
|
|
|
rh = new RemoteClientCallInfoEnumerationHandle;
|
|
if (rh == NULL)
|
|
return RPC_S_OUT_OF_MEMORY;
|
|
|
|
rh->ThisHandleType = rehtClientCallInfo;
|
|
Status = OpenRPCDebugClientCallInfoEnumeration(CallID, IfStart, ProcNum, ProcessID, &rh->h);
|
|
if (Status != RPC_S_OK)
|
|
{
|
|
delete rh;
|
|
return Status;
|
|
}
|
|
|
|
*h = rh;
|
|
|
|
return RPC_S_OK;
|
|
}
|
|
|
|
error_status_t RemoteGetNextRPCDebugClientCallInfo(
|
|
/* [in] */ DbgClientCallEnumHandle h,
|
|
/* [unique][out][in] */ RemoteDebugClientCallInfo __RPC_FAR *__RPC_FAR *debugInfo,
|
|
/* [unique][out][in] */ RemoteDebugCallTargetInfo __RPC_FAR *__RPC_FAR *CallTargetDebugInfo,
|
|
/* [out] */ DebugCellID __RPC_FAR *CellID,
|
|
/* [out] */ DWORD __RPC_FAR *ProcessID)
|
|
{
|
|
RemoteClientCallInfoEnumerationHandle *rh;
|
|
RPC_STATUS Status;
|
|
DebugClientCallInfo *NextClientCall;
|
|
DebugCallTargetInfo *NextCallTarget;
|
|
|
|
if (debugInfo == NULL)
|
|
RpcRaiseException(ERROR_INVALID_PARAMETER);
|
|
|
|
if (CallTargetDebugInfo == NULL)
|
|
RpcRaiseException(ERROR_INVALID_PARAMETER);
|
|
|
|
*debugInfo = NULL;
|
|
*CallTargetDebugInfo = NULL;
|
|
CellID->SectionID = 0;
|
|
CellID->CellID = 0;
|
|
|
|
rh = (RemoteClientCallInfoEnumerationHandle *)h;
|
|
if (rh->ThisHandleType != rehtClientCallInfo)
|
|
return ERROR_INVALID_HANDLE;
|
|
|
|
Status = GetNextRPCDebugClientCallInfo(rh->h, &NextClientCall, &NextCallTarget,
|
|
CellID, ProcessID);
|
|
if (Status == RPC_S_OK)
|
|
{
|
|
*debugInfo = (RemoteDebugClientCallInfo *) MIDL_user_allocate(sizeof(RemoteDebugClientCallInfo));
|
|
if (*debugInfo != NULL)
|
|
{
|
|
TranslateLocalClientCallInfoToRemoteClientCallInfo(NextClientCall, *debugInfo);
|
|
|
|
*CallTargetDebugInfo
|
|
= (RemoteDebugCallTargetInfo *)MIDL_user_allocate(sizeof(RemoteDebugCallTargetInfo));
|
|
if (*CallTargetDebugInfo != NULL)
|
|
{
|
|
if ((NextCallTarget != NULL) && (NextCallTarget->Type != dctCallTargetInfo))
|
|
{
|
|
// inconsistent info - return NULL for call target
|
|
MIDL_user_free(*CallTargetDebugInfo);
|
|
*CallTargetDebugInfo = NULL;
|
|
NextCallTarget = NULL;
|
|
}
|
|
else
|
|
{
|
|
TranslateLocalCallTargetInfoToRemoteCallTargetInfo(NextCallTarget, *CallTargetDebugInfo);
|
|
}
|
|
}
|
|
// else - don't care - this is a best effort. We will return what we
|
|
// can. Client is prepared to handle NULL in the call target
|
|
}
|
|
else
|
|
Status = RPC_S_OUT_OF_MEMORY;
|
|
}
|
|
return Status;
|
|
}
|
|
|
|
error_status_t RemoteFinishRPCDebugClientCallInfoEnumeration(
|
|
/* [out][in] */ DbgClientCallEnumHandle __RPC_FAR *h)
|
|
{
|
|
RemoteClientCallInfoEnumerationHandle *rh;
|
|
|
|
rh = (RemoteClientCallInfoEnumerationHandle *)*h;
|
|
|
|
if (rh == NULL)
|
|
RpcRaiseException(ERROR_INVALID_PARAMETER);
|
|
|
|
if (rh->ThisHandleType != rehtClientCallInfo)
|
|
return ERROR_INVALID_HANDLE;
|
|
|
|
DbgClientCallEnumHandle_rundown(*h);
|
|
|
|
*h = NULL;
|
|
return RPC_S_OK;
|
|
}
|
|
|
|
void __RPC_USER DbgClientCallEnumHandle_rundown(DbgClientCallEnumHandle h)
|
|
{
|
|
RemoteClientCallInfoEnumerationHandle *rh;
|
|
|
|
rh = (RemoteClientCallInfoEnumerationHandle *)h;
|
|
|
|
FinishRPCDebugClientCallInfoEnumeration(&rh->h);
|
|
delete rh;
|
|
}
|
|
|
|
END_C_EXTERN
|