diff --git a/dlls/rpcrt4/ncastatus.h b/dlls/rpcrt4/ncastatus.h new file mode 100644 index 00000000000..0a9700268e2 --- /dev/null +++ b/dlls/rpcrt4/ncastatus.h @@ -0,0 +1,66 @@ +/* + * NCA Status definitions + * + * Copyright 2007 Robert Shearman + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#define NCA_S_COMM_FAILURE 0x1C010001 +#define NCA_S_OP_RNG_ERROR 0x1C010002 +#define NCA_S_UNK_IF 0x1C010003 +#define NCA_S_WRONG_BOOT_TIME 0x1C010006 +#define NCA_S_YOU_CRASHED 0x1C010009 +#define NCA_S_PROTO_ERROR 0x1C01000B +#define NCA_S_OUT_ARGS_TOO_BIG 0x1C010013 +#define NCA_S_SERVER_TOO_BUSY 0x1C010014 +#define NCA_S_FAULT_STRING_TOO_LONG 0x1C010015 +#define NCA_S_UNSUPPORTED_TYPE 0x1C010017 + +#define NCA_S_FAULT_INT_DIV_BY_ZERO 0x1C000001 +#define NCA_S_FAULT_ADDR_ERROR 0x1C000002 +#define NCA_S_FAULT_FP_DIV_ZERO 0x1C000003 +#define NCA_S_FAULT_FP_UNDERFLOW 0x1C000004 +#define NCA_S_FAULT_FP_OVERFLOW 0x1C000005 +#define NCA_S_FAULT_INVALID_TAG 0x1C000006 +#define NCA_S_FAULT_INVALID_BOUND 0x1C000007 +#define NCA_S_RPC_VERSION_MISMATCH 0x1C000008 +#define NCA_S_UNSPEC_REJECT 0x1C000009 +#define NCA_S_BAD_ACTID 0x1C00000A +#define NCA_S_WHO_ARE_YOU_FAILED 0x1C00000B +#define NCA_S_MANAGER_NOT_ENTERED 0x1C00000C +#define NCA_S_FAULT_CANCEL 0x1C00000D +#define NCA_S_FAULT_ILL_INST 0x1C00000E +#define NCA_S_FAULT_FP_ERROR 0x1C00000F +#define NCA_S_FAULT_INT_OVERFLOW 0x1C000010 +#define NCA_S_FAULT_UNSPEC 0x1C000012 +#define NCA_S_FAULT_REMOTE_COMM_FAILURE 0x1C000013 +#define NCA_S_FAULT_PIPE_EMPTY 0x1C000014 +#define NCA_S_FAULT_PIPE_CLOSED 0x1C000015 +#define NCA_S_FAULT_PIPE_ORDER 0x1C000016 +#define NCA_S_FAULT_PIPE_DISCIPLINE 0x1C000017 +#define NCA_S_FAULT_PIPE_COMM_ERROR 0x1C000018 +#define NCA_S_FAULT_PIPE_MEMORY 0x1C000019 +#define NCA_S_FAULT_CONTEXT_MISMATCH 0x1C00001A +#define NCA_S_FAULT_REMOTE_NO_MEMORY 0x1C00001B +#define NCA_S_INVALID_PRES_CONTEXT_ID 0x1C00001C +#define NCA_S_UNSUPPORTED_AUTHN_LEVEL 0x1C00001D +#define NCA_S_INVALID_CHECKSUM 0x1C00001F +#define NCA_S_INVALID_CRC 0x1C000020 +#define NCA_S_FAULT_USER_DEFINED 0x1C000021 +#define NCA_S_FAULT_TX_OPEN_FAILED 0x1C000022 +#define NCA_S_FAULT_CODESET_CONV_ERROR 0x1C000023 +#define NCA_S_FAULT_OBJECT_NOT_FOUND 0x1C000024 +#define NCA_S_FAULT_NO_CLIENT_STUB 0x1C000025 diff --git a/dlls/rpcrt4/rpc_message.c b/dlls/rpcrt4/rpc_message.c index 6c3227269bb..3fc8e0f5ca2 100644 --- a/dlls/rpcrt4/rpc_message.c +++ b/dlls/rpcrt4/rpc_message.c @@ -38,6 +38,7 @@ #include "rpc_misc.h" #include "rpc_defs.h" #include "rpc_message.h" +#include "ncastatus.h" WINE_DEFAULT_DEBUG_CHANNEL(rpc); @@ -284,6 +285,74 @@ VOID RPCRT4_FreeHeader(RpcPktHdr *Header) HeapFree(GetProcessHeap(), 0, Header); } +NCA_STATUS RPC2NCA_STATUS(RPC_STATUS status) +{ + switch (status) + { + case ERROR_INVALID_HANDLE: return NCA_S_FAULT_CONTEXT_MISMATCH; + case ERROR_OUTOFMEMORY: return NCA_S_FAULT_REMOTE_NO_MEMORY; + case RPC_S_NOT_LISTENING: return NCA_S_SERVER_TOO_BUSY; + case RPC_S_UNKNOWN_IF: return NCA_S_UNK_IF; + case RPC_S_SERVER_TOO_BUSY: return NCA_S_SERVER_TOO_BUSY; + case RPC_S_CALL_FAILED: return NCA_S_FAULT_UNSPEC; + case RPC_S_CALL_FAILED_DNE: return NCA_S_MANAGER_NOT_ENTERED; + case RPC_S_PROTOCOL_ERROR: return NCA_S_PROTO_ERROR; + case RPC_S_UNSUPPORTED_TYPE: return NCA_S_UNSUPPORTED_TYPE; + case RPC_S_INVALID_TAG: return NCA_S_FAULT_INVALID_TAG; + case RPC_S_INVALID_BOUND: return NCA_S_FAULT_INVALID_BOUND; + case RPC_S_PROCNUM_OUT_OF_RANGE: return NCA_S_OP_RNG_ERROR; + case RPC_X_SS_HANDLES_MISMATCH: return NCA_S_FAULT_CONTEXT_MISMATCH; + case STATUS_FLOAT_DIVIDE_BY_ZERO: return NCA_S_FAULT_FP_DIV_ZERO; + case STATUS_FLOAT_INVALID_OPERATION: return NCA_S_FAULT_FP_ERROR; + case STATUS_FLOAT_OVERFLOW: return NCA_S_FAULT_FP_OVERFLOW; + case STATUS_FLOAT_UNDERFLOW: return NCA_S_FAULT_FP_UNDERFLOW; + case STATUS_INTEGER_DIVIDE_BY_ZERO: return NCA_S_FAULT_INT_DIV_BY_ZERO; + case STATUS_INTEGER_OVERFLOW: return NCA_S_FAULT_INT_OVERFLOW; + default: return status; + } +} + +RPC_STATUS NCA2RPC_STATUS(NCA_STATUS status) +{ + switch (status) + { + case NCA_S_COMM_FAILURE: return RPC_S_COMM_FAILURE; + case NCA_S_OP_RNG_ERROR: return RPC_S_PROCNUM_OUT_OF_RANGE; + case NCA_S_UNK_IF: return RPC_S_UNKNOWN_IF; + case NCA_S_YOU_CRASHED: return RPC_S_CALL_FAILED; + case NCA_S_PROTO_ERROR: return RPC_S_PROTOCOL_ERROR; + case NCA_S_OUT_ARGS_TOO_BIG: return ERROR_NOT_ENOUGH_SERVER_MEMORY; + case NCA_S_SERVER_TOO_BUSY: return RPC_S_SERVER_TOO_BUSY; + case NCA_S_UNSUPPORTED_TYPE: return RPC_S_UNSUPPORTED_TYPE; + case NCA_S_FAULT_INT_DIV_BY_ZERO: return RPC_S_ZERO_DIVIDE; + case NCA_S_FAULT_ADDR_ERROR: return RPC_S_ADDRESS_ERROR; + case NCA_S_FAULT_FP_DIV_ZERO: return RPC_S_FP_DIV_ZERO; + case NCA_S_FAULT_FP_UNDERFLOW: return RPC_S_FP_UNDERFLOW; + case NCA_S_FAULT_FP_OVERFLOW: return RPC_S_FP_OVERFLOW; + case NCA_S_FAULT_INVALID_TAG: return RPC_S_INVALID_TAG; + case NCA_S_FAULT_INVALID_BOUND: return RPC_S_INVALID_BOUND; + case NCA_S_RPC_VERSION_MISMATCH: return RPC_S_PROTOCOL_ERROR; + case NCA_S_UNSPEC_REJECT: return RPC_S_CALL_FAILED_DNE; + case NCA_S_BAD_ACTID: return RPC_S_CALL_FAILED_DNE; + case NCA_S_WHO_ARE_YOU_FAILED: return RPC_S_CALL_FAILED; + case NCA_S_MANAGER_NOT_ENTERED: return RPC_S_CALL_FAILED_DNE; + case NCA_S_FAULT_CANCEL: return RPC_S_CALL_CANCELLED; + case NCA_S_FAULT_ILL_INST: return RPC_S_ADDRESS_ERROR; + case NCA_S_FAULT_FP_ERROR: return RPC_S_FP_OVERFLOW; + case NCA_S_FAULT_INT_OVERFLOW: return RPC_S_ADDRESS_ERROR; + case NCA_S_FAULT_UNSPEC: return RPC_S_CALL_FAILED; + case NCA_S_FAULT_PIPE_EMPTY: return RPC_X_PIPE_EMPTY; + case NCA_S_FAULT_PIPE_CLOSED: return RPC_X_PIPE_CLOSED; + case NCA_S_FAULT_PIPE_ORDER: return RPC_X_WRONG_PIPE_ORDER; + case NCA_S_FAULT_PIPE_DISCIPLINE: return RPC_X_PIPE_DISCIPLINE_ERROR; + case NCA_S_FAULT_PIPE_COMM_ERROR: return RPC_S_COMM_FAILURE; + case NCA_S_FAULT_PIPE_MEMORY: return ERROR_OUTOFMEMORY; + case NCA_S_FAULT_CONTEXT_MISMATCH: return ERROR_INVALID_HANDLE; + case NCA_S_FAULT_REMOTE_NO_MEMORY: return ERROR_NOT_ENOUGH_SERVER_MEMORY; + default: return status; + } +} + static RPC_STATUS RPCRT4_SecurePacket(RpcConnection *Connection, enum secure_packet_direction dir, RpcPktHdr *hdr, unsigned int hdr_size, @@ -927,7 +996,7 @@ RPC_STATUS WINAPI I_RpcSend(PRPC_MESSAGE pMsg) if (bind->server) { if (pMsg->RpcFlags & WINE_RPCFLAG_EXCEPTION) { hdr = RPCRT4_BuildFaultHeader(pMsg->DataRepresentation, - *(DWORD *)pMsg->Buffer); + RPC2NCA_STATUS(*(RPC_STATUS *)pMsg->Buffer)); } else { hdr = RPCRT4_BuildResponseHeader(pMsg->DataRepresentation, pMsg->BufferLength); @@ -1034,7 +1103,7 @@ RPC_STATUS WINAPI I_RpcReceive(PRPC_MESSAGE pMsg) case PKT_FAULT: pMsg->RpcFlags |= WINE_RPCFLAG_EXCEPTION; ERR ("we got fault packet with status 0x%lx\n", hdr->fault.status); - status = hdr->fault.status; /* FIXME: do translation from nca error codes */ + status = NCA2RPC_STATUS(hdr->fault.status); if (is_hard_error(status)) goto fail; break; diff --git a/dlls/rpcrt4/rpc_message.h b/dlls/rpcrt4/rpc_message.h index a9a9f836807..103bc668b6a 100644 --- a/dlls/rpcrt4/rpc_message.h +++ b/dlls/rpcrt4/rpc_message.h @@ -24,6 +24,8 @@ #include "wine/rpcss_shared.h" #include "rpc_defs.h" +typedef unsigned int NCA_STATUS; + RpcPktHdr *RPCRT4_BuildFaultHeader(unsigned long DataRepresentation, RPC_STATUS Status); RpcPktHdr *RPCRT4_BuildBindHeader(unsigned long DataRepresentation, unsigned short MaxTransmissionSize, unsigned short MaxReceiveSize, unsigned long AssocGroupId, const RPC_SYNTAX_IDENTIFIER *AbstractId, const RPC_SYNTAX_IDENTIFIER *TransferId); RpcPktHdr *RPCRT4_BuildBindNackHeader(unsigned long DataRepresentation, unsigned char RpcVersion, unsigned char RpcVersionMinor); @@ -31,5 +33,7 @@ RpcPktHdr *RPCRT4_BuildBindAckHeader(unsigned long DataRepresentation, unsigned VOID RPCRT4_FreeHeader(RpcPktHdr *Header); RPC_STATUS RPCRT4_Send(RpcConnection *Connection, RpcPktHdr *Header, void *Buffer, unsigned int BufferLength); RPC_STATUS RPCRT4_Receive(RpcConnection *Connection, RpcPktHdr **Header, PRPC_MESSAGE pMsg); +NCA_STATUS RPC2NCA_STATUS(RPC_STATUS status); +RPC_STATUS NCA2RPC_STATUS(NCA_STATUS status); #endif diff --git a/dlls/rpcrt4/rpc_server.c b/dlls/rpcrt4/rpc_server.c index 02509029111..20c1afacf1d 100644 --- a/dlls/rpcrt4/rpc_server.c +++ b/dlls/rpcrt4/rpc_server.c @@ -45,6 +45,7 @@ #include "rpc_misc.h" #include "rpc_message.h" #include "rpc_defs.h" +#include "ncastatus.h" WINE_DEFAULT_DEBUG_CHANNEL(rpc); @@ -219,6 +220,7 @@ static void RPCRT4_process_packet(RpcConnection* conn, RpcPktHdr* hdr, RPC_MESSA /* fail if the connection isn't bound with an interface */ if (UuidIsNil(&conn->ActiveInterface.SyntaxGUID, &status)) { + /* FIXME: should send BindNack instead */ response = RPCRT4_BuildFaultHeader(NDR_LOCAL_DATA_REPRESENTATION, status); @@ -237,7 +239,7 @@ static void RPCRT4_process_packet(RpcConnection* conn, RpcPktHdr* hdr, RPC_MESSA if (!sif) { WARN("interface %s no longer registered, returning fault packet\n", debugstr_guid(&conn->ActiveInterface.SyntaxGUID)); response = RPCRT4_BuildFaultHeader(NDR_LOCAL_DATA_REPRESENTATION, - RPC_S_UNKNOWN_IF); + NCA_S_UNK_IF); RPCRT4_Send(conn, response, NULL, 0); RPCRT4_FreeHeader(response); @@ -277,12 +279,12 @@ static void RPCRT4_process_packet(RpcConnection* conn, RpcPktHdr* hdr, RPC_MESSA if (msg->Buffer != buf) I_RpcFreeBuffer(msg); /* this will cause a failure packet to be sent in I_RpcSend */ msg->RpcFlags |= WINE_RPCFLAG_EXCEPTION; - msg->BufferLength = sizeof(DWORD); + msg->BufferLength = sizeof(RPC_STATUS); I_RpcGetBuffer(msg); if (GetExceptionCode() == STATUS_ACCESS_VIOLATION) - *(DWORD*)msg->Buffer = ERROR_NOACCESS; + *(RPC_STATUS*)msg->Buffer = ERROR_NOACCESS; else - *(DWORD*)msg->Buffer = GetExceptionCode(); + *(RPC_STATUS*)msg->Buffer = GetExceptionCode(); } __ENDTRY /* send response packet */