From bf42021e06b6757db5b014a8cde443aada22a0a1 Mon Sep 17 00:00:00 2001 From: Bill Medland Date: Thu, 23 Dec 2004 11:29:54 +0000 Subject: [PATCH] Implemented DceErrorInqText. --- dlls/rpcrt4/rpcrt4.spec | 4 ++-- dlls/rpcrt4/rpcrt4_main.c | 50 +++++++++++++++++++++++++++++++++++++++ dlls/rpcrt4/tests/rpc.c | 45 +++++++++++++++++++++++++++++++++++ include/rpcdce.h | 4 ++++ 4 files changed, 101 insertions(+), 2 deletions(-) diff --git a/dlls/rpcrt4/rpcrt4.spec b/dlls/rpcrt4/rpcrt4.spec index b2285011fc5..7a5aa9c1fae 100644 --- a/dlls/rpcrt4/rpcrt4.spec +++ b/dlls/rpcrt4/rpcrt4.spec @@ -1,5 +1,5 @@ -@ stub DceErrorInqTextA -@ stub DceErrorInqTextW +@ stdcall DceErrorInqTextA (long ptr) +@ stdcall DceErrorInqTextW (long ptr) @ stdcall -private DllRegisterServer() RPCRT4_DllRegisterServer @ stub MesBufferHandleReset diff --git a/dlls/rpcrt4/rpcrt4_main.c b/dlls/rpcrt4/rpcrt4_main.c index d223400b19a..6ceeaa2e239 100644 --- a/dlls/rpcrt4/rpcrt4_main.c +++ b/dlls/rpcrt4/rpcrt4_main.c @@ -748,3 +748,53 @@ BOOL RPCRT4_RPCSSOnDemandCall(PRPCSS_NP_MESSAGE msg, char *vardata_payload, PRPC return TRUE; } + +/* DceErrorInqText + * + * Notes + * 1. On passing a NULL pointer the code does bomb out. + * 2. The size of the required buffer is not defined in the documentation. + * It appears to be 256. + * 3. The function is defined to return RPC_S_INVALID_ARG but I don't know + * of any value for which it does. + * 4. The MSDN documentation currently declares that the second argument is + * unsigned char *, even for the W version. I don't believe it. + */ + +#define MAX_RPC_ERROR_TEXT 256 + +RPC_STATUS RPC_ENTRY DceErrorInqTextW (unsigned long e, unsigned short *buffer) +{ + DWORD count; + count = FormatMessageW (FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, e, 0, buffer, MAX_RPC_ERROR_TEXT, NULL); + if (!count) + { + count = FormatMessageW (FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, RPC_S_NOT_RPC_ERROR, 0, buffer, MAX_RPC_ERROR_TEXT, NULL); + if (!count) + { + ERR ("Failed to translate error"); + return RPC_S_INVALID_ARG; + } + } + return RPC_S_OK; +} + +RPC_STATUS RPC_ENTRY DceErrorInqTextA (unsigned long e, unsigned char *buffer) +{ + RPC_STATUS status; + WCHAR bufferW [MAX_RPC_ERROR_TEXT]; + if ((status = DceErrorInqTextW (e, bufferW)) == RPC_S_OK) + { + if (!WideCharToMultiByte(CP_ACP, 0, bufferW, -1, buffer, MAX_RPC_ERROR_TEXT, + NULL, NULL)) + { + ERR ("Failed to translate error"); + status = RPC_S_INVALID_ARG; + } + } + return status; +} diff --git a/dlls/rpcrt4/tests/rpc.c b/dlls/rpcrt4/tests/rpc.c index a336999545a..efc186cd1c1 100644 --- a/dlls/rpcrt4/tests/rpc.c +++ b/dlls/rpcrt4/tests/rpc.c @@ -28,6 +28,7 @@ #include "wine/unicode.h" #include "rpc.h" +#include "rpcdce.h" static UUID Uuid_Table[10] = { { 0x00000000, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} }, /* 0 (null) */ @@ -122,8 +123,52 @@ void UuidConversionAndComparison(void) { } } +void TestDceErrorInqText (void) +{ + char bufferInvalid [1024]; + char buffer [1024]; /* The required size is not documented but would + * appear to be 256. + */ + DWORD dwCount; + + dwCount = FormatMessageA (FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, RPC_S_NOT_RPC_ERROR, 0, bufferInvalid, + sizeof(bufferInvalid)/sizeof(bufferInvalid[0]), NULL); + + /* A random sample of DceErrorInqText */ + /* 0 is success */ + ok ((DceErrorInqTextA (0, buffer) == RPC_S_OK), + "DceErrorInqTextA(0...)\n"); + /* A real RPC_S error */ + ok ((DceErrorInqTextA (RPC_S_INVALID_STRING_UUID, buffer) == RPC_S_OK), + "DceErrorInqTextA(valid...)\n"); + + if (dwCount) + { + /* A message for which FormatMessage should fail + * which should return RPC_S_OK and the + * fixed "not valid" message + */ + ok ((DceErrorInqTextA (35, buffer) == RPC_S_OK && + strcmp (buffer, bufferInvalid) == 0), + "DceErrorInqTextA(unformattable...)\n"); + /* One for which FormatMessage should succeed but + * DceErrorInqText should "fail" + * 3814 is generally quite a long message + */ + ok ((DceErrorInqTextA (3814, buffer) == RPC_S_OK && + strcmp (buffer, bufferInvalid) == 0), + "DceErrorInqTextA(deviation...)\n"); + } + else + ok (0, "Cannot set up for DceErrorInqText\n"); +} + START_TEST( rpc ) { trace ( " ** Uuid Conversion and Comparison Tests **\n" ); UuidConversionAndComparison(); + trace ( " ** DceErrorInqText **\n"); + TestDceErrorInqText(); } diff --git a/include/rpcdce.h b/include/rpcdce.h index 9e929782aa0..9e9fe018a0b 100644 --- a/include/rpcdce.h +++ b/include/rpcdce.h @@ -109,6 +109,10 @@ typedef struct _RPC_POLICY #define RPC_IF_ALLOW_UNKNOWN_AUTHORITY 0x4 #define RPC_IF_ALLOW_SECURE_ONLY 0x8 +RPC_STATUS RPC_ENTRY DceErrorInqTextA(unsigned long e, unsigned char *buffer); +RPC_STATUS RPC_ENTRY DceErrorInqTextW(unsigned long e, unsigned short *buffer); +#define DceErrorInqText WINELIB_NAME_AW(DceErrorInqText) + RPCRTAPI void RPC_ENTRY RpcRaiseException( RPC_STATUS exception );