/*++ Copyright (C) Microsoft Corporation, 1991 - 2000 Module Name: uclnt.cxx Abstract: This module is half of the build verification for the RPC runtime; the other half can be found in the file usvr.cxx. These two executables (uclnt.exe and usvr.exe) work together to test all runtime APIs. Author: Michael Montague (mikemon) 01-Jan-1990 Revision History: --*/ #include #include #include #include #include "pipe.h" #include "astub.h" #define UCLNT #define swaplong(Value) #define swapshort(Value) #define EXPORT #include #include #include #include BOOL IsWMSG = FALSE ; extern RPC_CLIENT_INTERFACE HelgaInterfaceInformation ; /* Transports: Update this to add a new transport. */ #define RPC_TRANSPORT_NAMEPIPE 1 #define RPC_LRPC 2 #define RPC_TRANSPORT_TCP 3 #define RPC_TRANSPORT_DNET 4 #define RPC_TRANSPORT_NETBIOS 5 #define RPC_TRANSPORT_SPX 6 #define RPC_TRANSPORT_UDP 7 #define RPC_TRANSPORT_IPX 8 #define RPC_TRANSPORT_DSP 9 #define RPC_TRANSPORT_VNS 10 #define RPC_WMSG 11 #define RPC_TRANSPORT_MSMQ 12 // // constants // #define RETRYCOUNT 10 #define RETRYDELAY 500L #define LONG_TESTDELAY 10000L #define EXTENDED_ERROR_EXCEPTION 77777 // // global variables // long TestDelay = 3000L; int NumberOfTestsRun = 0; static unsigned long DefaultThreadStackSize = 0; BOOL fNonCausal = 0; unsigned long HelgaMaxSize = 0xffffffff; unsigned int NoCallBacksFlag = 0; unsigned int UseEndpointMapperFlag = 0; unsigned int MaybeTests = 0; unsigned int IdempotentTests = 0; unsigned int BroadcastTests = 0; unsigned int NoSecurityTests = 0; unsigned int HackForOldStubs = 0; unsigned int DatagramTests = 0; unsigned int fUniqueBinding = 0; int Subtest = 0; int Verbose = 0; int IFSecurityFlag = 0; int AutoListenFlag = 1; char *SecurityUser = NULL; char *SecurityDomain = NULL; char *SecurityPassword = NULL; char *gPrincName = NULL; unsigned long ulSecurityPackage = 10 ; unsigned long TransportType; unsigned int WarnFlag = 0; // Flag for warning messages. unsigned int ErrorFlag = 1; // Flag for error messages. char NetBiosProtocol[20] = "ncacn_nb_nb"; // NetBios transport protocol char * Server ; RPC_STATUS Status; // Contains the status of the last RPC API call. /* volatile */ int fShutdown; // Flag indicating that shutdown should occur. #define CHUNK_SIZE 50 #define NUM_CHUNKS 100 #define BUFF_SIZE 100 // if you change the type of the pipe element // make sure you change the pull and push routines // to correctly initialize the pipe element typedef int pipe_element_t ; typedef struct { void (PAPI *Pull) ( char PAPI *state, pipe_element_t PAPI *buffer, int max_buf, int PAPI *size_to_send ) ; void (PAPI *Push) ( char PAPI *state, pipe_element_t PAPI *input_buffer, int ecount ) ; void (PAPI *Alloc) ( char PAPI *state, int requested_size, pipe_element_t PAPI * PAPI *allocate_buf, int PAPI *allocated_size ) ; char PAPI *state ; } pipe_t ; static CRITICAL_SECTION TestMutex; // // forward declarations // void DgTransport ( int testnum ); void SecurityErrorWrapper( int subtest ); DWORD DumpEeInfo( int indentlevel ); DWORD HelgaSendReceiveFailure ( RPC_BINDING_HANDLE Binding, // Specifies the binding to use in making the // remote procedure call. int ProcNum ); int FooSync ( RPC_BINDING_HANDLE hBinding, /* [in] */ int sizein, /* [in] */ int *bufferin, /* [in, out] */ int *sizeout, /* [out] */ int **bufferout ); // // function definitions // void TestMutexRequest ( void ) { EnterCriticalSection(&TestMutex); } void TestMutexClear ( void ) { LeaveCriticalSection(&TestMutex); } void ApiError ( // An API error occured; we just print a message. IN char * Routine, // The routine which called the API. IN char * API, IN RPC_STATUS status ) { if (ErrorFlag) { TestMutexRequest(); PrintToConsole(" ApiError in %s (%s = %u)\n",Routine,API,status); TestMutexClear(); } // _asm {int 3} ; } void PauseExecution ( unsigned long milliseconds ) { Sleep(milliseconds); } void OtherError ( // Some other error occured; again, we just print a message. IN char * Routine, // The routine where the error occured. IN char * Message ) { if (ErrorFlag) { TestMutexRequest(); PrintToConsole(" Error in %s (%s)\n",Routine,Message); TestMutexClear(); } } unsigned int IsabelleErrors = 0; unsigned int HelgaErrors = 0; unsigned int SylviaErrors = 0; void IsabelleError ( ) { IsabelleErrors += 1 ; } void HelgaError ( ) { HelgaErrors += 1 ; } void SylviaError ( ) { SylviaErrors += 1 ; } #define SIGFRIED 0 #define ELLIOTMINIMIZE 1 #define ELLIOTMAXIMIZE 2 #define ELLIOTNORMAL 3 #define ANDROMIDA 4 #define FREDRICK 7 #define ISABELLENORMAL 10 #define ISABELLEMINIMIZE 11 #define ISABELLEMAXIMIZE 12 #define CHRISTOPHER 13 #define CHRISTOPHERHELGA 14 #define CHRISTOPHERISABELLE 15 #define TYLER 17 #define RICHARD 18 #define RICHARDHELPER 19 #define NOENDPOINT 20 #define DAVIDFIRST 21 #define DAVIDSECOND 22 #define BARTHOLOMEW 23 #define GRANT 24 #define HERMAN 25 #define IVAN 26 #define JASON 27 #define KENNETH 28 #define TESTYIELD 29 #define SPIPE TESTYIELD #define SECURITY_ERROR TESTYIELD /* Transports: Update this to add a new transport. */ char * NamepipeAddresses [] = { "\\pipe\\sigfried", "\\pipe\\elliotmi", "\\pipe\\elliotma", "\\pipe\\elliotno", "\\pipe\\andromno", 0, 0, "\\pipe\\fredrick", 0, 0, "\\pipe\\isabelno", "\\pipe\\isabelmi", "\\pipe\\isabelma", "\\pipe\\christ", "\\pipe\\zippyhe", "\\pipe\\zippyis", 0, "\\pipe\\tyler", "\\pipe\\richard", "\\pipe\\richardh", 0, "\\pipe\\david1", "\\pipe\\david2", "\\pipe\\bart", "\\pipe\\grant", "\\pipe\\herman", "\\pipe\\ivan", "\\pipe\\jason", "\\pipe\\kenneth", "\\pipe\\testyield" }; char * DspAddresses [] = { "\\pipe\\sigfried", "\\pipe\\elliotmi", "\\pipe\\elliotma", "\\pipe\\elliotno", "\\pipe\\andromno", 0, 0, "\\pipe\\fredrick", 0, 0, "\\pipe\\isabelno", "\\pipe\\isabelmi", "\\pipe\\isabelma", "\\pipe\\christ", "\\pipe\\zippyhe", "\\pipe\\zippyis", 0, "\\pipe\\tyler", "\\pipe\\richard", "\\pipe\\richardh", 0, "\\pipe\\david1", "\\pipe\\david2", "\\pipe\\bart", "\\pipe\\grant", "\\pipe\\herman", "\\pipe\\ivan", "\\pipe\\jason", "\\pipe\\kenneth", "\\pipe\\testyield" }; char * TCPDefaultServer = "serverhost"; char * UDPDefaultServer = "serverhost"; char * NetBiosAddresses [] = { "201", // sigfried "202", // elliotmi "203", // elliotma "204", // elliotno "205", // andromno 0, 0, "206", // fredrick 0, 0, "207", // isabelno "208", // isabelmi "209", // isabelma "210", // christ "211", // zippyhe "212", // zippyis 0, "214", // tyler "215", // richard "216", // richardh 0, "217", // david1 "218", // david2 "219", // bart "220", // grant "221", // herman "222", // ivan "223", // jason "224", // kenneth "225" // testyield }; char * TCPAddresses [] = { "2025", // SIGFRIED "2026", // ELLIOTMINIMIZE "2027", // ELLIOTMAXIMIZE "2028", // ELLIOTNORMAL "2029", // ANDROMIDA 0, 0, "2032", // FREDRICK 0, 0, "2035", // ISABELLENORMAL "2036", // ISABELLEMINIMIZE "2037", // ISABELLEMAXIMIZE "2038", // CHRISTOPHER "2039", // CHRISTOPHERHELGA "2040", // CHRISTOPHERISABELLE 0, "2042", // TYLER "2043", // RICHARD "2044", // RICHARDHELPER 0, "2045", //D1 "2046", //D2 "2047", // Bartholomew "2048", // Grant "2049", // Herman "2050", // Ivan "2051", // Jason "2052", // Kenneth "2053" // TestYield }; char * UDPAddresses [] = { "2025", // SIGFRIED "2026", // ELLIOTMINIMIZE "2027", // ELLIOTMAXIMIZE "2028", // ELLIOTNORMAL "2029", // ANDROMIDA 0, 0, "2032", // FREDRICK 0, 0, "2035", // ISABELLENORMAL "2036", // ISABELLEMINIMIZE "2037", // ISABELLEMAXIMIZE "2038", // CHRISTOPHER "2039", // CHRISTOPHERHELGA "2040", // CHRISTOPHERISABELLE 0, "2042", // TYLER "2043", // RICHARD "2044", // RICHARDHELPER 0, "2045", //D1 "2046", //D2 "2047", // Bartholomew "2048", // Grant "2049", // Herman "2050", // Ivan "2051", // Jason "2052", // Kenneth "2053" // TestYield }; char * SPCAddresses [] = { "sigfried", "elliotminimize", "elliotmaximize", "elliotnormal", "andromida", 0, 0, "fredrick", 0, 0, "isabellenormal", "isabelleminimize", "isabellemaximize", "christopher", "christopherhelga", "christopherisabelle", 0, "tyler", "richard", "richardhelper", 0, "davidfirst", "davidsecond", "bartholomew", "grant", "herman", "ivan", "jason", "kenneth", "testyield" }; char * SPXAddresses [] = { "5000", // sigfried "5001", // elliotmi "5002", // elliotma "5003", // elliotno "5004", // andromno "5005", "5006", "5007", // fredrick "5008", "5009", "5010", // isabelno "5011", // isabelmi "5012", // isabelma "5013", // christ "5014", // zippyhe "5015", // zippyis "5016", "5017", // tyler "5020", // richard "5021", // richardh 0, "5022", // david1 "5023", // david2 "5024", // bart "5025", // grant "5026", // herman "5027", // ivan "5028", // jason "5029", // kenneth "5030" // testyield }; char * IPXAddresses [] = { "5000", // sigfried "5001", // elliotmi "5002", // elliotma "5003", // elliotno "5004", // andromno "5005", "5006", "5007", // fredrick "5008", "5009", "5010", // isabelno "5011", // isabelmi "5012", // isabelma "5013", // christ "5014", // zippyhe "5015", // zippyis "5016", "5017", // tyler "5020", // richard "5021", // richardh 0, "5022", // david1 "5023", // david2 "5024", // bart "5025", // grant "5026", // herman "5027", // ivan "5028", // jason "5029", // kenneth "5030" // testyield }; char * VNSAddresses [] = { "250", // sigfried "251", // elliotmi "252", // elliotma "253", // elliotno "254", // andromno "255", "256", "257", // fredrick "258", "259", "260", // isabelno "261", // isabelmi "262", // isabelma "263", // christ "264", // zippyhe "265", // zippyis "266", "267", // tyler "270", // richard "271", // richardh 0, "272", // david1 "273", // david2 "274", // bart "275", // grant "276", // herman "277", // ivan "278", // jason "279", // kenneth "280" // testyield }; char * MSMQAddresses [] = { "SIGFRIED", "ELLIOTMINIMIZE", "ELLIOTMAXIMIZE", "ELLIOTNORMAL", "ANDROMIDA", 0, 0, "FREDRICK", 0, 0, "ISABELLENORMAL", "ISABELLEMINIMIZE", "ISABELLEMAXIMIZE", "CHRISTOPHER", "CHRISTOPHERHELGA", "CHRISTOPHERISABELLE", 0, "TYLER", "RICHARD", "RICHARDHELPER", 0, "D1", "D2", "Bartholomew", "Grant", "Herman", "Ivan", "Jason", "Kenneth", "TestYield" }; unsigned char PAPI * GetStringBinding ( IN unsigned int Address, IN char PAPI * ObjectUuid, OPTIONAL IN unsigned char PAPI * NetworkOptions OPTIONAL ) /*++ Routine Description: A string binding for the desired address is constructed. Arguments: Address - Supplies an index into a table of endpoints. ObjectUuid - Optionally supplies the string representation of a UUID to be specified as the object uuid in the string binding. NetworkOptions - Optionally supplies the network options for this string binding. Return Value: The constructed string binding will be returned. Transports: Update this to add a new transport. --*/ { unsigned char PAPI * StringBinding; if (TransportType == RPC_TRANSPORT_NAMEPIPE) { Status = RpcStringBindingComposeA((unsigned char PAPI *) ObjectUuid, (unsigned char PAPI *) "ncacn_np", #ifdef WIN32RPC (unsigned char PAPI *) ((Server)? Server: "\\\\."), #else (unsigned char PAPI *) Server, #endif (unsigned char PAPI *) NamepipeAddresses[Address], NetworkOptions, &StringBinding); } if (TransportType == RPC_TRANSPORT_NETBIOS) { Status = RpcStringBindingComposeA((unsigned char PAPI *) ObjectUuid, (unsigned char PAPI *) NetBiosProtocol, (unsigned char PAPI *) Server, (unsigned char PAPI *) NetBiosAddresses[Address], NetworkOptions, &StringBinding); } if (TransportType == RPC_LRPC) { Status = RpcStringBindingComposeA((unsigned char PAPI *) ObjectUuid, (unsigned char PAPI *) "ncalrpc", NULL, (unsigned char PAPI *) SPCAddresses[Address], NetworkOptions, &StringBinding); } if (TransportType == RPC_TRANSPORT_TCP) { Status = RpcStringBindingComposeA((unsigned char PAPI *) ObjectUuid, (unsigned char PAPI *) "ncacn_ip_tcp", (unsigned char PAPI *) Server, (unsigned char PAPI *) TCPAddresses[Address], NetworkOptions, &StringBinding); } if (TransportType == RPC_TRANSPORT_UDP) { Status = RpcStringBindingComposeA((unsigned char PAPI *) ObjectUuid, (unsigned char PAPI *) "ncadg_ip_udp", (unsigned char PAPI *) Server, (unsigned char PAPI *) UDPAddresses[Address], NetworkOptions, &StringBinding); } if (TransportType == RPC_TRANSPORT_SPX) { Status = RpcStringBindingComposeA((unsigned char PAPI *) ObjectUuid, (unsigned char PAPI *) "ncacn_spx", (unsigned char PAPI *) Server, (unsigned char PAPI *) SPXAddresses[Address], NetworkOptions, &StringBinding); } if (TransportType == RPC_TRANSPORT_IPX) { Status = RpcStringBindingComposeA((unsigned char PAPI *) ObjectUuid, (unsigned char PAPI *) "ncadg_ipx", (unsigned char PAPI *) Server, (unsigned char PAPI *) IPXAddresses[Address], NetworkOptions, &StringBinding); } if (TransportType == RPC_TRANSPORT_DSP) { Status = RpcStringBindingComposeA((unsigned char PAPI *) ObjectUuid, (unsigned char PAPI *) "ncacn_at_dsp", (unsigned char PAPI *) Server, (unsigned char PAPI *) DspAddresses[Address], NetworkOptions, &StringBinding); } if (TransportType == RPC_TRANSPORT_VNS) { Status = RpcStringBindingComposeA((unsigned char PAPI *) ObjectUuid, (unsigned char PAPI *) "ncacn_vns_spp", (unsigned char PAPI *) Server, (unsigned char PAPI *) VNSAddresses[Address], NetworkOptions, &StringBinding); } if (TransportType == RPC_TRANSPORT_MSMQ) { Status = RpcStringBindingComposeA((unsigned char PAPI *) ObjectUuid, (unsigned char PAPI *) "ncadg_mq", (unsigned char PAPI *) Server, (unsigned char PAPI *) MSMQAddresses[Address], NetworkOptions, &StringBinding); } if (Status) { ApiError("GetStringBinding","RpcStringBindingCompose",Status); PrintToConsole("GetStringBinding failed in "); PrintToConsole("RpcStringBindingCompose\n"); return(0); } return(StringBinding); } RPC_STATUS GetBinding ( IN unsigned int Address, OUT RPC_BINDING_HANDLE PAPI * Binding ) /*++ Routine Description: A binding for the desired address is constructed. This is a wrapper around GetStringBinding and RpcBindingFromStringBinding. Arguments: Address - Supplies an index into a table of endpoints. Binding - A pointer to the location to store the returned binding handle. Return Value: The status code from RpcBindingFromStringBinding is returned. --*/ { unsigned char PAPI * StringBinding; RPC_STATUS FreeStatus; StringBinding = GetStringBinding(Address, 0, 0); Status = RpcBindingFromStringBindingA(StringBinding, Binding); if (Status) ApiError("GetBinding","RpcBindingFromStringBinding",Status); if (IFSecurityFlag) { Status = RpcBindingSetAuthInfo( *Binding, NULL, RPC_C_AUTHN_LEVEL_CONNECT, 10, NULL, NULL); if (Status != RPC_S_OK) { ApiError("GetBinding","RpcBindingSetAuthInfo",Status); return Status; } } if (StringBinding) { FreeStatus = RpcStringFreeA(&StringBinding); if (FreeStatus) { ApiError("GetBinding","RpcStringFree",FreeStatus); PrintToConsole("GetBinding failed in "); PrintToConsole("RpcStringFree\n"); } } if (fUniqueBinding) { Status = RpcBindingSetOption( *Binding, RPC_C_OPT_UNIQUE_BINDING, TRUE ); if (Status != RPC_S_OK) { ApiError("GetBinding","RpcBindingSetOption",Status); return Status; } } return(Status); } RPC_STATUS UclntSendReceive ( IN OUT PRPC_MESSAGE RpcMessage ) /*++ Routine Description: This routine takes care of retrying to send the remote procedure call. Arguments: RpcMessage - Supplies and returns the message for I_RpcSendReceive. Return Value: The result of I_RpcSendReceive will be returned. --*/ { Status = I_RpcSendReceive(RpcMessage); return(Status); } RPC_STATUS UclntGetBuffer ( IN OUT PRPC_MESSAGE RpcMessage ) /*++ Routine Description: This routine takes care of retrying to getting a buffer. Arguments: RpcMessage - Supplies and returns the message for I_RpcGetBuffer. Return Value: The result of I_RpcGetBuffer will be returned. --*/ { unsigned int RetryCount; RPC_BINDING_HANDLE Handle = RpcMessage->Handle; for (RetryCount = 0; RetryCount < RETRYCOUNT; RetryCount++) { RpcMessage->Handle = Handle; Status = I_RpcGetBuffer(RpcMessage); if ( (Status != RPC_S_SERVER_TOO_BUSY) && (Status != RPC_S_CALL_FAILED_DNE)) break; PauseExecution(RETRYDELAY); } return(Status); } /* -------------------------------------------------------------------- Isabelle Interface -------------------------------------------------------------------- */ RPC_PROTSEQ_ENDPOINT IsabelleRpcProtseqEndpoint[] = { {(unsigned char *) "ncacn_np", #ifdef WIN32RPC (unsigned char *) "\\pipe\\zippyis"}, #else // WIN32RPC (unsigned char *) "\\device\\namedpipe\\christopherisabelle"}, #endif // WIN32RPC {(unsigned char *) "ncacn_ip_tcp",(unsigned char *) "2040"} ,{(unsigned char *) "ncadg_ip_udp",(unsigned char *) "2040"} ,{(unsigned char *) "ncalrpc",(unsigned char *) "christopherisabelle"} ,{(unsigned char *) "ncacn_nb_nb",(unsigned char *) "212"} ,{(unsigned char *) "ncacn_spx",(unsigned char *) "5015"} ,{(unsigned char *) "ncadg_ipx",(unsigned char *) "5015"} ,{(unsigned char *) "ncacn_vns_spp", (unsigned char *) "265"} ,{(unsigned char *) "ncacn_at_dsp", (unsigned char *) "\\pipe\\zippyis"} ,{(unsigned char *) "ncadg_mq", (unsigned char *) "christopherisabelle"} }; RPC_CLIENT_INTERFACE IsabelleInterfaceInformation = { sizeof(RPC_CLIENT_INTERFACE), {{9,8,8,{7,7,7,7,7,7,7,7}}, {1,1}}, {{0x8A885D04,0x1CEB,0x11C9,{0x9F,0xE8,0x08,0x00,0x2B,0x10,0x48,0x60}}, {2,0}}, /* {4,5}}, */ 0, sizeof(IsabelleRpcProtseqEndpoint) / sizeof(RPC_PROTSEQ_ENDPOINT), IsabelleRpcProtseqEndpoint, 0, NULL, RPC_INTERFACE_HAS_PIPES }; void IsabelleShutdown ( RPC_BINDING_HANDLE Binding // Specifies the binding to use in making the // remote procedure call. ) { RPC_MESSAGE Caller; Caller.Handle = Binding; Caller.BufferLength = 0; Caller.ProcNum = 0 | HackForOldStubs ; Caller.RpcInterfaceInformation = &IsabelleInterfaceInformation; Caller.RpcFlags = 0; if (IdempotentTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_IDEMPOTENT; } if (MaybeTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_MAYBE; } if (BroadcastTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_BROADCAST; } Status = UclntGetBuffer(&Caller); if (Status) { ApiError("IsabelleShutdown", "I_RpcGetBuffer", Status); IsabelleError(); return; } Status = UclntSendReceive(&Caller); if (Status) { ApiError("IsabelleShutdown","I_RpcSendReceive",Status); IsabelleError(); return; } else { if (Caller.BufferLength != 0) { OtherError("IsabelleShutdown","BufferLength != 0"); IsabelleError(); return; } Status = I_RpcFreeBuffer(&Caller); if (Status) { ApiError("IsabelleShutdown","I_RpcFreeBuffer",Status); IsabelleError(); return; } } } void IsabelleNtSecurity ( RPC_BINDING_HANDLE Binding, // Specifies the binding to use in making the // remote procedure call. unsigned int BufferLength, void PAPI * Buffer ) { RPC_MESSAGE Caller; Caller.Handle = Binding; Caller.BufferLength = BufferLength; Caller.ProcNum = 1 | HackForOldStubs ; Caller.RpcInterfaceInformation = &IsabelleInterfaceInformation; Caller.RpcFlags = 0; if (IdempotentTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_IDEMPOTENT; } if (MaybeTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_MAYBE; } if (BroadcastTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_BROADCAST; } Status = UclntGetBuffer(&Caller); if (Status) { ApiError("IsabelleNtSecurity","I_RpcGetBuffer",Status); IsabelleError(); return; } RpcpMemoryCopy(Caller.Buffer,Buffer,BufferLength); Status = UclntSendReceive(&Caller); if (Status) { ApiError("IsabelleNtSecurity","I_RpcSendReceive",Status); IsabelleError(); return; } else { if (Caller.BufferLength != 0) { OtherError("IsabelleNtSecurity","BufferLength != 0"); IsabelleError(); return; } Status = I_RpcFreeBuffer(&Caller); if (Status) { ApiError("IsabelleNtSecurity","I_RpcFreeBuffer",Status); IsabelleError(); return; } } } void IsabelleToStringBinding ( RPC_BINDING_HANDLE Binding // Specifies the binding to use in making the // remote procedure call. ) { RPC_MESSAGE Caller; Caller.Handle = Binding; Caller.BufferLength = 0; Caller.ProcNum = 2 | HackForOldStubs ; Caller.RpcInterfaceInformation = &IsabelleInterfaceInformation; Caller.RpcFlags = 0; if (IdempotentTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_IDEMPOTENT; } if (MaybeTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_MAYBE; } if (BroadcastTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_BROADCAST; } Status = UclntGetBuffer(&Caller); if (Status) { ApiError("IsabelleToStringBinding", "I_RpcGetBuffer", Status); IsabelleError(); return; } Status = UclntSendReceive(&Caller); if (Status) { ApiError("IsabelleToStringBinding","I_RpcSendReceive",Status); IsabelleError(); return; } else { if (Caller.BufferLength != 0) { OtherError("IsabelleToStringBinding","BufferLength != 0"); IsabelleError(); return; } Status = I_RpcFreeBuffer(&Caller); if (Status) { ApiError("IsabelleToStringBinding","I_RpcFreeBuffer",Status); IsabelleError(); return; } } } #define RICHARDHELPER_EXIT 1 #define RICHARDHELPER_EXECUTE 2 #define RICHARDHELPER_IGNORE 3 #define RICHARDHELPER_DELAY_EXIT 4 RPC_STATUS IsabelleRichardHelper ( IN RPC_BINDING_HANDLE Binding, IN unsigned /*long*/ char Command ) /*++ Routine Description: This routine is the caller stub for the IsabelleRichardHelper routine on the server side. We marshall the command, and use the supplied binding handle to direct the call. Arguments: Binding - Supplies a binding to direct the call. Command - Supplies a command for IsabelleRichardHelper to execute on the server side. Command must be one of the following values. RICHARDHELPER_EXIT - This value will cause the server to exit. RICHARDHELPER_EXECUTE - The server will execute usvr.exe with this the -richardhelper flag. RICHARDHELPER_IGNORE - The server will do nothing except return. Return Value: The status of the operation will be returned. This will be the status codes returned from RpcGetBuffer and/or RpcSendReceive. --*/ { RPC_MESSAGE Caller; unsigned /*long*/ char PAPI * plScan; Caller.Handle = Binding; Caller.BufferLength = sizeof(unsigned /*long*/ char); Caller.ProcNum = 3 | HackForOldStubs ; Caller.RpcInterfaceInformation = &IsabelleInterfaceInformation; Caller.RpcFlags = 0; if (IdempotentTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_IDEMPOTENT; } if (MaybeTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_MAYBE; } if (BroadcastTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_BROADCAST; } Status = UclntGetBuffer(&Caller); if (Status != RPC_S_OK) return(Status); plScan = (unsigned /*long*/ char PAPI *) Caller.Buffer; *plScan = Command; Status = UclntSendReceive(&Caller); if (Status != RPC_S_OK) return(Status); return(I_RpcFreeBuffer(&Caller)); } RPC_STATUS IsabelleRaiseException ( IN RPC_BINDING_HANDLE Binding, IN unsigned /*long*/ char Exception ) /*++ Routine Description: This routine is the caller stub for the IsabelleRaiseException routine on the server side. We marshall the exception code, and use the supplied binding handle to direct the call. Arguments: Binding - Supplies a binding to direct the call. Exception - Supplies the exception to be raised by IsabelleRaiseException. Return Value: The exception raised will be returned. --*/ { RPC_MESSAGE Caller; unsigned /*long*/ char PAPI * plScan; Caller.Handle = Binding; Caller.BufferLength = sizeof(unsigned /*long*/ char); Caller.ProcNum = 4 | HackForOldStubs ; Caller.RpcInterfaceInformation = &IsabelleInterfaceInformation; Caller.RpcFlags = 0; if (IdempotentTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_IDEMPOTENT; } if (MaybeTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_MAYBE; } if (BroadcastTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_BROADCAST; } Status = UclntGetBuffer(&Caller); if (Status != RPC_S_OK) return(Status); plScan = (unsigned /*long*/ char PAPI *) Caller.Buffer; *plScan = Exception; Status = UclntSendReceive(&Caller); return(Status); } void IsabelleSetRundown ( RPC_BINDING_HANDLE Binding ) /*++ Routine Description: This is the caller stub which will request that the server set a rundown routine for the association over which the call came. Arguments: Binding - Supplies a binding handle to be used to direct the remote procedure call. --*/ { RPC_MESSAGE Caller; Caller.Handle = Binding; Caller.BufferLength = 0; Caller.ProcNum = 5 | HackForOldStubs ; Caller.RpcInterfaceInformation = &IsabelleInterfaceInformation; Caller.RpcFlags = 0; if (IdempotentTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_IDEMPOTENT; } if (MaybeTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_MAYBE; } if (BroadcastTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_BROADCAST; } Status = UclntGetBuffer(&Caller); if (Status) { ApiError("IsabelleSetRundown", "I_RpcGetBuffer", Status); IsabelleError(); return; } Status = UclntSendReceive(&Caller); if (Status) { ApiError("IsabelleSetRundown","I_RpcSendReceive",Status); IsabelleError(); return; } else { if (Caller.BufferLength != 0) { OtherError("IsabelleSetRundown","BufferLength != 0"); IsabelleError(); return; } Status = I_RpcFreeBuffer(&Caller); if (Status) { ApiError("IsabelleSetRundown","I_RpcFreeBuffer",Status); IsabelleError(); return; } } } void IsabelleCheckRundown ( RPC_BINDING_HANDLE Binding ) /*++ Routine Description: This is the caller stub which will request that the server check that the rundown routine actually got called. Arguments: Binding - Supplies a binding handle to be used to direct the remote procedure call. --*/ { RPC_MESSAGE Caller; Caller.Handle = Binding; Caller.BufferLength = 0; Caller.ProcNum = 6| HackForOldStubs ; Caller.RpcInterfaceInformation = &IsabelleInterfaceInformation; Caller.RpcFlags = 0; if (IdempotentTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_IDEMPOTENT; } if (MaybeTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_MAYBE; } if (BroadcastTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_BROADCAST; } Status = UclntGetBuffer(&Caller); if (Status) { ApiError("IsabelleCheckRundown", "I_RpcGetBuffer", Status); IsabelleError(); return; } Status = UclntSendReceive(&Caller); if (Status) { ApiError("IsabelleCheckRundown","I_RpcSendReceive",Status); IsabelleError(); return; } else { if (Caller.BufferLength != 0) { OtherError("IsabelleCheckRundown","BufferLength != 0"); IsabelleError(); return; } Status = I_RpcFreeBuffer(&Caller); if (Status) { ApiError("IsabelleCheckRundown","I_RpcFreeBuffer",Status); IsabelleError(); return; } } } void IsabelleMustFail ( RPC_BINDING_HANDLE Binding ) /*++ Routine Description: Arguments: Binding - Supplies a binding handle to be used to direct the remote procedure call. --*/ { RPC_MESSAGE Caller; Caller.Handle = Binding; Caller.BufferLength = 0; Caller.ProcNum = 6| HackForOldStubs ; Caller.RpcInterfaceInformation = &IsabelleInterfaceInformation; Caller.RpcFlags = 0; if (IdempotentTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_IDEMPOTENT; } if (MaybeTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_MAYBE; } if (BroadcastTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_BROADCAST; } Status = UclntGetBuffer(&Caller); if (Status) { return; } Status = UclntSendReceive(&Caller); if (Status) { return; } PrintToConsole("IsabelleMustFail: This call is supposed to fail\n") ; IsabelleError(); } void IsabelleCheckContext ( RPC_BINDING_HANDLE Binding ) /*++ Routine Description: This is the caller stub which will request that the server check the association context for this association (the one the call comes in other), and then to set a new association context. Arguments: Binding - Supplies a binding handle to be used to direct the remote procedure call. --*/ { RPC_MESSAGE Caller; Caller.Handle = Binding; Caller.BufferLength = 0; Caller.ProcNum = 7 | HackForOldStubs ; Caller.RpcInterfaceInformation = &IsabelleInterfaceInformation; Caller.RpcFlags = 0; if (IdempotentTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_IDEMPOTENT; } if (MaybeTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_MAYBE; } if (BroadcastTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_BROADCAST; } Status = UclntGetBuffer(&Caller); if (Status) { ApiError("IsabelleCheckContext", "I_RpcGetBuffer", Status); IsabelleError(); return; } Status = UclntSendReceive(&Caller); if (Status) { ApiError("IsabelleCheckContext","I_RpcSendReceive",Status); IsabelleError(); return; } else { if (Caller.BufferLength != 0) { OtherError("IsabelleCheckContext","BufferLength != 0"); IsabelleError(); return; } Status = I_RpcFreeBuffer(&Caller); if (Status) { ApiError("IsabelleCheckContext","I_RpcFreeBuffer",Status); IsabelleError(); return; } } } unsigned char * IsabelleGetStringBinding ( RPC_BINDING_HANDLE Binding ) /*++ Routine Description: This is the caller stub which will request that the server return the next string binding from the list of bindings supported by the server. Arguments: Binding - Supplies a binding handle to be used to direct the remote procedure call. Return Value: A copy of the string binding will be returned. This can be freed using the delete operator. If there are no more string bindings, or an error occurs, zero will be returned. --*/ { RPC_MESSAGE Caller; unsigned char * StringBinding; Caller.Handle = Binding; Caller.BufferLength = 0; Caller.ProcNum = 8 | HackForOldStubs ; Caller.RpcInterfaceInformation = &IsabelleInterfaceInformation; Caller.RpcFlags = 0; if (IdempotentTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_IDEMPOTENT; } if (MaybeTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_MAYBE; } if (BroadcastTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_BROADCAST; } Status = UclntGetBuffer(&Caller); if (Status) { ApiError("IsabelleGetStringBinding", "I_RpcGetBuffer", Status); IsabelleError(); return(0); } Status = UclntSendReceive(&Caller); if (Status) { ApiError("IsabelleGetStringBinding","I_RpcSendReceive",Status); IsabelleError(); return(0); } if (Caller.BufferLength != 0) { StringBinding = new unsigned char[Caller.BufferLength]; RpcpMemoryCopy(StringBinding,Caller.Buffer,Caller.BufferLength); } else StringBinding = 0; Status = I_RpcFreeBuffer(&Caller); if (Status) { ApiError("IsabelleGetStringBinding","I_RpcFreeBuffer",Status); IsabelleError(); return(0); } return(StringBinding); } void IsabelleCheckNoRundown ( RPC_BINDING_HANDLE Binding ) /*++ Routine Description: This is the caller stub which will request that the server check that the rundown routine did not get called. Arguments: Binding - Supplies a binding handle to be used to direct the remote procedure call. --*/ { RPC_MESSAGE Caller; Caller.Handle = Binding; Caller.BufferLength = 0; Caller.ProcNum = 9| HackForOldStubs ; Caller.RpcInterfaceInformation = &IsabelleInterfaceInformation; Caller.RpcFlags = 0; if (IdempotentTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_IDEMPOTENT; } if (MaybeTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_MAYBE; } if (BroadcastTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_BROADCAST; } Status = UclntGetBuffer(&Caller); if (Status) { ApiError("IsabelleCheckNoRundown", "I_RpcGetBuffer", Status); IsabelleError(); return; } Status = UclntSendReceive(&Caller); if (Status) { ApiError("IsabelleCheckNoRundown","I_RpcSendReceive",Status); IsabelleError(); return; } else { if (Caller.BufferLength != 0) { OtherError("IsabelleCheckNoRundown","BufferLength != 0"); IsabelleError(); return; } Status = I_RpcFreeBuffer(&Caller); if (Status) { ApiError("IsabelleCheckNoRundown","I_RpcFreeBuffer",Status); IsabelleError(); return; } } } void IsabelleUnregisterInterfaces ( RPC_BINDING_HANDLE Binding ) /*++ Routine Description: Arguments: Binding - Supplies a binding handle to be used to direct the remote procedure call. --*/ { RPC_MESSAGE Caller; Caller.Handle = Binding; Caller.BufferLength = 0; Caller.ProcNum = 11| HackForOldStubs ; Caller.RpcInterfaceInformation = &IsabelleInterfaceInformation; Caller.RpcFlags = 0; if (IdempotentTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_IDEMPOTENT; } if (MaybeTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_MAYBE; } if (BroadcastTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_BROADCAST; } Status = UclntGetBuffer(&Caller); if (Status) { ApiError("IsabelleUnregisterInterfaces", "I_RpcGetBuffer", Status); IsabelleError(); return; } Status = UclntSendReceive(&Caller); if (Status) { ApiError("IsabelleUnregisterInterfaces","I_RpcSendReceive",Status); IsabelleError(); return; } Status = I_RpcFreeBuffer(&Caller); if (Status) { ApiError("IsabelleUnregisterInterfaces","I_RpcFreeBuffer",Status); IsabelleError(); return; } } void IsabelleRegisterInterfaces ( RPC_BINDING_HANDLE Binding ) /*++ Routine Description: Arguments: Binding - Supplies a binding handle to be used to direct the remote procedure call. --*/ { RPC_MESSAGE Caller; Caller.Handle = Binding; Caller.BufferLength = 0; Caller.ProcNum = 12| HackForOldStubs ; Caller.RpcInterfaceInformation = &IsabelleInterfaceInformation; Caller.RpcFlags = 0; if (IdempotentTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_IDEMPOTENT; } if (MaybeTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_MAYBE; } if (BroadcastTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_BROADCAST; } Status = UclntGetBuffer(&Caller); if (Status) { ApiError("IsabelleRegisterInterfaces", "I_RpcGetBuffer", Status); IsabelleError(); return; } Status = UclntSendReceive(&Caller); if (Status) { ApiError("IsabelleRegisterInterfaces","I_RpcSendReceive",Status); IsabelleError(); return; } Status = I_RpcFreeBuffer(&Caller); if (Status) { ApiError("IsabelleRegisterInterfaces","I_RpcFreeBuffer",Status); IsabelleError(); return; } } void PipeAlloc( char PAPI *state, int requested_size, pipe_element_t PAPI * PAPI *allocated_buf, int PAPI * allocated_size) { static int size = 0; static void PAPI *buffer = NULL; if (size < requested_size) { if (buffer) { I_RpcFree(buffer) ; } buffer = I_RpcAllocate(requested_size) ; if (buffer == 0) { *allocated_size = 0 ; size = 0 ; } else { *allocated_size = requested_size ; size = requested_size ; } *allocated_buf = (pipe_element_t PAPI *) buffer ; } else { *allocated_buf = (pipe_element_t PAPI *) buffer ; *allocated_size = size ; } } void PipePull( char PAPI *state, pipe_element_t PAPI *buffer, int num_buf_elem, int PAPI *size_to_send ) { int i ; char j = 0; if (*((int PAPI *)state) <= 0) { *size_to_send = 0 ; return ; } // fill pipe elements for (i = 0; iAlloc(pipe->state, chunksize * sizeof(pipe_element_t) + sizeof(DWORD), &buf, &num_buf_bytes ) ; num_buf_elem = (num_buf_bytes -sizeof(DWORD)) / sizeof(pipe_element_t) ; pipe->Pull(pipe->state, (pipe_element_t PAPI *) ((char PAPI *) buf+sizeof(DWORD)), num_buf_elem, &count ) ; *((DWORD PAPI *) buf) = count ; LengthToSend = (count * sizeof(pipe_element_t)) + sizeof(DWORD) ; Status = I_RpcReallocPipeBuffer(&Caller, LengthToSend+BufferOffset) ; if (Status) { ApiError("IsabellePipeIN","I_RpcReallocPipeBuffer",Status); IsabelleError(); return; } if (count == 0) { Caller.RpcFlags = 0 ; } RpcpMemoryCopy((char PAPI *) Caller.Buffer+BufferOffset, buf, LengthToSend) ; Status = I_RpcSend(&Caller) ; if (Status == RPC_S_SEND_INCOMPLETE) { BufferOffset = Caller.BufferLength ; } else if (Status) { ApiError("IsabellePipeIN","I_RpcSend",Status); IsabelleError(); return; } else { BufferOffset = 0 ; } } while (count > 0) ; size = 0 ; Caller.RpcFlags = 0 ; Status = I_RpcReceive(&Caller, size) ; if (Status == RPC_S_OK) { if (Caller.BufferLength != 0) { OtherError("IsabellePipeIN","BufferLength != 0"); IsabelleError(); return; } Status = I_RpcFreeBuffer(&Caller); if (Status) { ApiError("IsabellePipeIN","I_RpcFreeBuffer",Status); IsabelleError(); return; } } } void LocalPipePull( PIPE_STATE PAPI *state, void PAPI *buffer, int max_buf, int PAPI *actual_transfer_count ) { unsigned num_elements = 0 ; DWORD size = (DWORD) max_buf; int bytescopied ; RPC_MESSAGE Caller ; *actual_transfer_count = 0 ; if (state->EndOfPipe) { return ; } I_RpcReadPipeElementsFromBuffer(state, (char PAPI *) buffer, max_buf, (int *) &num_elements) ; *actual_transfer_count += num_elements ; bytescopied = num_elements * sizeof(pipe_element_t) ; if (state->EndOfPipe == 0 && num_elements < (max_buf / sizeof(pipe_element_t))) { Caller.RpcFlags = RPC_BUFFER_PARTIAL ; Caller.Buffer = state->Buffer ; Caller.BufferLength = state->BufferLength ; Status = I_RpcReceive(&Caller, size) ; if (Status) { ApiError("PipePull", "I_RpcReceive", Status) ; return ; } num_elements = 0 ; state->Buffer = Caller.Buffer ; state->BufferLength = Caller.BufferLength ; state->CurPointer = (char PAPI *) Caller.Buffer ; state->BytesRemaining = Caller.BufferLength ; I_RpcReadPipeElementsFromBuffer( (PIPE_STATE PAPI *) state, (char PAPI *) buffer+bytescopied, max_buf - bytescopied, (int *) &num_elements) ; *actual_transfer_count += num_elements ; } } void IsabellePipeOUT ( RPC_BINDING_HANDLE Binding, pipe_t PAPI *pipe, int chunksize ) { RPC_MESSAGE Caller; int num_elements ; int count ; DWORD size = chunksize * sizeof(pipe_element_t) + sizeof(DWORD) *2; int max_buf ; PIPE_STATE localstate ; pipe_element_t PAPI *buf ; pipe_element_t pipe_element ; int rchunksize, rnumchunks, rbuffsize, rchecksum ; char PAPI *temp, PAPI *cur ; Caller.Handle = Binding; Caller.BufferLength = 0; Caller.ProcNum = 14 | HackForOldStubs | RPC_FLAGS_VALID_BIT; Caller.RpcInterfaceInformation = &IsabelleInterfaceInformation; Caller.RpcFlags = RPC_BUFFER_PARTIAL ; Status = I_RpcGetBuffer(&Caller) ; if (Status) { ApiError("IsabellePipeOUT","I_RpcSendReceive",Status); IsabelleError(); return; } Caller.RpcFlags = 0; Status = I_RpcSend(&Caller) ; if (Status) { ApiError("IsabellePipeOUT","I_RpcSendReceive",Status); IsabelleError(); return; } Caller.RpcFlags |= RPC_BUFFER_PARTIAL ; Status = I_RpcReceive(&Caller, size) ; if (Status) { ApiError("IsabellePipeOUT", "I_RpcReceive", Status) ; IsabelleError() ; return ; } localstate.Buffer = Caller.Buffer ; localstate.BufferLength = Caller.BufferLength ; localstate.CurrentState = start ; localstate.CurPointer = (char PAPI *) Caller.Buffer ; localstate.BytesRemaining = Caller.BufferLength ; localstate.EndOfPipe = 0 ; localstate.PipeElementSize = sizeof(pipe_element_t) ; localstate.PartialPipeElement = &pipe_element ; localchecksum = 0; do { pipe->Alloc(pipe->state, size, &buf, &max_buf ) ; LocalPipePull(&localstate, buf, max_buf, &num_elements) ; pipe->Push(pipe->state, buf, num_elements) ; } while (num_elements > 0); if (!(Caller.RpcFlags & RPC_BUFFER_COMPLETE)) { Caller.RpcFlags = 0 ; Status = I_RpcReceive(&Caller, size) ; if (Status) { ApiError("IsabellePipeOUT", "I_RpcReceive", Status) ; IsabelleError() ; return ; } } if (localstate.BytesRemaining > 0) { // this might be quite inefficient... need to improve // Also, CurPointer may be a pointer in Caller.Buffer // need to keep track of this in the state. temp = (char PAPI *) I_RpcAllocate(Caller.BufferLength + localstate.BytesRemaining) ; RpcpMemoryCopy(temp, localstate.CurPointer, localstate.BytesRemaining) ; RpcpMemoryCopy(temp+localstate.BytesRemaining, Caller.Buffer, Caller.BufferLength) ; cur = temp ; } else { temp = 0; cur = (char PAPI *) Caller.Buffer ; } rchunksize = *((int PAPI *) cur) ; cur += sizeof(int) ; rnumchunks = *((int PAPI *) cur) ; cur += sizeof(int) ; rchecksum = *((int PAPI *) cur) ; cur += sizeof(int) ; rbuffsize = *((int PAPI *) cur) ; cur += sizeof(int) ; PrintToConsole("IsabellePipeOUT: chunksize = %d\n", rchunksize) ; PrintToConsole("IsabellePipeOUT: numchunks = %d\n", rnumchunks) ; PrintToConsole("IsabellePipeOUT: buffsize = %d\n", rbuffsize) ; PrintToConsole("IsabellePipeOUT: checksum = %d\n", rchecksum) ; if (temp) { I_RpcFree(temp) ; } Status = I_RpcFreeBuffer(&Caller) ; if (Status) { ApiError("IsabellePipeOUT","I_RpcSendReceive",Status); IsabelleError() ; return; } if (rchecksum != localchecksum) { IsabelleError() ; } } void IsabellePipeINOUT ( RPC_BINDING_HANDLE Binding, pipe_t PAPI *pipe, int chunksize, int checksum ) { RPC_MESSAGE Caller, TempBuf; pipe_element_t PAPI *buf ; int num_buf_bytes ; int count ; int num_buf_elem ; DWORD size = chunksize * sizeof(pipe_element_t) + sizeof(DWORD) * 2; PIPE_STATE localstate ; int max_buf ; int num_elements ; pipe_element_t pipe_element ; int BufferOffset = 0 ; int LengthToSend ; Caller.Handle = Binding; Caller.BufferLength = 0; Caller.ProcNum = 15 | HackForOldStubs | RPC_FLAGS_VALID_BIT; Caller.RpcInterfaceInformation = &IsabelleInterfaceInformation; Caller.RpcFlags = RPC_BUFFER_PARTIAL ; Status = UclntGetBuffer(&Caller) ; if (Status) { ApiError("IsabellePipeINOUT","I_RpcSendReceive",Status); IsabelleError(); return; } // send the marshalled parameters Status = I_RpcSend(&Caller); if (Status == RPC_S_SEND_INCOMPLETE) { BufferOffset = Caller.BufferLength ; } else if (Status) { ApiError("IsabellePipeINOUT","I_RpcSendReceive",Status); IsabelleError(); return; } do { pipe->Alloc(pipe->state, size, &buf, &num_buf_bytes ) ; num_buf_elem = (num_buf_bytes -sizeof(DWORD)) / sizeof(pipe_element_t) ; pipe->Pull(pipe->state, (pipe_element_t PAPI *) ((char PAPI *) buf+sizeof(DWORD)), num_buf_elem, &count ) ; *((DWORD PAPI *) buf) = count ; LengthToSend = (count * sizeof(pipe_element_t)) + sizeof(DWORD) ; Status = I_RpcReallocPipeBuffer(&Caller, LengthToSend+BufferOffset) ; if (Status) { ApiError("IsabellePipeINOUT","I_RpcGetBuffer",Status); IsabelleError(); return; } if (count == 0) { Caller.RpcFlags = 0 ; } RpcpMemoryCopy((char PAPI *) Caller.Buffer+BufferOffset, buf, LengthToSend) ; Status = I_RpcSend(&Caller) ; if (Status == RPC_S_SEND_INCOMPLETE) { BufferOffset = Caller.BufferLength ; } else if (Status) { ApiError("IsabellePipeINOUT","I_RpcSend",Status); IsabelleError(); return; } else { BufferOffset = 0 ; } } while (count > 0) ; Caller.RpcFlags |= RPC_BUFFER_PARTIAL ; Status = I_RpcReceive(&Caller, size) ; if (Status) { ApiError("IsabellePipeINOUT", "I_RpcReceive", Status) ; IsabelleError() ; return ; } PrintToConsole("IsabellePipeINOUT: checksum (IN) = %d\n", checksum) ; localstate.Buffer = Caller.Buffer ; localstate.CurrentState = start ; localstate.CurPointer = (char PAPI *) Caller.Buffer ; localstate.BytesRemaining = Caller.BufferLength ; localstate.EndOfPipe = 0 ; localstate.PipeElementSize = sizeof(pipe_element_t) ; localstate.PartialPipeElement = &pipe_element ; localchecksum = 0; do { pipe->Alloc(pipe->state, size, &buf, &max_buf ) ; LocalPipePull(&localstate, buf, max_buf, &num_elements) ; pipe->Push(pipe->state, buf, num_elements ) ; } while (num_elements > 0); if (!(Caller.RpcFlags & RPC_BUFFER_COMPLETE)) { Status = I_RpcReceive(&Caller, size) ; if (Status) { ApiError("IsabellePipeINOUT", "I_RpcReceive", Status) ; IsabelleError() ; return ; } } Status = I_RpcFreeBuffer(&Caller) ; if (Status) { ApiError("IsabellePipeINOUT","I_RpcSendReceive",Status); IsabelleError(); return; } PrintToConsole("IsabellePipeINOUT: checksum (OUT) = %d\n", localchecksum) ; } BOOL IsServerNTSystem(RPC_BINDING_HANDLE Binding) { OSVERSIONINFO *pOsVer; BOOL fResult; RPC_MESSAGE Caller; Caller.Handle = Binding; Caller.BufferLength = 0; Caller.ProcNum = 20| HackForOldStubs ; Caller.RpcInterfaceInformation = &IsabelleInterfaceInformation; Caller.RpcFlags = 0; if (IdempotentTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_IDEMPOTENT; } if (MaybeTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_MAYBE; } if (BroadcastTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_BROADCAST; } Status = UclntGetBuffer(&Caller); if (Status) { ApiError("IsServerNTSystem", "I_RpcGetBuffer", Status); IsabelleError(); return TRUE; } Status = UclntSendReceive(&Caller); if (Status) { ApiError("IsServerNTSystem","I_RpcSendReceive",Status); IsabelleError(); return TRUE; } pOsVer = (OSVERSIONINFO *)Caller.Buffer; if (pOsVer->dwPlatformId == VER_PLATFORM_WIN32_NT) fResult = TRUE; else fResult = FALSE; Status = I_RpcFreeBuffer(&Caller); if (Status) { ApiError("IsServerNTSystem","I_RpcFreeBuffer",Status); IsabelleError(); } return fResult; } typedef struct _WIRE_CONTEXT { unsigned long ContextType; UUID ContextUuid; } WIRE_CONTEXT; typedef struct _CCONTEXT { RPC_BINDING_HANDLE hRPC; // binding handle assoicated with context unsigned long MagicValue; WIRE_CONTEXT NDR; } CCONTEXT, *PCCONTEXT; const ULONG CONTEXT_MAGIC_VALUE = 0xFEDCBA98; void UnregisterHelgaEx ( RPC_BINDING_HANDLE Binding ) { RPC_MESSAGE Caller; Caller.Handle = Binding; Caller.BufferLength = 0; Caller.ProcNum = 22| HackForOldStubs ; Caller.RpcInterfaceInformation = &IsabelleInterfaceInformation; Caller.RpcFlags = 0; if (IdempotentTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_IDEMPOTENT; } if (MaybeTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_MAYBE; } if (BroadcastTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_BROADCAST; } Status = UclntGetBuffer(&Caller); if (Status) { ApiError("UnregisterHelgaEx", "I_RpcGetBuffer", Status); IsabelleError(); return; } Status = UclntSendReceive(&Caller); if (Status) { ApiError("UnregisterHelgaEx","I_RpcSendReceive",Status); IsabelleError(); return; } Status = I_RpcFreeBuffer(&Caller); if (Status) { ApiError("UnregisterHelgaEx","I_RpcFreeBuffer",Status); IsabelleError(); } } void OpenContextHandle( IN RPC_BINDING_HANDLE Binding, IN RPC_CLIENT_INTERFACE *If, OUT CCONTEXT *ContextHandle ) { RPC_MESSAGE Caller; Caller.Handle = Binding; Caller.BufferLength = sizeof(WIRE_CONTEXT); if (If == &IsabelleInterfaceInformation) Caller.ProcNum = 21| HackForOldStubs ; else if (If == &HelgaInterfaceInformation) Caller.ProcNum = 10| HackForOldStubs ; else { ASSERT(0); } Caller.RpcInterfaceInformation = If; Caller.RpcFlags = 0; if (IdempotentTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_IDEMPOTENT; } if (MaybeTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_MAYBE; } if (BroadcastTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_BROADCAST; } Status = UclntGetBuffer(&Caller); if (Status) { ApiError("OpenContextHandle", "I_RpcGetBuffer", Status); IsabelleError(); return; } memset(Caller.Buffer, 0, sizeof(WIRE_CONTEXT)); Status = UclntSendReceive(&Caller); if (Status) { ApiError("OpenContextHandle","I_RpcSendReceive",Status); IsabelleError(); return; } if (ContextHandle) { Status = RpcBindingCopy(Binding, &ContextHandle->hRPC); if (Status) { ApiError("OpenContextHandle","RpcBindingCopy", Status); IsabelleError(); } ContextHandle->MagicValue = CONTEXT_MAGIC_VALUE; memcpy(&ContextHandle->NDR, Caller.Buffer, sizeof(WIRE_CONTEXT)); } Status = I_RpcFreeBuffer(&Caller); if (Status) { ApiError("OpenContextHandle","I_RpcFreeBuffer",Status); IsabelleError(); } } /* ----------------------------------------------------------------- Synchronize Routine --------------------------------------------------------------------*/ void Synchro( unsigned int Address // Specifies the binding to use in making the call ) { RPC_BINDING_HANDLE Binding ; int fPrint = 0; RPC_MESSAGE Caller; if (AutoListenFlag) { Caller.BufferLength = 0; Caller.ProcNum = 4 | HackForOldStubs ; Caller.RpcInterfaceInformation = &HelgaInterfaceInformation ; Caller.RpcFlags = 0; } Status = GetBinding(Address, &Binding); if (Status) { ApiError("Synchro","GetBinding",Status); PrintToConsole("Synchro : FAIL - Unable to Bind\n"); return; } #ifdef __RPC_WIN32__ if (AutoListenFlag) { Caller.Handle = Binding; while(1) { while(UclntGetBuffer(&Caller)) { Caller.Handle = Binding; PrintToConsole("."); fPrint = 1; PauseExecution(100); } if( UclntSendReceive(&Caller) == 0) { PrintToConsole("\n"); break ; } PauseExecution(100) ; PrintToConsole("."); fPrint = 1; Caller.Handle = Binding ; } // SendReceive okay, free buffer now. Status = I_RpcFreeBuffer(&Caller); if (Status) ApiError("Synchro","I_RpcFreeBuffer",Status); } else { while(RpcMgmtIsServerListening(Binding) != RPC_S_OK) { PrintToConsole("."); fPrint = 1; PauseExecution(100) ; } } #else Caller.Handle = Binding; while(1) { while(UclntGetBuffer(&Caller)) { Caller.Handle = Binding; PrintToConsole("."); fPrint = 1; PauseExecution(100); } if( UclntSendReceive(&Caller) == 0) { PrintToConsole("\n"); break ; } PauseExecution(100) ; PrintToConsole("."); fPrint = 1; } // SendReceive okay, free buffer now. Status = I_RpcFreeBuffer(&Caller); if (Status) ApiError("Synchro","I_RpcFreeBuffer",Status); #endif Status = RpcBindingFree(&Binding); if (Status) { ApiError("Synchro","RpcBindingFree",Status); PrintToConsole("Synchro : FAIL - Unable to Free Binding"); return; } if (fPrint) { PrintToConsole("\n"); } } /* -------------------------------------------------------------------- Helga Interface -------------------------------------------------------------------- */ void InitializeBuffer ( IN OUT void PAPI * Buffer, IN unsigned int BufferLength ) /*++ Routine Description: This routine is used to initialize the buffer; the first long in the buffer is set to be the length of the buffer. The rest of the buffer is initialized with a pattern which will be checked by the receiver. Arguments: Buffer - Supplies the buffer to be initialized. BufferLength - Supplies the length of the buffer. --*/ { unsigned long PAPI * Length; unsigned char PAPI * BufferScan; static unsigned char InitialValue = 96; unsigned char Value; Length = (unsigned long PAPI *) Buffer; *Length = BufferLength; swaplong(*Length) ; Value = InitialValue; InitialValue += 1; for (BufferScan = (unsigned char PAPI *) (Length + 1), BufferLength -= 4; BufferLength > 0; BufferLength--, BufferScan++, Value++) *BufferScan = Value; } int CheckBuffer ( IN void PAPI * Buffer, IN unsigned long BufferLength ) /*++ Routine Description: We need to check that the correct bytes were sent. We do not check the length of the buffer. Arguments: Buffer - Supplies the buffer to be checked. BufferLength - Supplies the length of the buffer to be checked. Return Value: A value of zero will be returned if the buffer contains the correct bytes; otherwise, non-zero will be returned. --*/ { unsigned long PAPI * Length; unsigned char PAPI * BufferScan; unsigned char Value = 0; Length = (unsigned long PAPI *) Buffer; swaplong(*Length) ; for (BufferScan = (unsigned char PAPI *) (Length + 1), Value = *BufferScan, BufferLength -= 4; BufferLength > 0; BufferLength--, BufferScan++, Value++) if (*BufferScan != Value) return(1); return(0); } RPC_PROTSEQ_ENDPOINT HelgaRpcProtseqEndpoint[] = { {(unsigned char *) "ncacn_np", #ifdef WIN32RPC (unsigned char *) "\\pipe\\zippyhe"}, #else // WIN32RPC (unsigned char *) "\\device\\namedpipe\\christopherhelga"}, #endif // WIN32RPC {(unsigned char *) "ncacn_ip_tcp", (unsigned char *) "2039"} ,{(unsigned char *) "ncadg_ip_udp", (unsigned char *) "2039"} ,{(unsigned char *) "ncalrpc",(unsigned char *) "christopherhelga"} ,{(unsigned char *) "ncacn_nb_nb",(unsigned char *) "211"} ,{(unsigned char *) "ncacn_spx", (unsigned char *) "5014"} ,{(unsigned char *) "ncadg_ipx", (unsigned char *) "5014"} ,{(unsigned char *) "ncacn_vns_spp", (unsigned char *) "264"} ,{(unsigned char *) "ncacn_at_dsp", (unsigned char *) "\\pipe\\zippyhe"} ,{(unsigned char *) "ncadg_mq", (unsigned char *) "christopherhelga"} }; RPC_CLIENT_INTERFACE HelgaInterfaceInformation = { sizeof(RPC_CLIENT_INTERFACE), {{1,2,2,{3,3,3,3,3,3,3,3}}, {1,1}}, {{0x8A885D04, 0x1CEB, 0x11C9, {0x9F, 0xE8, 0x08, 0x00, 0x2B, 0x10, 0x48, 0x60}}, {2, 0}}, 0, sizeof(HelgaRpcProtseqEndpoint) / sizeof(RPC_PROTSEQ_ENDPOINT), HelgaRpcProtseqEndpoint, 0, NULL, RPC_INTERFACE_HAS_PIPES }; // Send a 0 length packet and expect a 0 length one in reply void Helga ( RPC_BINDING_HANDLE Binding // Specifies the binding to use in making the // remote procedure call. ) { RPC_MESSAGE Caller; Caller.Handle = Binding; Caller.BufferLength = 0; Caller.ProcNum = 0 | HackForOldStubs ; Caller.RpcInterfaceInformation = &HelgaInterfaceInformation; Caller.RpcFlags = 0; if (IdempotentTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_IDEMPOTENT; } if (MaybeTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_MAYBE; } if (BroadcastTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_BROADCAST; } Status = UclntGetBuffer(&Caller); if (Status) { ApiError("Helga","I_RpcGetBuffer",Status); HelgaError(); return; } Status = UclntSendReceive(&Caller); if (Status) { ApiError("Helga","I_RpcSendReceive",Status); HelgaError(); return; } else { if (Caller.BufferLength != 0) { OtherError("Helga","BufferLength != 0"); HelgaError(); return; } Status = I_RpcFreeBuffer(&Caller); if (Status) { ApiError("Helga","I_RpcFreeBuffer",Status); HelgaError(); return; } } } // Send a 0 length packet and expect a 0 length one in reply DWORD HelgaSendReceiveFailure ( RPC_BINDING_HANDLE Binding, // Specifies the binding to use in making the // remote procedure call. int ProcNum ) { RPC_MESSAGE Caller; Caller.Handle = Binding; Caller.BufferLength = 0; Caller.ProcNum = ProcNum | HackForOldStubs ; Caller.RpcInterfaceInformation = &HelgaInterfaceInformation; Caller.RpcFlags = 0; if (IdempotentTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_IDEMPOTENT; } if (MaybeTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_MAYBE; } if (BroadcastTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_BROADCAST; } Status = UclntGetBuffer(&Caller); if (Status) { ApiError("Helga","I_RpcGetBuffer",Status); HelgaError(); return -1; } Status = UclntSendReceive(&Caller); if (!Status) { ApiError("HelgaSendReceiveFailure","I_RpcSendReceive",Status); HelgaError(); I_RpcFreeBuffer(&Caller); return -1; } return Status; } void HelgaSyncLpcSecurity ( RPC_BINDING_HANDLE Binding ) { RPC_MESSAGE Caller; Caller.Handle = Binding; Caller.BufferLength = 0; Caller.ProcNum = 6 | HackForOldStubs ; Caller.RpcInterfaceInformation = &HelgaInterfaceInformation; Caller.RpcFlags = 0; if (IdempotentTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_IDEMPOTENT; } if (MaybeTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_MAYBE; } if (BroadcastTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_BROADCAST; } Status = UclntGetBuffer(&Caller); if (Status) { ApiError("HelgaLpcSecurity","I_RpcGetBuffer",Status); HelgaError(); return; } Status = UclntSendReceive(&Caller); if (Status) { ApiError("HelgaLpcSecurity","I_RpcSendReceive",Status); HelgaError(); return; } if (Caller.BufferLength != 0) { OtherError("HelgaLpcSecurity","BufferLength != 0"); HelgaError(); return; } Status = I_RpcFreeBuffer(&Caller); if (Status) { ApiError("HelgaLpcSecurity","I_RpcFreeBuffer",Status); HelgaError(); return; } } void HelgaAsyncLpcSecurity ( RPC_BINDING_HANDLE Binding ) { RPC_MESSAGE Caller; RPC_ASYNC_STATE Async; Caller.Handle = Binding; Caller.BufferLength = 0; Caller.ProcNum = 6 | HackForOldStubs | RPC_FLAGS_VALID_BIT; Caller.RpcInterfaceInformation = &HelgaInterfaceInformation; Caller.RpcFlags = RPC_BUFFER_ASYNC; if (IdempotentTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_IDEMPOTENT; } if (MaybeTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_MAYBE; } if (BroadcastTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_BROADCAST; } Status = UclntGetBuffer(&Caller); if (Status) { ApiError("HelgaLpcSecurity","I_RpcGetBuffer",Status); HelgaError(); return; } Async.u.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL) ; if (Async.u.hEvent == 0) { HelgaError(); return; } Async.NotificationType = RpcNotificationTypeEvent ; Status = I_RpcAsyncSetHandle(&Caller, (PRPC_ASYNC_STATE) &Async); if (Status) { HelgaError(); return; } Caller.RpcFlags = RPC_BUFFER_ASYNC; Status = I_RpcSend(&Caller); if (Status) { ApiError("HelgaLpcSecurity","I_RpcSend",Status); HelgaError(); return; } if (Caller.BufferLength != 0) { OtherError("HelgaLpcSecurity","BufferLength != 0"); HelgaError(); return; } WaitForSingleObject(Async.u.hEvent, INFINITE); Caller.RpcFlags = RPC_BUFFER_ASYNC; Status = I_RpcReceive(&Caller, 0); if (Status) { HelgaError(); return; } Status = I_RpcFreeBuffer(&Caller); if (Status) { ApiError("HelgaLpcSecurity","I_RpcFreeBuffer",Status); HelgaError(); return; } } void HelgaLpcSecurity ( RPC_BINDING_HANDLE Binding, BOOL fAsync ) { if (fAsync) { HelgaAsyncLpcSecurity(Binding); } else { HelgaSyncLpcSecurity(Binding); } } void HelgaMustFail ( RPC_BINDING_HANDLE Binding // Specifies the binding to use in making the // remote procedure call. ) { RPC_MESSAGE Caller; Caller.Handle = Binding; Caller.BufferLength = 0; Caller.ProcNum = 0 | HackForOldStubs ; Caller.RpcInterfaceInformation = &HelgaInterfaceInformation; Caller.RpcFlags = 0; if (IdempotentTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_IDEMPOTENT; } if (MaybeTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_MAYBE; } if (BroadcastTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_BROADCAST; } Status = UclntGetBuffer(&Caller); if (Status) { PrintToConsole("HelgaMustFail: I_RpcGetBuffer: %d\n", Status) ; return; } Status = UclntSendReceive(&Caller); if (Status) { PrintToConsole("HelgaMustFail: I_RpcSendReceive: %d\n", Status) ; return; } PrintToConsole("HelgaMustFail: This call is supposed to fail\n") ; HelgaError(); } void HelgaUsingContextHandle ( void PAPI * ContextHandle ) { RPC_MESSAGE Caller; Caller.Handle = NDRCContextBinding(ContextHandle); Caller.BufferLength = 0; Caller.ProcNum = 0| HackForOldStubs ; Caller.RpcInterfaceInformation = &HelgaInterfaceInformation; Caller.RpcFlags = 0; if (IdempotentTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_IDEMPOTENT; } if (MaybeTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_MAYBE; } if (BroadcastTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_BROADCAST; } Status = UclntGetBuffer(&Caller); if (Status) { ApiError("Helga","I_RpcGetBuffer",Status); HelgaError(); return; } Status = UclntSendReceive(&Caller); if (Status) { ApiError("Helga","I_RpcSendReceive",Status); HelgaError(); return; } else { if (Caller.BufferLength != 0) { OtherError("Helga","BufferLength != 0"); HelgaError(); return; } Status = I_RpcFreeBuffer(&Caller); if (Status) { ApiError("Helga","I_RpcFreeBuffer",Status); HelgaError(); return; } } } // Send a packet of a requested size, the expected reply is 0 length // The first long of the packet is the expected size on the server size void HelgaIN ( RPC_BINDING_HANDLE Binding, // Specifies the binding to use in making the // remote procedure call. unsigned long BufferLength // Specifies the length of the buffer. ) { RPC_MESSAGE Caller; Caller.Handle = Binding; Caller.BufferLength = BufferLength; Caller.ProcNum = 1 | HackForOldStubs ; Caller.RpcInterfaceInformation = &HelgaInterfaceInformation; Caller.RpcFlags = 0; if (IdempotentTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_IDEMPOTENT; } if (MaybeTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_MAYBE; } if (BroadcastTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_BROADCAST; } Status = UclntGetBuffer(&Caller); if (Status) { ApiError("HelgaIN","I_RpcGetBuffer",Status); HelgaError(); return; } InitializeBuffer(Caller.Buffer, BufferLength); Status = UclntSendReceive(&Caller); if (Status) { ApiError("HelgaIN","I_RpcSendReceive",Status); HelgaError(); return; } else { if (Caller.BufferLength != 0) { OtherError("HelgaIN","BufferLength != 0"); HelgaError(); return; } Status = I_RpcFreeBuffer(&Caller); if (Status) { ApiError("HelgaIN","I_RpcFreeBuffer",Status); HelgaError(); return; } } } // Send a packet which contains a single long, which is the size // of the packet the server will send in reply void HelgaOUT ( RPC_BINDING_HANDLE Binding, // Specifies the binding to use in making the // remote procedure call. unsigned long BufferLength // Specifies the length of the buffer. ) { RPC_MESSAGE Caller; unsigned long PAPI * Length; Caller.Handle = Binding; Caller.BufferLength = sizeof(unsigned long); Caller.ProcNum = 2 | HackForOldStubs ; Caller.RpcInterfaceInformation = &HelgaInterfaceInformation; Caller.RpcFlags = 0; if (IdempotentTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_IDEMPOTENT; } if (MaybeTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_MAYBE; } if (BroadcastTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_BROADCAST; } Status = UclntGetBuffer(&Caller); if (Status) { ApiError("HelgaOUT","I_RpcGetBuffer",Status); HelgaError(); return; } Length = (unsigned long PAPI *) Caller.Buffer; *Length = BufferLength; swaplong(*Length) ; Status = UclntSendReceive(&Caller); if (Status) { ApiError("HelgaOUT","I_RpcSendReceive",Status); HelgaError(); return; } else { Length = (unsigned long PAPI *) Caller.Buffer; swaplong(*Length) ; if (Caller.BufferLength != *Length) { OtherError("HelgaOUT","BufferLength != *Length"); HelgaError(); return; } if (CheckBuffer(Caller.Buffer, Caller.BufferLength) != 0) { OtherError("HelgaOUT","CheckBuffer Failed"); HelgaError(); return; } Status = I_RpcFreeBuffer(&Caller); if (Status) { ApiError("HelgaOUT","I_RpcFreeBuffer",Status); HelgaError(); return; } } } // Send a packet, which the first long is the size of the packet, whoes // reply should be a packet of the same size void HelgaINOUT ( RPC_BINDING_HANDLE Binding, // Specifies the binding to use in making the // remote procedure call. unsigned long BufferLength // Specifies the length of the buffer. ) { RPC_MESSAGE Caller; unsigned long PAPI * Length; Caller.Handle = Binding; Caller.BufferLength = BufferLength; Caller.ProcNum = 3 | HackForOldStubs ; Caller.RpcInterfaceInformation = &HelgaInterfaceInformation; Caller.RpcFlags = 0; if (IdempotentTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_IDEMPOTENT; } if (MaybeTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_MAYBE; } if (BroadcastTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_BROADCAST; } Status = UclntGetBuffer(&Caller); if (Status) { ApiError("HelgaINOUT","I_RpcGetBuffer",Status); HelgaError(); return; } InitializeBuffer(Caller.Buffer, BufferLength); Status = UclntSendReceive(&Caller); if (Status) { ApiError("HelgaINOUT","I_RpcSendReceive",Status); HelgaError(); return; } else { Length = (unsigned long PAPI *) Caller.Buffer; swaplong(*Length) ; if (Caller.BufferLength != *Length) { OtherError("HelgaINOUT","BufferLength != *Length"); HelgaError(); return; } if (CheckBuffer(Caller.Buffer, Caller.BufferLength) != 0) { OtherError("HelgaINOUT","CheckBuffer Failed"); HelgaError(); return; } Status = I_RpcFreeBuffer(&Caller); if (Status) { ApiError("HelgaINOUT","I_RpcFreeBuffer",Status); HelgaError(); return; } } } unsigned long HelgaSizes[] = { 128, 256, 512, 1024, 1024*2, 1024*4, 1024*8, 10000, 15000, 20000, 60000, 30000, 40000, 100000, 1024*82, 0 }; #if 0 unsigned long HelgaSizes[] = { 128, 128, 0 }; #endif void TestHelgaInterface ( RPC_BINDING_HANDLE HelgaBinding, unsigned long SizeUpperBound ) /*++ Routine Description: The various tests uses this routine to test the Helga interface in different scenarios. We run each of the routines for a variety of input and output buffer sizes. This is controlled by the array, HelgaSizes. Arguments: HelgaBinding - Supplies the binding handle to use when calling each of the Helga caller stubs. --*/ { int Count; Helga(HelgaBinding); for (Count = 0; HelgaSizes[Count] != 0; Count++) { if (HelgaSizes[Count] <= SizeUpperBound) { HelgaIN(HelgaBinding,HelgaSizes[Count]); } } for (Count = 0; HelgaSizes[Count] != 0; Count++) { if (HelgaSizes[Count] <= SizeUpperBound) { HelgaOUT(HelgaBinding,HelgaSizes[Count]); } } for (Count = 0; HelgaSizes[Count] != 0; Count++) { if (HelgaSizes[Count] <= SizeUpperBound) { HelgaINOUT(HelgaBinding,HelgaSizes[Count]); } } } RPC_CLIENT_INTERFACE HelgaInterfaceWrongTransferSyntax = { sizeof(RPC_CLIENT_INTERFACE), {{1,2,2,{3,3,3,3,3,3,3,3}}, {1,1}}, {{0xb4537da9, 0x3d03, 0x4f6b, {0xb5, 0x94, 0x52, 0xb2, 0x87, 0x4e, 0xe9, 0xd0}}, {1, 0}}, 0, 0, 0, 0, 0, RPC_INTERFACE_HAS_PIPES }; RPC_CLIENT_INTERFACE HelgaInterfaceWrongGuid = { sizeof(RPC_CLIENT_INTERFACE), {{1,2,4,{3,3,3,3,3,3,3,3}}, {1,1}}, {{0x8A885D04, 0x1CEB, 0x11C9, {0x9F, 0xE8, 0x08, 0x00, 0x2B, 0x10, 0x48, 0x60}}, {2,0}}, 0, 0, 0, 0, 0, RPC_INTERFACE_HAS_PIPES }; int HelgaWrongInterfaceGuid ( RPC_BINDING_HANDLE Binding ) /*++ Routine Description: This routine makes a remote procedure call using the wrong interface GUID (not supported by the server). The call must fail, otherwise, there is a bug in the runtime. (Otherwise there are no bugs in the runtime -- I wish.) Arguments: Binding - Supplies the binding handle to use in trying to make the remote procedure call. Return Value: Zero will be returned in the call fails as expected. Otherwise, non-zero will be returned. --*/ { RPC_MESSAGE Caller; Caller.Handle = Binding; Caller.BufferLength = 0; Caller.ProcNum = 0 | HackForOldStubs ; Caller.RpcInterfaceInformation = &HelgaInterfaceWrongGuid; Caller.RpcFlags = 0; if (IdempotentTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_IDEMPOTENT; } if (MaybeTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_MAYBE; } if (BroadcastTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_BROADCAST; } Status = UclntGetBuffer(&Caller); if (Status == RPC_S_UNKNOWN_IF) return(0); Status = UclntSendReceive(&Caller); if (Status == RPC_S_UNKNOWN_IF) return(0); return(1); } int HelgaWrongTransferSyntax ( RPC_BINDING_HANDLE Binding ) /*++ Routine Description: This routine makes a remote procedure call using the wrong transfer syntax (not supported by the server). The call must fail, otherwise, there is a bug in the runtime. (Otherwise there are no bugs in the runtime -- I wish.) Arguments: Binding - Supplies the binding handle to use in trying to make the remote procedure call. Return Value: Zero will be returned in the call fails as expected. Otherwise, non-zero will be returned. --*/ { RPC_MESSAGE Caller; Caller.Handle = Binding; Caller.BufferLength = 0; Caller.ProcNum = 0 | HackForOldStubs ; Caller.RpcInterfaceInformation = &HelgaInterfaceWrongTransferSyntax; Caller.RpcFlags = 0; if (IdempotentTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_IDEMPOTENT; } if (MaybeTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_MAYBE; } if (BroadcastTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_BROADCAST; } Status = UclntGetBuffer(&Caller); if (Status == RPC_S_UNSUPPORTED_TRANS_SYN) return(0); Status = UclntSendReceive(&Caller); if (Status == RPC_S_UNSUPPORTED_TRANS_SYN) return(0); return(1); } /* -------------------------------------------------------------------- Sylvia Interface -------------------------------------------------------------------- */ extern RPC_DISPATCH_TABLE SylviaDispatchTable; RPC_CLIENT_INTERFACE SylviaInterfaceInformation = { sizeof(RPC_CLIENT_INTERFACE), {{3,2,2,{1,1,1,1,1,1,1,1}}, {1,1}}, {{0x8A885D04, 0x1CEB, 0x11C9, {0x9F, 0xE8, 0x08, 0x00, 0x2B, 0x10, 0x48, 0x60}}, {2, 0}}, &SylviaDispatchTable, 0, 0, 0, 0, RPC_INTERFACE_HAS_PIPES }; unsigned int LocalSylviaCall ( unsigned /*long*/ char Depth, unsigned /*long*/ char Breadth, unsigned /*long*/ char Count ) { if (Depth > 0) { if (Depth == Breadth) { Count = (unsigned char) LocalSylviaCall(Depth-1,Breadth,Count); } else Count = (unsigned char) LocalSylviaCall(Depth-1,Breadth,Count); } return(Count+1); } unsigned /*long*/ char // Specifies the new count of calls. SylviaCall ( RPC_BINDING_HANDLE Binding, unsigned /*long*/ char Depth, // Specifies the depth of recursion desired. unsigned /*long*/ char Breadth, // Specifies the breadth desired. unsigned /*long*/ char Count // Specifies the count of calls up to this point. ) { RPC_MESSAGE Caller; unsigned /*long*/ char PAPI * plScan, ReturnValue ; if ( NoCallBacksFlag != 0 ) { return((unsigned char) LocalSylviaCall(Depth, Breadth, Count)); } Caller.Handle = Binding; Caller.BufferLength = sizeof(unsigned /*long*/ char) *4+10240; Caller.ProcNum = 0 | HackForOldStubs ; Caller.RpcInterfaceInformation = &SylviaInterfaceInformation; Caller.RpcFlags = 0; if (IdempotentTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_IDEMPOTENT; } if (MaybeTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_MAYBE; } if (BroadcastTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_BROADCAST; } Status = UclntGetBuffer(&Caller); if (Status) { ApiError("SylviaCall","I_RpcGetBuffer",Status); SylviaError(); return(0); } plScan = (unsigned /*long*/ char PAPI *) Caller.Buffer; plScan[0] = (unsigned char) Depth; plScan[1] = (unsigned char) Breadth; plScan[2] = (unsigned char) Count; Status = UclntSendReceive(&Caller); if (Status) { ApiError("SylviaCall","I_RpcSendReceive",Status); SylviaError(); return(0); } plScan = (unsigned /*long*/ char PAPI *) Caller.Buffer; ReturnValue = *plScan; Status = I_RpcFreeBuffer(&Caller); if (Status) { ApiError("SylviaCall","I_RpcFreeBuffer",Status); SylviaError(); return(0); } return(ReturnValue); } RPC_BINDING_HANDLE SylviaBinding; unsigned int SylviaCallbackUserCode ( unsigned /*long*/ char Depth, unsigned /*long*/ char Breadth, unsigned /*long*/ char Count ); // Prototype to keep the compiler happy because we recursively call // this routine. unsigned int SylviaCallbackUserCode ( // The user code for SylviaCallback. unsigned /*long*/ char Depth, unsigned /*long*/ char Breadth, unsigned /*long*/ char Count ) { if (Depth > 0) { if (Depth == Breadth) { Count = (unsigned char) SylviaCallbackUserCode(Depth-1,Breadth,Count); } else Count = SylviaCall(SylviaBinding,Depth-1,Breadth,Count); } return(Count+1); } void __RPC_STUB SylviaCallback ( PRPC_MESSAGE Callee ) { unsigned /*long*/ char ReturnValue, PAPI *plScan; if ( Callee->ProcNum != 0 ) { OtherError("SylviaCallback", "Callee->ProcNum != 0"); SylviaError(); } if ( RpcpMemoryCompare(Callee->RpcInterfaceInformation, &SylviaInterfaceInformation, sizeof(SylviaInterfaceInformation)) != 0 ) { OtherError("SylviaCallback", "Callee->RpcInteraceInformation != &SylviaInterfaceInformation"); SylviaError(); } if (Callee->BufferLength != sizeof(unsigned /*long*/ char)*4+10240) { OtherError("SylviaCallback", "Callee->BufferLength != sizeof(unsigned int)*4"); SylviaError(); } plScan = (unsigned /*long*/ char PAPI *) Callee->Buffer; ReturnValue = (unsigned char) SylviaCallbackUserCode(plScan[0],plScan[1],plScan[2]); Callee->BufferLength = sizeof(unsigned char /*long*/); Status = I_RpcGetBuffer(Callee); if (Status) { ApiError("SylviaCallback","I_RpcGetBuffer",Status); SylviaError(); } plScan = (unsigned /*long*/ char PAPI *) Callee->Buffer; *plScan = ReturnValue; } RPC_DISPATCH_FUNCTION SylviaDispatchFunction[] = {SylviaCallback}; RPC_DISPATCH_TABLE SylviaDispatchTable = { 1, SylviaDispatchFunction }; void GenerateUuidValue ( IN unsigned short MagicNumber, OUT UUID PAPI * Uuid ) /*++ Routine Description: This routine is used to generate a value for a uuid. The magic number argument is used in mysterious and wonderful ways to generate a uuid (which is not necessarily correct). Arguments: MagicNumber - Supplies a magic number which will be used to generate a uuid. Uuid - Returns the generated uuid. --*/ { Uuid->Data1= (unsigned long) MagicNumber * (unsigned long) MagicNumber ; //swaplong(Uuid->Data1) ; Uuid->Data2 = MagicNumber; Uuid->Data3 = MagicNumber / 2; //swapshort(Uuid->Data2) ; //swapshort(Uuid->Data3) ; Uuid->Data4[0] = MagicNumber % 256; Uuid->Data4[1] = MagicNumber % 257; Uuid->Data4[2] = MagicNumber % 258; Uuid->Data4[3] = MagicNumber % 259; Uuid->Data4[4] = MagicNumber % 260; Uuid->Data4[5] = MagicNumber % 261; Uuid->Data4[6] = MagicNumber % 262; Uuid->Data4[7] = MagicNumber % 263; } int CheckUuidValue ( IN unsigned short MagicNumber, OUT UUID PAPI * Uuid ) /*++ Routine Description: This routine is used to check that a generated uuid value is correct. Arguments: MagicNumber - Supplies a magic number which will be used to check a generated uuid. Uuid - Supplies a generated uuid to check. Return Value: Zero will be returned if the uuid value is correct; otherwise, non-zero will be returned. --*/ { // swaplong(Uuid->Data1) ; if ( Uuid->Data1 != ((unsigned long) MagicNumber) * ((unsigned long) MagicNumber)) return(1); // swapshort(Uuid->Data2) ; if ( Uuid->Data2 != MagicNumber ) return(1); // swapshort(Uuid->Data3) ; if ( Uuid->Data3 != MagicNumber / 2 ) return(1); if ( Uuid->Data4[0] != MagicNumber % 256 ) return(1); if ( Uuid->Data4[1] != MagicNumber % 257 ) return(1); if ( Uuid->Data4[2] != MagicNumber % 258 ) return(1); if ( Uuid->Data4[3] != MagicNumber % 259 ) return(1); if ( Uuid->Data4[4] != MagicNumber % 260 ) return(1); if ( Uuid->Data4[5] != MagicNumber % 261 ) return(1); if ( Uuid->Data4[6] != MagicNumber % 262 ) return(1); if ( Uuid->Data4[7] != MagicNumber % 263 ) return(1); return(0); } static unsigned int TryFinallyCount; static unsigned int TryFinallyFailed; void TheodoreTryFinally ( unsigned int count, unsigned int raise ) { if (count == 0) { if (raise) RpcRaiseException(437); return; } RpcTryFinally { TryFinallyCount += 1; TheodoreTryFinally(count-1,raise); } RpcFinally { TryFinallyCount -= 1; if ( (RpcAbnormalTermination() && !raise) || (!RpcAbnormalTermination() && raise)) TryFinallyFailed += 1; } RpcEndFinally } void Theodore ( // This test checks the exception handling support provided // by the RPC runtime. No remote procedure calls occur. ) { unsigned int TryFinallyPass = 0; if ( NumberOfTestsRun++ ) { PauseExecution(TestDelay); } PrintToConsole("Theodore : Verify exception handling support\n"); TryFinallyCount = 0; TryFinallyFailed = 0; RpcTryExcept { RpcTryExcept { TheodoreTryFinally(20,1); } RpcExcept(I_RpcExceptionFilter(RpcExceptionCode())) { if ( (RpcExceptionCode() == 437) && (TryFinallyCount == 0)) TryFinallyPass = 1; } RpcEndExcept } RpcExcept(I_RpcExceptionFilter(RpcExceptionCode())) { PrintToConsole("Theodore : FAIL in RpcTryExcept (%u)\n",TryFinallyCount); return; } RpcEndExcept if (!TryFinallyPass) { PrintToConsole("Theodore : FAIL in RpcTryFinally\n"); return; } if (TryFinallyFailed) { PrintToConsole("Theodore : FAIL in RpcTryFinally\n"); return; } TryFinallyCount = 0; TryFinallyFailed = 0; RpcTryExcept { TheodoreTryFinally(20,0); } RpcExcept(I_RpcExceptionFilter(RpcExceptionCode())) { PrintToConsole("Theodore : FAIL in RpcTryExcept\n"); return; } RpcEndExcept if (TryFinallyFailed) { PrintToConsole("Theodore : FAIL in RpcTryFinally\n"); return; } PrintToConsole("Theodore : PASS\n"); } void Sebastian ( ) /*++ Routine Description: We perform a build verification test in the routine. This test checks for basic functionality of the runtime. It works with Sigfried in usvr.exe. This particular test is dedicated to a cat. --*/ { RPC_BINDING_HANDLE HelgaBinding; RPC_BINDING_HANDLE IsabelleBinding; int HelgaCount; Synchro(SIGFRIED) ; if ( NumberOfTestsRun++ ) { PauseExecution(TestDelay); } PrintToConsole("Sebastian : Verify Basic Client Functionality\n"); Status = GetBinding(SIGFRIED, &HelgaBinding); if (Status) { ApiError("Sebastian","GetBinding",Status); PrintToConsole("Sebastian : FAIL - Unable to Bind (Sigfried)\n"); return; } Status = GetBinding(SIGFRIED, &IsabelleBinding); if (Status) { ApiError("Sebastian","GetBinding",Status); PrintToConsole("Sebastian : FAIL - Unable to Bind (Sigfried)\n"); return; } for (HelgaCount = 0; HelgaCount < 100; HelgaCount++) { Status = RpcBindingFree(&HelgaBinding); if (Status) { ApiError("Sebastian","RpcBindingFree",Status); PrintToConsole("Sebastian : FAIL - Unable to Free Binding"); PrintToConsole(" (HelgaBinding)\n"); return; } Status = GetBinding(SIGFRIED, &HelgaBinding); if (Status) { ApiError("Sebastian","GetBinding",Status); PrintToConsole("Sebastian : FAIL - Unable to Bind (Sigfried)\n"); return; } Helga(HelgaBinding); } TestHelgaInterface(HelgaBinding, HelgaMaxSize); IsabelleShutdown(IsabelleBinding); if (HelgaErrors != 0) { PrintToConsole("Sebastian : FAIL - Error(s) in Helga Interface\n"); HelgaErrors = 0; return; } Status = RpcBindingFree(&HelgaBinding); if (Status) { ApiError("Sebastian","RpcBindingFree",Status); PrintToConsole("Sebastian : FAIL - Unable to Free Binding"); PrintToConsole(" (HelgaBinding)\n"); return; } if (IsabelleErrors != 0) { PrintToConsole("Sebastian : FAIL - Error(s) in Isabelle Interface\n"); IsabelleErrors = 0; return; } Status = RpcBindingFree(&IsabelleBinding); if (Status) { ApiError("Sebastian","RpcBindingFree",Status); PrintToConsole("Sebastian : FAIL - Unable to Free Binding"); PrintToConsole(" (IsabelleBinding)\n"); return; } PrintToConsole("Sebastian : PASS\n"); } void Pipe ( ) /*++ Routine Description: We perform a build verification test in the routine. This test checks for basic functionality of the runtime. It works with Sigfried in usvr.exe. This particular test is dedicated to a cat. --*/ { RPC_BINDING_HANDLE IsabelleBinding; pipe_t pipe ; int state ; int local_buf[BUFF_SIZE] ; int i ; long checksum ; Synchro(SPIPE) ; if ( NumberOfTestsRun++ ) { PauseExecution(TestDelay); } PrintToConsole("PIPE : Verify Basic Client Functionality\n"); Status = GetBinding(SPIPE, &IsabelleBinding); if (Status) { ApiError("PIPE","GetBinding",Status); PrintToConsole("PIPE : FAIL - Unable to Bind (Sigfried)\n"); return; } pipe.Alloc = PipeAlloc ; pipe.Pull = PipePull ; pipe.Push = PipePush ; pipe.state = (char PAPI *) &state ; for (i = 0; i < BUFF_SIZE; i++) { local_buf[i] = i ; } state = NUM_CHUNKS ; checksum = (long) (CHUNK_SIZE-1) * (long) CHUNK_SIZE /2 * (long) NUM_CHUNKS ; IsabellePipeIN(IsabelleBinding, &pipe, CHUNK_SIZE, NUM_CHUNKS, checksum, BUFF_SIZE * sizeof(int), (char PAPI *) local_buf) ; if (IsabelleErrors != 0) { PrintToConsole("PIPE : FAIL - Error(s) in Isabelle Interface\n"); IsabelleErrors = 0; return; } IsabellePipeOUT(IsabelleBinding, &pipe, CHUNK_SIZE) ; if (IsabelleErrors != 0) { PrintToConsole("PIPE : FAIL - Error(s) in Isabelle Interface\n"); IsabelleErrors = 0; return; } state = NUM_CHUNKS ; IsabellePipeINOUT(IsabelleBinding, &pipe, CHUNK_SIZE, checksum) ; if (IsabelleErrors != 0) { PrintToConsole("PIPE : FAIL - Error(s) in Isabelle Interface\n"); IsabelleErrors = 0; return; } IsabelleShutdown(IsabelleBinding); if (IsabelleErrors != 0) { PrintToConsole("PIPE : FAIL - Error(s) in Isabelle Interface\n"); IsabelleErrors = 0; return; } Status = RpcBindingFree(&IsabelleBinding); if (Status) { ApiError("PIPE","RpcBindingFree",Status); PrintToConsole("PIPE : FAIL - Unable to Free Binding"); PrintToConsole(" (IsabelleBinding)\n"); return; } PrintToConsole("PIPE : PASS\n"); } void LpcSecurityHelper ( BOOL fAsync, BOOL fDynamic ) { RPC_SECURITY_QOS QOS; RPC_BINDING_HANDLE HelgaBinding; Status = GetBinding(SIGFRIED, &HelgaBinding); if (Status) { ApiError("LpcSecurity","GetBinding",Status); PrintToConsole("LpcSecurity : FAIL - Unable to Bind (Sigfried)\n"); return; } QOS.Version = RPC_C_SECURITY_QOS_VERSION; QOS.ImpersonationType = RPC_C_IMP_LEVEL_IMPERSONATE; QOS.Capabilities = RPC_C_QOS_CAPABILITIES_DEFAULT; if (fDynamic) { QOS.IdentityTracking = RPC_C_QOS_IDENTITY_DYNAMIC; } else { QOS.IdentityTracking = RPC_C_QOS_IDENTITY_STATIC; } Status = RpcBindingSetAuthInfoEx( HelgaBinding, RPC_STRING_LITERAL("ServerPrincipal"), RPC_C_AUTHN_LEVEL_CONNECT, 10, NULL, 0, &QOS); if (Status != RPC_S_OK) { ApiError("LpcSecurity","RpcBindingSetAuthInfoEx",Status); goto Cleanup; } // // Logon as local administrator and call again // HANDLE hToken; if (LogonUser( RPC_T("Administrator"), NULL, RPC_T(""), LOGON32_LOGON_BATCH, LOGON32_PROVIDER_DEFAULT, &hToken) == 0) { ApiError("LpcSecurity","LogonUser",GetLastError()); goto Cleanup; } if (ImpersonateLoggedOnUser(hToken) == 0) { ApiError("LpcSecurity","LogonUser",GetLastError()); goto Cleanup; } if (fDynamic) { PrintToConsole("LpcSecurity: Expected: Administrator\n"); } else { PrintToConsole("LpcSecurity: Expected: REDMOND\\mazharm\n"); } HelgaLpcSecurity(HelgaBinding, fAsync) ; RevertToSelf(); PrintToConsole("LpcSecurity: Expected: REDMOND\\mazharm\n"); HelgaLpcSecurity(HelgaBinding, fAsync) ; CloseHandle(hToken); Cleanup: Status = RpcBindingFree(&HelgaBinding); if (Status) { ApiError("LpcSecurity","RpcBindingFree",Status); PrintToConsole("LpcSecurity : FAIL - Unable to Free Binding"); PrintToConsole(" (HelgaBinding)\n"); return; } } void LpcSecurityTwoHandles ( BOOL fAsync ) { RPC_SECURITY_QOS QOS; RPC_BINDING_HANDLE HelgaBinding; RPC_BINDING_HANDLE HelgaBinding1; Status = GetBinding(SIGFRIED, &HelgaBinding); if (Status) { ApiError("LpcSecurity","GetBinding",Status); PrintToConsole("LpcSecurity : FAIL - Unable to Bind (Sigfried)\n"); return; } Status = GetBinding(SIGFRIED, &HelgaBinding1); if (Status) { ApiError("LpcSecurity","GetBinding",Status); PrintToConsole("LpcSecurity : FAIL - Unable to Bind (Sigfried)\n"); return; } QOS.Version = RPC_C_SECURITY_QOS_VERSION; QOS.ImpersonationType = RPC_C_IMP_LEVEL_IMPERSONATE; QOS.Capabilities = RPC_C_QOS_CAPABILITIES_DEFAULT; QOS.IdentityTracking = RPC_C_QOS_IDENTITY_STATIC; Status = RpcBindingSetAuthInfoExA( HelgaBinding, (unsigned char *) "ServerPrincipal", RPC_C_AUTHN_LEVEL_CONNECT, 10, NULL, 0, &QOS); if (Status != RPC_S_OK) { ApiError("LpcSecurity","RpcBindingSetAuthInfoEx",Status); goto Cleanup; } // // Logon as local administrator and call again // HANDLE hToken; if (LogonUserA( "Administrator", NULL, "", LOGON32_LOGON_BATCH, LOGON32_PROVIDER_DEFAULT, &hToken) == 0) { ApiError("LpcSecurity","LogonUser",GetLastError()); goto Cleanup; } if (ImpersonateLoggedOnUser(hToken) == 0) { ApiError("LpcSecurity","LogonUser",GetLastError()); goto Cleanup; } QOS.Version = RPC_C_SECURITY_QOS_VERSION; QOS.ImpersonationType = RPC_C_IMP_LEVEL_IMPERSONATE; QOS.Capabilities = RPC_C_QOS_CAPABILITIES_DEFAULT; QOS.IdentityTracking = RPC_C_QOS_IDENTITY_STATIC; Status = RpcBindingSetAuthInfoExA( HelgaBinding1, (unsigned char *) "ServerPrincipal", RPC_C_AUTHN_LEVEL_CONNECT, 10, NULL, 0, &QOS); if (Status != RPC_S_OK) { ApiError("LpcSecurity","RpcBindingSetAuthInfoEx",Status); goto Cleanup; } PrintToConsole("LpcSecurity: Expected: REDMOND\\mazharm\n"); HelgaLpcSecurity(HelgaBinding, fAsync); PrintToConsole("LpcSecurity: Expected: Administrator\n"); HelgaLpcSecurity(HelgaBinding1, fAsync); RevertToSelf(); PrintToConsole("LpcSecurity: Expected: REDMOND\\mazharm\n"); HelgaLpcSecurity(HelgaBinding, fAsync) ; PrintToConsole("LpcSecurity: Expected: Administrator\n"); HelgaLpcSecurity(HelgaBinding1, fAsync); CloseHandle(hToken); Cleanup: Status = RpcBindingFree(&HelgaBinding); if (Status) { ApiError("LpcSecurity","RpcBindingFree",Status); PrintToConsole("LpcSecurity : FAIL - Unable to Free Binding"); PrintToConsole(" (HelgaBinding)\n"); return; } Status = RpcBindingFree(&HelgaBinding1); if (Status) { ApiError("LpcSecurity","RpcBindingFree",Status); PrintToConsole("LpcSecurity : FAIL - Unable to Free Binding"); PrintToConsole(" (HelgaBinding)\n"); return; } } void LpcSecurity ( ) /*++ Routine Description: We perform a build verification test in the routine. This test checks for basic functionality of the runtime. It works with Sigfried in usvr.exe. This particular test is dedicated to a cat. --*/ { RPC_BINDING_HANDLE IsabelleBinding; int HelgaCount; Synchro(SIGFRIED) ; if ( NumberOfTestsRun++ ) { PauseExecution(TestDelay); } PrintToConsole("LpcSecurity : Verify Basic Client Functionality\n"); Status = GetBinding(SIGFRIED, &IsabelleBinding); if (Status) { ApiError("LpcSecurity","GetBinding",Status); PrintToConsole("LpcSecurity : FAIL - Unable to Bind (Sigfried)\n"); return; } #if 0 // // Sync call with static // PrintToConsole("LpcSecurity: Sync call with static tracking\n"); LpcSecurityHelper(0, 0); #endif // // Sync call with dynamic binding // PrintToConsole("LpcSecurity: Sync call with dynamic tracking\n"); LpcSecurityHelper(0, 1); #if 0 // // Async call with static binding // PrintToConsole("LpcSecurity: Async call with static tracking \n"); LpcSecurityHelper(1, 0); #endif // // Async call with dynamic binding // PrintToConsole("LpcSecurity: Async call with dynamic tracking \n"); LpcSecurityHelper(1, 1); #if 0 // // Async call with static,using two handles // LpcSecurityTwoHandles(1); // // Sync call with static using two handle // LpcSecurityTwoHandles(0); #endif IsabelleShutdown(IsabelleBinding); if (HelgaErrors != 0) { PrintToConsole("LpcSecurity : FAIL - Error(s) in Helga Interface\n"); HelgaErrors = 0; return; } if (IsabelleErrors != 0) { PrintToConsole("LpcSecurity : FAIL - Error(s) in Isabelle Interface\n"); IsabelleErrors = 0; return; } Status = RpcBindingFree(&IsabelleBinding); if (Status) { ApiError("LpcSecurity","RpcBindingFree",Status); PrintToConsole("LpcSecurity : FAIL - Unable to Free Binding"); PrintToConsole(" (IsabelleBinding)\n"); return; } PrintToConsole("LpcSecurity : PASS\n"); } RPC_STATUS UclntGetBufferWithObject ( IN OUT PRPC_MESSAGE RpcMessage, IN UUID *ObjectUuid ) /*++ Routine Description: This routine takes care of retrying to getting a buffer. Arguments: RpcMessage - Supplies and returns the message for I_RpcGetBuffer. Return Value: The result of I_RpcGetBuffer will be returned. --*/ { unsigned int RetryCount; for (RetryCount = 0; RetryCount < RETRYCOUNT; RetryCount++) { Status = I_RpcGetBufferWithObject(RpcMessage, ObjectUuid); if ( (Status != RPC_S_SERVER_TOO_BUSY) && (Status != RPC_S_CALL_FAILED_DNE)) break; PauseExecution(RETRYDELAY); } return(Status); } void HelgaObjectUuids ( RPC_BINDING_HANDLE HelgaBinding, UUID *ObjectUuid ) { RPC_MESSAGE Caller; Caller.Handle = HelgaBinding; Caller.BufferLength = sizeof(BOOL)+sizeof(UUID); Caller.ProcNum = 8 | HackForOldStubs ; Caller.RpcInterfaceInformation = &HelgaInterfaceInformation; Caller.RpcFlags = 0; if (IdempotentTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_IDEMPOTENT; } if (MaybeTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_MAYBE; } if (BroadcastTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_BROADCAST; } if (ObjectUuid) { Status = UclntGetBufferWithObject(&Caller, ObjectUuid); } else { Status = UclntGetBuffer(&Caller); } if (Status) { ApiError("Helga","I_RpcGetBuffer",Status); HelgaError(); return; } char *Ptr = (char *) Caller.Buffer; if (ObjectUuid) { *((LONG *) Ptr) = 1; Ptr += sizeof(BOOL); RpcpMemoryCopy(Ptr, ObjectUuid, sizeof(UUID)); } else { *((LONG *) Ptr) = 0; } Status = UclntSendReceive(&Caller); if (Status) { ApiError("Helga","I_RpcSendReceive",Status); HelgaError(); return; } if (Caller.BufferLength != 0) { OtherError("Helga","BufferLength != 0"); HelgaError(); return; } Status = I_RpcFreeBuffer(&Caller); if (Status) { ApiError("Helga","I_RpcFreeBuffer",Status); HelgaError(); return; } } void TestObjectUuids ( ) /*++ Routine Description: We perform a build verification test in the routine. This test checks for basic functionality of the runtime. It works with Sigfried in usvr.exe. This particular test is dedicated to a cat. --*/ { RPC_BINDING_HANDLE HelgaBinding; RPC_BINDING_HANDLE IsabelleBinding; int HelgaCount; Synchro(SIGFRIED) ; if ( NumberOfTestsRun++ ) { PauseExecution(TestDelay); } PrintToConsole("TestObjectUuids : Verify Basic Client Functionality\n"); Status = GetBinding(SIGFRIED, &HelgaBinding); if (Status) { ApiError("TestObjectUuids","GetBinding",Status); PrintToConsole("TestObjectUuids : FAIL - Unable to Bind (Sigfried)\n"); return; } Status = GetBinding(SIGFRIED, &IsabelleBinding); if (Status) { ApiError("TestObjectUuids","GetBinding",Status); PrintToConsole("TestObjectUuids : FAIL - Unable to Bind (Sigfried)\n"); return; } HelgaObjectUuids(HelgaBinding, 0); UUID MyUuid; RpcpMemorySet(&MyUuid, 'M', sizeof(UUID)); HelgaObjectUuids(HelgaBinding, &MyUuid); HelgaObjectUuids(HelgaBinding, 0); IsabelleShutdown(IsabelleBinding); if (HelgaErrors != 0) { PrintToConsole("TestObjectUuids : FAIL - Error(s) in Helga Interface\n"); HelgaErrors = 0; return; } Status = RpcBindingFree(&HelgaBinding); if (Status) { ApiError("TestObjectUuids","RpcBindingFree",Status); PrintToConsole("TestObjectUuids : FAIL - Unable to Free Binding"); PrintToConsole(" (HelgaBinding)\n"); return; } if (IsabelleErrors != 0) { PrintToConsole("TestObjectUuids : FAIL - Error(s) in Isabelle Interface\n"); IsabelleErrors = 0; return; } Status = RpcBindingFree(&IsabelleBinding); if (Status) { ApiError("TestObjectUuids","RpcBindingFree",Status); PrintToConsole("TestObjectUuids : FAIL - Unable to Free Binding"); PrintToConsole(" (IsabelleBinding)\n"); return; } PrintToConsole("TestObjectUuids : PASS\n"); } void HelgaConnId ( RPC_BINDING_HANDLE HelgaBinding, BOOL fNewConnExpected ) { RPC_MESSAGE Caller; Caller.Handle = HelgaBinding; Caller.BufferLength = sizeof(BOOL)+sizeof(UUID); Caller.ProcNum = 9 | HackForOldStubs ; Caller.RpcInterfaceInformation = &HelgaInterfaceInformation; Caller.RpcFlags = 0; if (IdempotentTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_IDEMPOTENT; } if (MaybeTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_MAYBE; } if (BroadcastTests != 0) { Caller.RpcFlags |= RPC_NCA_FLAGS_BROADCAST; } Status = UclntGetBuffer(&Caller); if (Status) { ApiError("Helga","I_RpcGetBuffer",Status); HelgaError(); return; } char *Ptr = (char *) Caller.Buffer; *((BOOL *) Ptr) = fNewConnExpected; Status = UclntSendReceive(&Caller); if (Status) { ApiError("Helga","I_RpcSendReceive",Status); HelgaError(); return; } if (Caller.BufferLength != 0) { OtherError("Helga","BufferLength != 0"); HelgaError(); return; } Status = I_RpcFreeBuffer(&Caller); if (Status) { ApiError("Helga","I_RpcFreeBuffer",Status); HelgaError(); return; } } void TestConnId ( ) /*++ Routine Description: We perform a build verification test in the routine. This test checks for basic functionality of the runtime. It works with Sigfried in usvr.exe. This particular test is dedicated to a cat. --*/ { RPC_BINDING_HANDLE HelgaBinding; RPC_BINDING_HANDLE IsabelleBinding; int HelgaCount; Synchro(SIGFRIED) ; if ( NumberOfTestsRun++ ) { PauseExecution(TestDelay); } PrintToConsole("TestConnId : Verify Basic Client Functionality\n"); Status = GetBinding(SIGFRIED, &HelgaBinding); if (Status) { ApiError("TestConnId","GetBinding",Status); PrintToConsole("TestConnId : FAIL - Unable to Bind (Sigfried)\n"); return; } Status = GetBinding(SIGFRIED, &IsabelleBinding); if (Status) { ApiError("TestConnId","GetBinding",Status); PrintToConsole("TestConnId : FAIL - Unable to Bind (Sigfried)\n"); return; } HelgaConnId(HelgaBinding, 1); HelgaConnId(HelgaBinding, 0); RpcBindingFree(&HelgaBinding); Status = GetBinding(SIGFRIED, &HelgaBinding); if (Status) { ApiError("TestConnId","GetBinding",Status); PrintToConsole("TestConnId : FAIL - Unable to Bind (Sigfried)\n"); return; } HelgaConnId(HelgaBinding, 1); HelgaConnId(HelgaBinding, 0); IsabelleShutdown(IsabelleBinding); if (HelgaErrors != 0) { PrintToConsole("TestConnId : FAIL - Error(s) in Helga Interface\n"); HelgaErrors = 0; return; } Status = RpcBindingFree(&HelgaBinding); if (Status) { ApiError("TestConnId","RpcBindingFree",Status); PrintToConsole("TestConnId : FAIL - Unable to Free Binding"); PrintToConsole(" (HelgaBinding)\n"); return; } if (IsabelleErrors != 0) { PrintToConsole("TestConnId : FAIL - Error(s) in Isabelle Interface\n"); IsabelleErrors = 0; return; } Status = RpcBindingFree(&IsabelleBinding); if (Status) { ApiError("TestConnId","RpcBindingFree",Status); PrintToConsole("TestConnId : FAIL - Unable to Free Binding"); PrintToConsole(" (IsabelleBinding)\n"); return; } PrintToConsole("TestConnId : PASS\n"); } void Hybrid ( ) /*++ Routine Description: We perform a build verification test in the routine. This test checks for basic functionality of the runtime. It works with Hybrid in usvr.exe. This particular test is dedicated to a cat. --*/ { RPC_BINDING_HANDLE HelgaBinding; RPC_BINDING_HANDLE IsabelleBinding; int HelgaCount; Synchro(SIGFRIED) ; if ( NumberOfTestsRun++ ) { PauseExecution(TestDelay); } PrintToConsole("Hybrid : Verify Basic Client Functionality\n"); Status = GetBinding(SIGFRIED, &HelgaBinding); if (Status) { ApiError("Hybrid","GetBinding",Status); PrintToConsole("Hybrid : FAIL - Unable to Bind (Sigfried)\n"); return; } Status = GetBinding(SIGFRIED, &IsabelleBinding); if (Status) { ApiError("Hybrid","GetBinding",Status); PrintToConsole("Hybrid : FAIL - Unable to Bind (Sigfried)\n"); return; } for (HelgaCount = 0; HelgaCount < 30; HelgaCount++) { Helga(HelgaBinding); IsabelleUnregisterInterfaces(IsabelleBinding) ; HelgaMustFail(HelgaBinding) ; IsabelleRegisterInterfaces(IsabelleBinding) ; } for (HelgaCount = 0; HelgaCount < 5; HelgaCount++) { TestHelgaInterface(HelgaBinding, HelgaMaxSize); IsabelleUnregisterInterfaces(IsabelleBinding) ; HelgaMustFail(HelgaBinding) ; IsabelleRegisterInterfaces(IsabelleBinding) ; } IsabelleShutdown(IsabelleBinding); if (HelgaErrors != 0) { PrintToConsole("Hybrid : FAIL - Error(s) in Helga Interface\n"); HelgaErrors = 0; return; } Status = RpcBindingFree(&HelgaBinding); if (Status) { ApiError("Hybrid","RpcBindingFree",Status); PrintToConsole("Hybrid : FAIL - Unable to Free Binding"); PrintToConsole(" (HelgaBinding)\n"); return; } if (IsabelleErrors != 0) { PrintToConsole("Hybrid : FAIL - Error(s) in Isabelle Interface\n"); IsabelleErrors = 0; return; } Status = RpcBindingFree(&IsabelleBinding); if (Status) { ApiError("Hybrid","RpcBindingFree",Status); PrintToConsole("Hybrid : FAIL - Unable to Free Binding"); PrintToConsole(" (IsabelleBinding)\n"); return; } PrintToConsole("Hybrid : PASS\n"); } void Graham ( ) /*++ Routine Description: We perform a build verification test in the routine. This test checks for basic functionality of the runtime. It works with Grant in usvr.exe. This particular test is dedicated to a cat. --*/ { RPC_BINDING_HANDLE HelgaBinding; RPC_BINDING_HANDLE IsabelleBinding; UUID ObjectUuid; unsigned short MagicValue; unsigned int Count; Synchro(GRANT) ; if ( NumberOfTestsRun++ ) { PauseExecution(TestDelay); } PrintToConsole("Graham : Verify Basic Client Functionality\n"); Status = GetBinding(GRANT, &HelgaBinding); if (Status) { ApiError("Graham","GetBinding",Status); PrintToConsole("Graham : FAIL - Unable to Bind (Grant)\n"); return; } Status = GetBinding(GRANT, &IsabelleBinding); if (Status) { ApiError("Graham","GetBinding",Status); PrintToConsole("Graham : FAIL - Unable to Bind (Grant)\n"); return; } MagicValue = 106; GenerateUuidValue(MagicValue, &ObjectUuid); Status = RpcBindingSetObject(HelgaBinding, &ObjectUuid); if (Status) { ApiError("Graham", "RpcBindingSetObject", Status); PrintToConsole("Graham : FAIL - Unable to Set Object\n"); return; } MagicValue += 1; Helga(HelgaBinding); GenerateUuidValue(MagicValue, &ObjectUuid); Status = RpcBindingSetObject(HelgaBinding, &ObjectUuid); if (Status) { ApiError("Graham", "RpcBindingSetObject", Status); PrintToConsole("Graham : FAIL - Unable to Set Object\n"); return; } MagicValue += 1; for (Count = 0; HelgaSizes[Count] != 0; Count++) { if (HelgaSizes[Count] > HelgaMaxSize) continue; HelgaIN(HelgaBinding,HelgaSizes[Count]); GenerateUuidValue(MagicValue, &ObjectUuid); Status = RpcBindingSetObject(HelgaBinding, &ObjectUuid); if (Status) { ApiError("Graham", "RpcBindingSetObject", Status); PrintToConsole("Graham : FAIL - Unable to Set Object\n"); return; } MagicValue += 1; } for (Count = 0; HelgaSizes[Count] != 0; Count++) { if (HelgaSizes[Count] > HelgaMaxSize) continue; HelgaOUT(HelgaBinding,HelgaSizes[Count]); GenerateUuidValue(MagicValue, &ObjectUuid); Status = RpcBindingSetObject(HelgaBinding, &ObjectUuid); if (Status) { ApiError("Graham", "RpcBindingSetObject", Status); PrintToConsole("Graham : FAIL - Unable to Set Object\n"); return; } MagicValue += 1; } for (Count = 0; HelgaSizes[Count] != 0; Count++) { if (HelgaSizes[Count] > HelgaMaxSize) continue; HelgaINOUT(HelgaBinding,HelgaSizes[Count]); GenerateUuidValue(MagicValue, &ObjectUuid); Status = RpcBindingSetObject(HelgaBinding, &ObjectUuid); if (Status) { ApiError("Graham", "RpcBindingSetObject", Status); PrintToConsole("Graham : FAIL - Unable to Set Object\n"); return; } MagicValue += 1; } IsabelleShutdown(IsabelleBinding); if (HelgaErrors != 0) { PrintToConsole("Graham : FAIL - Error(s) in Helga Interface\n"); HelgaErrors = 0; return; } Status = RpcBindingFree(&HelgaBinding); if (Status) { ApiError("Graham","RpcBindingFree",Status); PrintToConsole("Graham : FAIL - Unable to Free Binding"); PrintToConsole(" (HelgaBinding)\n"); return; } if (IsabelleErrors != 0) { PrintToConsole("Graham : FAIL - Error(s) in Isabelle Interface\n"); IsabelleErrors = 0; return; } Status = RpcBindingFree(&IsabelleBinding); if (Status) { ApiError("Graham","RpcBindingFree",Status); PrintToConsole("Graham : FAIL - Unable to Free Binding"); PrintToConsole(" (IsabelleBinding)\n"); return; } PrintToConsole("Graham : PASS\n"); } void Edward ( ) /*++ Routine Description: This routine verifies server support of multiple addresses and interfaces, as well as callbacks. In addition, we test binding here as well. This test works with Elliot in usvr.exe. --*/ { RPC_BINDING_HANDLE IsabelleBinding; RPC_BINDING_HANDLE SylviaMinimize; RPC_BINDING_HANDLE SylviaMaximize; RPC_BINDING_HANDLE HelgaMinimize; RPC_BINDING_HANDLE HelgaMaximize; RPC_BINDING_HANDLE EdwardMinimize; RPC_BINDING_HANDLE EdwardNormal; RPC_BINDING_HANDLE EdwardMaximize; Synchro(ELLIOTMINIMIZE) ; if ( NumberOfTestsRun++ ) { PauseExecution(TestDelay); } PrintToConsole("Edward : Verify Callbacks, Multiple Addresses"); PrintToConsole(", and Multiple Interfaces\n"); Status = GetBinding(ELLIOTMINIMIZE, &SylviaMinimize); if (Status) { ApiError("Edward","GetBinding",Status); PrintToConsole("Edward : FAIL - Unable to Bind (Elliot Minimize)\n"); return; } Status = GetBinding(ELLIOTMAXIMIZE, &SylviaMaximize); if (Status) { ApiError("Edward","GetBinding",Status); PrintToConsole("Edward : FAIL - Unable to Bind (Elliot Maximize)\n"); return; } Status = GetBinding(ELLIOTMINIMIZE, &HelgaMinimize); if (Status) { ApiError("Edward","GetBinding",Status); PrintToConsole("Edward : FAIL - Unable to Bind (Elliot Minimize)\n"); return; } Status = GetBinding(ELLIOTMAXIMIZE, &HelgaMaximize); if (Status) { ApiError("Edward","GetBinding",Status); PrintToConsole("Edward : FAIL - Unable to Bind (ElliotMaximize)\n"); return; } Status = GetBinding(ELLIOTMAXIMIZE, &IsabelleBinding); if (Status) { ApiError("Edward","GetBinding",Status); PrintToConsole("Edward : FAIL - Unable to Bind (Elliot Maximize)\n"); return; } // First, we will test callbacks. SylviaBinding = SylviaMinimize; if (SylviaCall(SylviaBinding,5,0,0) != LocalSylviaCall(5,0,0)) { PrintToConsole("Edward : FAIL - Incorrect result"); PrintToConsole(" from SylviaCall(5,0,0)\n"); return; } if (SylviaCall(SylviaBinding,10,5,0) != LocalSylviaCall(10,5,0)) { PrintToConsole("Edward : FAIL - Incorrect result"); PrintToConsole(" from SylviaCall(10,5,0)\n"); return; } // And then we will test callbacks again using the maximize address. SylviaBinding = SylviaMaximize; if (SylviaCall(SylviaBinding,5,0,0) != LocalSylviaCall(5,0,0)) { PrintToConsole("Edward : FAIL - Incorrect result from"); PrintToConsole(" SylviaCall(5,0,0)\n"); return; } if (SylviaCall(SylviaBinding,10,5,0) != LocalSylviaCall(10,5,0)) { PrintToConsole("Edward : FAIL - Incorrect result"); PrintToConsole(" from SylviaCall(10,5,0)\n"); return; } // Ok, now we will insure that the Helga interface works. Helga(HelgaMinimize); HelgaIN(HelgaMinimize,1024*4); HelgaOUT(HelgaMinimize,1024*8); HelgaINOUT(HelgaMinimize,1024*16); Helga(HelgaMaximize); HelgaIN(HelgaMaximize,1024*4); HelgaOUT(HelgaMaximize,1024*8); HelgaINOUT(HelgaMaximize,1024*16); if (HelgaErrors != 0) { PrintToConsole("Edward : FAIL - Error(s) in Helga Interface\n"); HelgaErrors = 0; return; } // Now we want to unbind both Sylvia binding handles, and then try // the Helga interface again. if (SylviaErrors != 0) { PrintToConsole("Edward : FAIL - Error(s) in Sylvia Interface\n"); SylviaErrors = 0; return; } Status = RpcBindingFree(&SylviaMinimize); if (Status) { ApiError("Edward","RpcBindingFree",Status); PrintToConsole("Edward : FAIL - Unable to Free Binding "); PrintToConsole("(SylviaMinimize)\n"); return; } Status = RpcBindingFree(&SylviaMaximize); if (Status) { ApiError("Edward","RpcBindingFree",Status); PrintToConsole("Edward : FAIL - Unable to Free Binding"); PrintToConsole(" (SylviaMaximize)\n"); return; } // Ok, now we will insure that the Helga interface still works. Helga(HelgaMinimize); HelgaIN(HelgaMinimize,1024*2); HelgaOUT(HelgaMinimize,1024*4); HelgaINOUT(HelgaMinimize,1024*8); Helga(HelgaMaximize); HelgaIN(HelgaMaximize,1024*2); HelgaOUT(HelgaMaximize,1024*4); HelgaINOUT(HelgaMaximize,1024*8); if (HelgaErrors != 0) { PrintToConsole("Edward : FAIL - Error(s) in Helga Interface\n"); HelgaErrors = 0; return; } // Now we need to test the binding stuff. Status = GetBinding(ELLIOTMINIMIZE, &EdwardMinimize); if (Status) { ApiError("Edward","GetBinding",Status); PrintToConsole("Edward : FAIL - Unable to Bind (Elliot Minimize)\n"); return; } Status = GetBinding(ELLIOTNORMAL, &EdwardNormal); if (Status) { ApiError("Edward","GetBinding",Status); PrintToConsole("Edward : FAIL - Unable to Bind (Elliot Normal)\n"); return; } Status = GetBinding(ELLIOTMAXIMIZE, &EdwardMaximize); if (Status) { ApiError("Edward","GetBinding",Status); PrintToConsole("Edward : FAIL - Unable to Bind (Elliot Maximize)\n"); return; } if (HelgaWrongInterfaceGuid(EdwardMinimize)) { PrintToConsole("Edward : FAIL - HelgaWrongInterfaceGuid Succeeded\n"); return; } if (HelgaWrongInterfaceGuid(EdwardNormal)) { PrintToConsole("Edward : FAIL - HelgaWrongInterfaceGuid Succeeded\n"); return; } if (HelgaWrongInterfaceGuid(EdwardMaximize)) { PrintToConsole("Edward : FAIL - HelgaWrongInterfaceGuid Succeeded\n"); return; } //Skip over the WrongTransfer Syntax tests for Datagram //Datagram doesnt req. any checks on Transfer syntaxes if (DatagramTests == 0) { if (HelgaWrongTransferSyntax(EdwardMinimize)) { PrintToConsole("Edward : FAIL - HelgaWrongTransferSyntax"); PrintToConsole(" Succeeded\n"); return; } if (HelgaWrongTransferSyntax(EdwardNormal)) { PrintToConsole("Edward : FAIL - HelgaWrongTransferSyntax"); PrintToConsole(" Succeeded\n"); return; } if (HelgaWrongTransferSyntax(EdwardMaximize)) { PrintToConsole("Edward : FAIL - HelgaWrongTransferSyntax"); PrintToConsole(" Succeeded\n"); return; } } Status = RpcBindingFree(&EdwardMinimize); if (Status) { PrintToConsole("Edward : FAIL - Unable to Free Binding "); PrintToConsole("(EdwardMinimize)\n"); return; } Status = RpcBindingFree(&EdwardNormal); if (Status) { PrintToConsole("Edward : FAIL - Unable to Free Binding "); PrintToConsole("(EdwardNormal)\n"); return; } Status = RpcBindingFree(&EdwardMaximize); if (Status) { PrintToConsole("Edward : FAIL - Unable to Free Binding "); PrintToConsole("(EdwardMaximize)\n"); return; } // Finally, we will tell the server to shutdown, and then we will // unbind the Helga bindings. IsabelleShutdown(IsabelleBinding); if (IsabelleErrors != 0) { PrintToConsole("Edward : FAIL - Error(s) in Isabelle Interface\n"); IsabelleErrors = 0; return; } Status = RpcBindingFree(&IsabelleBinding); if (Status) { PrintToConsole("Edward : FAIL - Unable to Free Binding"); PrintToConsole(" (IsabelleBinding)\n"); return; } Status = RpcBindingFree(&HelgaMaximize); if (Status) { PrintToConsole("Edward : FAIL - Unable to Free Binding "); PrintToConsole("(HelgaMaximize)\n"); return; } Status = RpcBindingFree(&HelgaMinimize); if (Status) { PrintToConsole("Edward : FAIL - Unable to Free Binding"); PrintToConsole(" (HelgaMinimize)\n"); return; } PrintToConsole("Edward : PASS\n"); } #ifdef NOVELL_NP unsigned int AstroThreads = 1; #else // NOVELL_NP unsigned int AstroThreads = 2; #endif // NOVELL #ifndef NOTHREADS unsigned int AstroThreadCount; /* volatile */ int fAstroResume; void AstroSylvia ( IN void * Ignore ) /*++ Routine Description: This routine will be called by each thread created by the Astro test to make calls against the Sylvia interface. Arguments: Ignore - Supplies an argument which we do not use. The thread class takes a single argument, which we ignore. --*/ { UNUSED(Ignore); if (SylviaCall(SylviaBinding,5,0,0) != LocalSylviaCall(5,0,0)) { PrintToConsole("AstroSylvia : FAIL - Incorrect result from"); PrintToConsole(" SylviaCall(5,0,0)\n"); return; } if (SylviaCall(SylviaBinding,10,5,0) != LocalSylviaCall(10,5,0)) { PrintToConsole("AstroSylvia : FAIL - Incorrect result from"); PrintToConsole(" SylviaCall(10,5,0)\n"); return; } TestMutexRequest(); AstroThreadCount -= 1; if (AstroThreadCount == 0) { TestMutexClear(); fAstroResume = 1; } else TestMutexClear(); } MUTEX2 Mutex2(&Status); void AstroMutex ( RPC_BINDING_HANDLE Dontcare ) { int i; while (1) { for (i = 0; i < 10; i++) { Mutex2.Request(); PrintToConsole("Thread %d in the mutex\n", GetCurrentThreadId()); Mutex2.Clear(); PauseExecution(30*i); } } } void AstroHelga ( RPC_BINDING_HANDLE HelgaBinding ) /*++ Routine Description: This routine will be used by the Astro test to perform a test against the Helga interface. More that one thread will execute this routine at a time. Arguments: HelgaBinding - Supplies the binding handle to use in make calls using the Helga interface. --*/ { TestHelgaInterface(HelgaBinding, ( HelgaMaxSize < 8*1024L ? HelgaMaxSize : 8*1024L )); TestMutexRequest(); AstroThreadCount -= 1; if (AstroThreadCount == 0) { TestMutexClear(); fAstroResume = 1; } else TestMutexClear(); } void AstroHelgaAndUnbind ( // Perform the a test using the Helga interface. When // done, unbind the binding handle. RPC_BINDING_HANDLE HelgaBinding // Binding to use to the Helga interface. ) /*++ Routine Description: This routine is the same as AstroHelga, except that we free the binding handle when we are done using it. Arguments: HelgaBinding - Supplies the binding handle to use in making calls using the Helga interface. When we are done with it, we free it. --*/ { TestHelgaInterface(HelgaBinding, ( HelgaMaxSize < 8*1024L ? HelgaMaxSize : 8*1024L )); Status = RpcBindingFree(&HelgaBinding); if (Status) { ApiError("Astro","RpcBindingFree",Status); PrintToConsole("Astro : FAIL - Unable to Free Binding "); PrintToConsole("(HelgaBinding)\n"); return; } TestMutexRequest(); AstroThreadCount -= 1; if (AstroThreadCount == 0) { TestMutexClear(); fAstroResume = 1; } else TestMutexClear(); } typedef enum _ASTRO_BIND_OPTION { AstroBindOnce, AstroBindThread, AstroBindSylvia, AstroDontBind } ASTRO_BIND_OPTION; int PerformMultiThreadAstroTest ( ASTRO_BIND_OPTION AstroBindOption, void (*AstroTestRoutine)(RPC_BINDING_HANDLE), unsigned int Address ) /*++ Routine Description: This routine takes care of performing all of the multi-threaded Astro tests. We create the binding handles as well as creating the threads to perform each test. We also wait around for all of the threads to complete. Arguments: AstroBindOption - Supplies information indicating how the binding for this particular test should be done. AstroTestRoutine - Supplies the test routine to be executed by each thread performing the test. Address - Supplies the address index to be passed to GetStringBinding used to get a string binding. The string binding is passed to RpcBindingFromStringBinding. Return Value: A return value of zero indicates that the test succeeded. Otherwise, the test failed. --*/ { RPC_STATUS RpcStatus; RPC_BINDING_HANDLE BindingHandle; unsigned int ThreadCount; if (AstroBindOption == AstroBindOnce) { Status = GetBinding(Address, &BindingHandle); if (Status) { ApiError("Astro","GetBinding",Status); PrintToConsole("Astro : FAIL - Unable to Bind\n"); return(1); } } else if (AstroBindOption == AstroBindSylvia) { Status = GetBinding(Address, &BindingHandle); SylviaBinding = BindingHandle; if (Status) { ApiError("Astro","GetBinding",Status); PrintToConsole("Astro : FAIL - Unable to Bind\n"); return(1); } } AstroThreadCount = AstroThreads; fAstroResume = 0; for (ThreadCount = 0; ThreadCount < AstroThreads; ThreadCount++) { if (AstroBindOption == AstroBindThread) { Status = GetBinding(Address, &BindingHandle); if (Status) { ApiError("Astro","GetBinding",Status); PrintToConsole("Astro : FAIL - Unable to Bind\n"); return(1); } } RpcStatus = RPC_S_OK; HANDLE HandleToThread; unsigned long ThreadId; HandleToThread = CreateThread( 0, DefaultThreadStackSize, (LPTHREAD_START_ROUTINE) AstroTestRoutine, BindingHandle, 0, &ThreadId); if (HandleToThread == 0) { OtherError("Astro", "CreateThread failed"); PrintToConsole("Astro : FAIL - Unable to create thread\n"); return(1); } } while (!fAstroResume) PauseExecution(200L); if (AstroThreadCount != 0) { PrintToConsole("Astro : FAIL - AstroThreadCount != 0\n"); return(1); } if (HelgaErrors != 0) { PrintToConsole("Astro : FAIL - Error(s) in Helga Interface\n"); return(1); } if ( (AstroBindOption == AstroBindOnce) || (AstroBindOption == AstroBindSylvia)) { Status = RpcBindingFree(&BindingHandle); if (Status) { ApiError("Astro","RpcBindingFree",Status); PrintToConsole("Astro : FAIL - Unable to Free Binding "); PrintToConsole("(BindingHandle)\n"); return(1); } } return(0); } #endif void Astro ( ) /*++ Routine Description: This routine tests the runtime by having more than one thread simultaneously perform remote procedure calls. This test works with the Andromida test in usvr.exe. --*/ { RPC_BINDING_HANDLE IsabelleBinding; RPC_STATUS RpcStatus = RPC_S_OK; Synchro(ANDROMIDA) ; if ( NumberOfTestsRun++ ) { PauseExecution(TestDelay); } PrintToConsole("Astro : Multithreaded Clients (%d)\n", AstroThreads); Status = GetBinding(ANDROMIDA, &IsabelleBinding); if (Status) { ApiError("Astro","GetBinding",Status); PrintToConsole("Astro : FAIL - Unable to Bind (Andromida)\n"); return; } #ifndef NOTHREADS if (PerformMultiThreadAstroTest(AstroBindOnce,AstroHelga, ANDROMIDA)) return; if (PerformMultiThreadAstroTest(AstroBindThread, AstroHelgaAndUnbind, ANDROMIDA)) return; if ( PerformMultiThreadAstroTest(AstroBindSylvia, AstroSylvia, ANDROMIDA) != 0 ) { return; } #endif IsabelleShutdown(IsabelleBinding); if (IsabelleErrors != 0) { PrintToConsole("Astro : FAIL - Error(s) in Isabelle Interface\n"); IsabelleErrors = 0; return; } Status = RpcBindingFree(&IsabelleBinding); if (Status) { ApiError("Astro","RpcBindingFree",Status); PrintToConsole("Astro : FAIL - Unable to Free Binding"); PrintToConsole(" (IsabelleBinding)\n"); return; } PrintToConsole("Astro : PASS\n"); } int FitzgeraldCompose ( IN char PAPI * ObjUuid OPTIONAL, IN char PAPI * Protseq, IN char PAPI * NetworkAddr, IN char PAPI * Endpoint OPTIONAL, IN char PAPI * NetworkOptions OPTIONAL, IN char PAPI * ExpectedStringBinding ) /*++ Routine Description: This routine is used by Fitzgerald to test the RpcStringBindingCompose API. Arguments: ObjUuid - Optionally supplies the object UUID field to pass to RpcStringBindingCompose. Protseq - Supplies the RPC protocol sequence field to pass to RpcStringBindingCompose. NetworkAddr - Supplies the network address field to pass to RpcStringBindingCompose. Endpoint - Optionally supplies the endpoint field to pass to RpcStringBindingCompose. NetworkOptions - Optionally supplies the network options field to pass to RpcStringBindingCompose. ExpectedStringBinding - Supplies the expected string binding which should be obtained from RpcStringBindingCompose. Return Value: 0 - The test passed successfully. 1 - The test failed. --*/ { unsigned char PAPI * StringBinding; RPC_STATUS Status; Status = RpcStringBindingComposeA((unsigned char PAPI *) ObjUuid, (unsigned char PAPI *) Protseq, (unsigned char PAPI *) NetworkAddr, (unsigned char PAPI *) Endpoint, (unsigned char PAPI *) NetworkOptions,&StringBinding); if (Status) { ApiError("FitzgeraldCompose","RpcStringBindingCompose",Status); PrintToConsole("Fitzgerald : FAIL - Error in"); PrintToConsole(" RpcStringBindingCompose\n"); return(1); } if (strcmp((char PAPI *) StringBinding, (char PAPI *) ExpectedStringBinding) != 0) { PrintToConsole("Fitzgerald : FAIL - StringBinding"); PrintToConsole(" != ExpectedStringBinding\n"); return(1); } Status = RpcStringFreeA(&StringBinding); if (Status) { ApiError("FitzgeraldCompose","RpcStringFree",Status); PrintToConsole("Fitzgerald : FAIL - Error in RpcStringFree\n"); return(1); } return(0); } int FitzgeraldParse ( IN char PAPI * StringBinding, IN char PAPI * ExpectedObjUuid OPTIONAL, IN char PAPI * ExpectedProtseq OPTIONAL, IN char PAPI * ExpectedNetworkAddr OPTIONAL, IN char PAPI * ExpectedEndpoint OPTIONAL, IN char PAPI * ExpectedOptions OPTIONAL ) /*++ Routine Description: This routine is used by Fitzgerald to test the RpcStringBindingParse API. Arguments: StringBinding - Supplies the string binding to be parsed. ExpectedObjUuid - Supplies a string containing the expected object UUID field. ExpectedProtseq - Supplies the expected RPC protocol sequence field. ExpectedNetworkAddr - Supplies the expected network address field. ExpectedEndpoint - Supplies the expected endpoint field. ExpectedOptions - Supplies the expected options field. Return Value: 0 - The test passed successfully. 1 - The test failed. --*/ { unsigned char PAPI * ObjUuid = 0; unsigned char PAPI * Protseq = 0; unsigned char PAPI * NetworkAddr = 0; unsigned char PAPI * Endpoint = 0; unsigned char PAPI * Options = 0; RPC_STATUS Status; Status = RpcStringBindingParseA((unsigned char PAPI *) StringBinding, (ARGUMENT_PRESENT(ExpectedObjUuid) ? (unsigned char PAPI * PAPI *) &ObjUuid : 0), (ARGUMENT_PRESENT(ExpectedProtseq) ? (unsigned char PAPI * PAPI *) &Protseq : 0), (ARGUMENT_PRESENT(ExpectedNetworkAddr) ? (unsigned char PAPI * PAPI *) &NetworkAddr : 0), (ARGUMENT_PRESENT(ExpectedEndpoint) ? (unsigned char PAPI * PAPI *) &Endpoint : 0), (ARGUMENT_PRESENT(ExpectedOptions) ? (unsigned char PAPI * PAPI *) &Options : 0)); if (Status) { ApiError("FitzgeraldParse","RpcStringBindingParse",Status); PrintToConsole("Fitzgerald : FAIL - Error in"); PrintToConsole(" RpcStringBindingParse\n"); return(1); } if (strcmp(ExpectedObjUuid,(char PAPI *) ObjUuid) != 0) { PrintToConsole("Fitzgerald : FAIL - ExpectedObjUuid != ObjUuid"); return(1); } if (strcmp(ExpectedProtseq,(char PAPI *) Protseq) != 0) { PrintToConsole("Fitzgerald : FAIL - ExpectedProtseq != Protseq"); return(1); } if (strcmp(ExpectedNetworkAddr,(char PAPI *) NetworkAddr) != 0) { PrintToConsole("Fitzgerald : FAIL - ExpectedNetworkAddr"); PrintToConsole(" != NetworkAddr"); return(1); } if (strcmp(ExpectedEndpoint,(char PAPI *) Endpoint) != 0) { PrintToConsole("Fitzgerald : FAIL - ExpectedEndpoint != Endpoint"); return(1); } if (strcmp(ExpectedOptions,(char PAPI *) Options) != 0) { PrintToConsole("Fitzgerald : FAIL - ExpectedOptions != Options"); return(1); } Status = RpcStringFreeA(&ObjUuid); if (Status) { ApiError("FitzgeraldParse","RpcStringFree",Status); PrintToConsole("Fitzgerald : FAIL - Error in RpcStringFree\n"); return(1); } Status = RpcStringFreeA(&Protseq); if (Status) { ApiError("FitzgeraldParse","RpcStringFree",Status); PrintToConsole("Fitzgerald : FAIL - Error in RpcStringFree\n"); return(1); } Status = RpcStringFreeA(&NetworkAddr); if (Status) { ApiError("FitzgeraldParse","RpcStringFree",Status); PrintToConsole("Fitzgerald : FAIL - Error in RpcStringFree\n"); return(1); } Status = RpcStringFreeA(&Endpoint); if (Status) { ApiError("FitzgeraldParse","RpcStringFree",Status); PrintToConsole("Fitzgerald : FAIL - Error in RpcStringFree\n"); return(1); } Status = RpcStringFreeA(&Options); if (Status) { ApiError("FitzgeraldParse","RpcStringFree",Status); PrintToConsole("Fitzgerald : FAIL - Error in RpcStringFree\n"); return(1); } return(0); } int FitzgeraldComposeAndParse ( void ) /*++ Routine Description: This routine tests that the string binding (RpcStringBindingCompose and RpcStringBindingParse) and string (RpcStringFree) APIs are working correctly. This is a build verification test; hence it focuses on testing that all functionality is there, testing error cases are not quite as important. Return Value: Zero will be returned if all of the tests pass, otherwise, non-zero will be returned. --*/ { unsigned char PAPI * StringBinding; if (FitzgeraldCompose(0,"ncacn_np","\\\\server","\\pipe\\endpoint",0, "ncacn_np:\\\\\\\\server[\\\\pipe\\\\endpoint]")) return(1); if (FitzgeraldCompose(0,"ncacn_np","\\\\server",0,0, "ncacn_np:\\\\\\\\server")) return(1); Status = RpcStringBindingComposeA( (unsigned char PAPI *) "12345678-9012-B456-8001-08002B033D7AA", (unsigned char PAPI *) "ncacn_np", (unsigned char PAPI *) "\\\\server", 0,0, &StringBinding); if ( Status != RPC_S_INVALID_STRING_UUID ) { ApiError("FitzgeraldComposeAndParse", "RpcStringBindingCompose", Status); PrintToConsole("Fitzgerald : FAIL - Error "); PrintToConsole("in RpcStringBindingCompose\n"); return(1); } if (FitzgeraldCompose("12345678-9012-B456-8001-08002B033D7A", "ncacn_np","\\\\server","\\pipe\\endpoint",0, "12345678-9012-b456-8001-08002b033d7a@ncacn_np:\\\\\\\\server[\\\\pipe\\\\endpoint]")) return(1); if (FitzgeraldCompose(0,"ncacn_np","\\\\server","\\pipe\\endpoint", "security=identify", "ncacn_np:\\\\\\\\server[\\\\pipe\\\\endpoint,security=identify]")) return(1); if (FitzgeraldCompose(0,"ncacn_np","\\\\server",0,"option=value", "ncacn_np:\\\\\\\\server[,option=value]")) return(1); if (FitzgeraldParse("12345678-9012-b456-8001-08002b033d7a@ncacn_np:\\\\\\\\server[\\\\pipe\\\\endpoint,security=identify]", "12345678-9012-b456-8001-08002b033d7a", "ncacn_np","\\\\server","\\pipe\\endpoint", "security=identify")) return(1); if (FitzgeraldParse("ncacn_np:\\\\\\\\server", "","ncacn_np","\\\\server","","")) return(1); if (FitzgeraldParse("ncacn_np:\\\\\\\\server[\\\\pipe\\\\endpoint]", "","ncacn_np","\\\\server","\\pipe\\endpoint","")) return(1); return(0); } int FitzgeraldBindingCopy ( ) /*++ Routine Description: Fitzgerald uses this routine to test the RpcBindingCopy API (we also use RpcBindingFromStringBinding and RpcBindingFree). Return Value: Zero will be returned if all of the tests pass, otherwise, non-zero will be returned. --*/ { RPC_BINDING_HANDLE BindingHandle; RPC_BINDING_HANDLE CopiedBeforeRpc; RPC_BINDING_HANDLE CopiedAfterRpc; Status = GetBinding(FREDRICK, &BindingHandle); if (Status) { ApiError("Fitzgerald","GetBinding",Status); PrintToConsole("Fitzgerald : FAIL - Unable to Bind"); PrintToConsole(" (Fredrick)"); return(1); } Status = RpcBindingCopy(BindingHandle,&CopiedBeforeRpc); if (Status) { ApiError("Fitzgerald","RpcBindingCopy",Status); PrintToConsole("Fitzgerald : FAIL - Unable to Copy Binding"); PrintToConsole(" (BindingHandle)\n"); return(1); } Helga(BindingHandle); if (HelgaErrors != 0) { PrintToConsole("Fitzgerald : FAIL - Error(s) in Helga Interface\n"); HelgaErrors = 0; return(1); } Helga(CopiedBeforeRpc); if (HelgaErrors != 0) { PrintToConsole("Fitzgerald : FAIL - Error(s) in Helga Interface\n"); HelgaErrors = 0; return(1); } Status = RpcBindingCopy(CopiedBeforeRpc,&CopiedAfterRpc); if (Status) { ApiError("Fitzgerald","RpcBindingCopy",Status); PrintToConsole("Fitzgerald : FAIL - Unable to Copy Binding"); PrintToConsole(" (CopiedBeforeRpc)\n"); return(1); } Status = RpcBindingFree(&BindingHandle); if (Status) { ApiError("Fitzgerald","RpcBindingFree",Status); PrintToConsole("Fitzgerald : FAIL - Unable to Free Binding"); PrintToConsole(" (BindingHandle)\n"); return(1); } Helga(CopiedBeforeRpc); if (HelgaErrors != 0) { PrintToConsole("Fitzgerald : FAIL - Error(s) in Helga Interface\n"); HelgaErrors = 0; return(1); } Helga(CopiedAfterRpc); if (HelgaErrors != 0) { PrintToConsole("Fitzgerald : FAIL - Error(s) in Helga Interface\n"); HelgaErrors = 0; return(1); } Status = RpcBindingFree(&CopiedBeforeRpc); if (Status) { ApiError("Fitzgerald","RpcBindingFree",Status); PrintToConsole("Fitzgerald : FAIL - Unable to Free Binding"); PrintToConsole(" (CopiedBeforeRpc)\n"); return(1); } Helga(CopiedAfterRpc); if (HelgaErrors != 0) { PrintToConsole("Fitzgerald : FAIL - Error(s) in Helga Interface\n"); HelgaErrors = 0; return(1); } Status = RpcBindingFree(&CopiedAfterRpc); if (Status) { ApiError("Fitzgerald","RpcBindingFree",Status); PrintToConsole("Fitzgerald : FAIL - Unable to Free Binding"); PrintToConsole(" (CopiedAfterRpc)\n"); return(1); } return(0); } int FitzgeraldToStringBinding ( IN unsigned char PAPI * UseThisStringBinding, IN unsigned char PAPI * ExpectedStringBinding, IN UUID PAPI * ObjectUuid OPTIONAL ) /*++ Routine Description: This routine tests the RpcBindingToStringBinding API. Arguments: UseThisStringBinding - Supplies the string binding to used in making the binding handle. ExpectedStringBinding - Supplies the expected string binding to be obtained from RpcBindingToStringBinding. ObjectUuid - Optionally supplies an object uuid which should be set in the binding handle. Return Value: Zero will be returned if the test passes, otherwise, non-zero will be returned. --*/ { RPC_BINDING_HANDLE BindingHandle; unsigned char PAPI * StringBinding; Status = RpcBindingFromStringBindingA(UseThisStringBinding,&BindingHandle); if (Status) { ApiError("Fitzgerald","RpcBindingFromStringBinding",Status); PrintToConsole("Fitzgerald : FAIL - Unable to Bind"); PrintToConsole(" (Fredrick)\n"); return(1); } if (ARGUMENT_PRESENT(ObjectUuid)) { Status = RpcBindingSetObject(BindingHandle,ObjectUuid); if (Status) { ApiError("Fitzgerald","RpcBindingSetObject",Status); PrintToConsole("Fitzgerald : FAIL - Error in "); PrintToConsole("RpcBindingSetObject\n"); return(1); } } Status = RpcBindingToStringBindingA(BindingHandle,&StringBinding); if (Status) { ApiError("Fitzgerald","RpcBindingToStringBinding",Status); PrintToConsole("Fitzgerald : FAIL - Unable to Create String Binding"); PrintToConsole(" (BindingHandle)\n"); return(1); } if (strcmp((char *) ExpectedStringBinding,(char *) StringBinding) != 0) { PrintToConsole("Fitzgerald : FAIL - ExpectedStringBinding"); PrintToConsole(" != StringBinding\n"); return(1); } Status = RpcStringFreeA(&StringBinding); if (Status) { ApiError("Fitzgerald","RpcStringFree",Status); PrintToConsole("Fitzgerald : FAIL - Error in RpcStringFree\n"); return(1); } Helga(BindingHandle); Status = RpcBindingToStringBindingA(BindingHandle,&StringBinding); if (Status) { ApiError("Fitzgerald","RpcBindingToStringBinding",Status); PrintToConsole("Fitzgerald : FAIL - Unable to Create String Binding"); PrintToConsole(" (BindingHandle)\n"); return(1); } if (strcmp((char *) ExpectedStringBinding,(char *) StringBinding) != 0) { PrintToConsole("Fitzgerald : FAIL - ExpectedStringBinding"); PrintToConsole(" != StringBinding\n"); return(1); } Status = RpcStringFreeA(&StringBinding); if (Status) { ApiError("Fitzgerald","RpcStringFree",Status); PrintToConsole("Fitzgerald : FAIL - Error in RpcStringFree\n"); return(1); } Status = RpcBindingFree(&BindingHandle); if (Status) { ApiError("Fitzgerald","RpcBindingCopy",Status); PrintToConsole("Fitzgerald : FAIL - Unable to Free Binding"); PrintToConsole(" (BindingHandle)\n"); return(1); } return(0); } int FitzgeraldInqSetObjectUuid ( IN unsigned int SetObjectBeforeRpcFlag, IN unsigned int InqObjectBeforeRpcFlag, IN UUID PAPI * ObjectUuid, IN unsigned char PAPI * StringBinding ) /*++ Routine Description: This routine tests the RpcBindingInqObject and RpcBindingSetObject APIs. Arguments: SetObjectBeforeRpcFlag - Supplies a flag that specifies when the object uuid in the binding handle should be set: one means the object uuid should be set before making a remote procedure call, and zero means afterward. InqObjectBeforeRpcFlag - Supplies a flag which is the same as the SetObjectBeforeRpcFlag, but it applies to inquiring the object uuid. ObjectUuid - Supplies the uuid to set in the binding handle. StringBinding - Supplies the string binding to use. Return Value: Zero will be returned if all of the tests pass, otherwise, non-zero will be returned. --*/ { UUID InqObjectUuid; RPC_BINDING_HANDLE BindingHandle; Status = RpcBindingFromStringBindingA(StringBinding,&BindingHandle); if (Status) { ApiError("Fitzgerald","RpcBindingFromStringBinding",Status); PrintToConsole("Fitzgerald : FAIL - Unable to Bind"); PrintToConsole(" (Fredrick)\n"); return(1); } if (SetObjectBeforeRpcFlag == 1) { Status = RpcBindingSetObject(BindingHandle,ObjectUuid); if (Status) { ApiError("Fitzgerald","RpcBindingSetObject",Status); PrintToConsole("Fitzgerald : FAIL - Error in "); PrintToConsole("RpcBindingSetObject\n"); return(1); } } if (InqObjectBeforeRpcFlag == 1) { Status = RpcBindingInqObject(BindingHandle,&InqObjectUuid); if (Status) { ApiError("Fitzgerald","RpcBindingInqObject",Status); PrintToConsole("Fitzgerald : FAIL - Error in "); PrintToConsole("RpcBindingInqObject\n"); return(1); } if ( (InqObjectUuid.Data1 != ObjectUuid->Data1) || (InqObjectUuid.Data2 != ObjectUuid->Data2) || (InqObjectUuid.Data3 != ObjectUuid->Data3) || (InqObjectUuid.Data4[0] != ObjectUuid->Data4[0]) || (InqObjectUuid.Data4[1] != ObjectUuid->Data4[1]) || (InqObjectUuid.Data4[2] != ObjectUuid->Data4[2]) || (InqObjectUuid.Data4[3] != ObjectUuid->Data4[3]) || (InqObjectUuid.Data4[4] != ObjectUuid->Data4[4]) || (InqObjectUuid.Data4[5] != ObjectUuid->Data4[5]) || (InqObjectUuid.Data4[6] != ObjectUuid->Data4[6]) || (InqObjectUuid.Data4[7] != ObjectUuid->Data4[7])) { PrintToConsole("Fitzgerald : FAIL - InqObjectUuid !="); PrintToConsole(" SetObjectUuid\n"); return(1); } } Helga(BindingHandle); if (SetObjectBeforeRpcFlag == 0) { Status = RpcBindingSetObject(BindingHandle,ObjectUuid); if (Status) { ApiError("Fitzgerald","RpcBindingSetObject",Status); PrintToConsole("Fitzgerald : FAIL - Error in "); PrintToConsole("RpcBindingSetObject\n"); return(1); } } if (InqObjectBeforeRpcFlag == 0) { Status = RpcBindingInqObject(BindingHandle,&InqObjectUuid); if (Status) { ApiError("Fitzgerald","RpcBindingInqObject",Status); PrintToConsole("Fitzgerald : FAIL - Error in "); PrintToConsole("RpcBindingInqObject\n"); return(1); } if ( (InqObjectUuid.Data1 != ObjectUuid->Data1) || (InqObjectUuid.Data2 != ObjectUuid->Data2) || (InqObjectUuid.Data3 != ObjectUuid->Data3) || (InqObjectUuid.Data4[0] != ObjectUuid->Data4[0]) || (InqObjectUuid.Data4[1] != ObjectUuid->Data4[1]) || (InqObjectUuid.Data4[2] != ObjectUuid->Data4[2]) || (InqObjectUuid.Data4[3] != ObjectUuid->Data4[3]) || (InqObjectUuid.Data4[4] != ObjectUuid->Data4[4]) || (InqObjectUuid.Data4[5] != ObjectUuid->Data4[5]) || (InqObjectUuid.Data4[6] != ObjectUuid->Data4[6]) || (InqObjectUuid.Data4[7] != ObjectUuid->Data4[7])) { PrintToConsole("Fitzgerald : FAIL - InqObjectUuid !="); PrintToConsole(" SetObjectUuid\n"); return(1); } } Status = RpcBindingFree(&BindingHandle); if (Status) { ApiError("Fitzgerald","RpcBindingCopy",Status); PrintToConsole("Fitzgerald : FAIL - Unable to Free Binding"); PrintToConsole(" (BindingHandle)\n"); return(1); } return(0); } int FitzgeraldStringBindingAndObject ( ) /*++ Routine Description: Fitzgerald uses this routine to test the RpcBindingToStringBinding, RpcBindingInqObject, and RpcBindingSetObject APIs. We need to test them together because we need to check that the object uuid gets placed into the string binding. Return Value: Zero will be returned if all of the tests pass, otherwise, non-zero will be returned. --*/ { UUID ObjectUuid; unsigned char PAPI * StringBinding1; unsigned char PAPI * StringBinding2; if (FitzgeraldToStringBinding(GetStringBinding(FREDRICK,0,0), GetStringBinding(FREDRICK,0,0), 0)) return(1); if (FitzgeraldToStringBinding(GetStringBinding(FREDRICK, "12345678-9012-B456-8001-08002B033D7A",0), GetStringBinding(FREDRICK, "12345678-9012-B456-8001-08002B033D7A",0), 0)) return(1); ObjectUuid.Data1 = 0x12345678; ObjectUuid.Data2 = 0x9012; ObjectUuid.Data3 = 0xB456; ObjectUuid.Data4[0] = 0x80; ObjectUuid.Data4[1] = 0x01; ObjectUuid.Data4[2] = 0x08; ObjectUuid.Data4[3] = 0x00; ObjectUuid.Data4[4] = 0x2B; ObjectUuid.Data4[5] = 0x03; ObjectUuid.Data4[6] = 0x3D; ObjectUuid.Data4[7] = 0x7A; StringBinding1 = GetStringBinding(FREDRICK, 0, 0) ; StringBinding2 = GetStringBinding(FREDRICK, "12345678-9012-B456-8001-08002B033D7A",0) ; if (FitzgeraldToStringBinding(StringBinding1, StringBinding2, &ObjectUuid)) return(1); #if 0 if (FitzgeraldToStringBinding(GetStringBinding(FREDRICK,0,0), GetStringBinding(FREDRICK, "12345678-9012-B456-8001-08002B033D7A",0), &ObjectUuid)) return(1); #endif if (FitzgeraldInqSetObjectUuid(1,1,&ObjectUuid, GetStringBinding(FREDRICK,0,0))) return(1); if (FitzgeraldInqSetObjectUuid(1,0,&ObjectUuid, GetStringBinding(FREDRICK,0,0))) return(1); if (FitzgeraldInqSetObjectUuid(0,0,&ObjectUuid, GetStringBinding(FREDRICK,0,0))) return(1); if (FitzgeraldInqSetObjectUuid(2,1,&ObjectUuid, GetStringBinding(FREDRICK, "12345678-9012-B456-8001-08002B033D7A",0))) return(1); if (FitzgeraldInqSetObjectUuid(2,0,&ObjectUuid, GetStringBinding(FREDRICK, "12345678-9012-B456-8001-08002B033D7A",0))) return(1); return(0); } int FitzgeraldComTimeout ( IN unsigned int SetBeforeRpc, IN unsigned int SetBeforeRpcTimeout, IN unsigned int InqBeforeRpc, IN unsigned int InqBeforeRpcTimeout, IN unsigned int SetAfterRpc, IN unsigned int SetAfterRpcTimeout, IN unsigned int InqAfterRpc, IN unsigned int InqAfterRpcTimeout ) /*++ Routine Description: Fitzgerald uses this routine to test the communications timeout management routines, RpcMgmtInqComTimeout and RpcMgmtSetComTimeout. Arguments: SetBeforeRpc - Supplies a flag which, if it is non-zero, indicates that the communications timeout should be set before making a remote procedure call. SetBeforeRpcTimeout - Supplies the timeout value to be set before making a remote procedure call. InqBeforeRpc - Supplies a flag which, if it is non-zero, indicates that the communications timeout should be inquired before making a remote procedure call. InqBeforeRpcTimeout - Supplies the expected timeout value to be inquired before making a remote procedure call. SetAfterRpc - Supplies a flag which, if it is non-zero, indicates that the communications timeout should be set after making a remote procedure call. SetAfterRpcTimeout - Supplies the timeout value to be set after making a remote procedure call. InqAfterRpc - Supplies a flag which, if it is non-zero, indicates that the communications timeout should be inquired after making a remote procedure call. InqAfterRpcTimeout - Supplies the expected timeout value to be inquired after making a remote procedure call. Return Value: Zero will be returned if all of the tests pass, otherwise, non-zero will be returned. --*/ { RPC_BINDING_HANDLE BindingHandle; unsigned int Timeout; Status = GetBinding(FREDRICK, &BindingHandle); if (Status) { ApiError("Fitzgerald","GetBinding",Status); PrintToConsole("Fitzgerald : FAIL - Unable to Bind"); PrintToConsole(" (Fredrick)"); return(1); } if (SetBeforeRpc != 0) { Status = RpcMgmtSetComTimeout(BindingHandle,SetBeforeRpcTimeout); if (Status) { ApiError("Fitzgerald","RpcMgmtSetComTimeout",Status); PrintToConsole("Fitzgerald : FAIL - Error in"); PrintToConsole(" RpcMgmtSetComTimeout\n"); return(1); } } if (InqBeforeRpc != 0) { Status = RpcMgmtInqComTimeout(BindingHandle,&Timeout); if (Status) { ApiError("Fitzgerald","RpcMgmtInqComTimeout",Status); PrintToConsole("Fitzgerald : FAIL - Error in"); PrintToConsole(" RpcMgmtInqComTimeout\n"); return(1); } if (Timeout != InqBeforeRpcTimeout) { PrintToConsole("Fitzgerald : FAIL - Timeout != "); PrintToConsole("InqBeforeRpcTimeout\n"); return(1); } } Helga(BindingHandle); if (HelgaErrors != 0) { PrintToConsole("Fitzgerald : FAIL - Error(s) in Helga Interface\n"); HelgaErrors = 0; return(1); } if (SetAfterRpc != 0) { Status = RpcMgmtSetComTimeout(BindingHandle,SetAfterRpcTimeout); if (Status) { ApiError("Fitzgerald","RpcMgmtSetComTimeout",Status); PrintToConsole("Fitzgerald : FAIL - Error in"); PrintToConsole(" RpcMgmtSetComTimeout\n"); return(1); } } if (InqAfterRpc != 0) { Status = RpcMgmtInqComTimeout(BindingHandle,&Timeout); if (Status) { ApiError("Fitzgerald","RpcMgmtInqComTimeout",Status); PrintToConsole("Fitzgerald : FAIL - Error in"); PrintToConsole(" RpcMgmtInqComTimeout\n"); return(1); } if (Timeout != InqAfterRpcTimeout) { PrintToConsole("Fitzgerald : FAIL - Timeout != "); PrintToConsole("InqAfterRpcTimeout\n"); return(1); } } Status = RpcBindingFree(&BindingHandle); if (Status) { ApiError("Fitzgerald","RpcBindingFree",Status); PrintToConsole("Fitzgerald : FAIL - Unable to Free Binding"); PrintToConsole(" (BindingHandle)\n"); return(1); } return(0); } int FitzgeraldTestFault ( void ) /*++ Routine Description: This routine will test that faults get propogated correctly from the server back to the client. Return Value: Zero will be returned if all of the tests pass, otherwise, non-zero will be returned. --*/ { RPC_BINDING_HANDLE ExceptionBinding; Status = GetBinding(FREDRICK, &ExceptionBinding); if (Status) { ApiError("Fitzgerald","GetBinding",Status); PrintToConsole("Fitzgerald : FAIL - Unable to Bind"); PrintToConsole(" (Fredrick)"); return(1); } Helga(ExceptionBinding); if (IsabelleRaiseException(ExceptionBinding, (unsigned char) ulSecurityPackage) != (unsigned char) ulSecurityPackage) { PrintToConsole("Fitzgerald : FAIL - Exception Not Raised\n"); return(1); } Helga(ExceptionBinding); if (HelgaErrors != 0) { PrintToConsole("Fitzgerald : FAIL - Error(s) in Helga Interface\n"); HelgaErrors = 0; return(1); } if (IsabelleErrors != 0) { PrintToConsole("Fitzgerald : FAIL - Error(s) in Isabelle"); PrintToConsole(" Interface\n"); IsabelleErrors = 0; return(1); } Status = RpcBindingFree(&ExceptionBinding); if (Status) { ApiError("Fitzgerald","RpcBindingFree",Status); PrintToConsole("Fitzgerald : FAIL - Unable to Free Binding"); PrintToConsole(" (ExceptionBinding)\n"); return(1); } return(0); } int FitzgeraldContextHandle ( ) { void PAPI * ContextHandle = 0; RPC_BINDING_HANDLE BindingHandle; unsigned long ContextUuid[5]; Status = GetBinding(FREDRICK, &BindingHandle); if (Status) { ApiError("Fitzgerald","GetBinding",Status); PrintToConsole("Fitzgerald : FAIL - Unable to Bind"); PrintToConsole(" (Fredrick)"); return(1); } Helga(BindingHandle); ContextUuid[0] = 0; ContextUuid[1] = 1; ContextUuid[2] = 2; ContextUuid[3] = 3; ContextUuid[4] = 4; NDRCContextUnmarshall(&ContextHandle, BindingHandle, ContextUuid, 0x00L | 0x10L | 0x0000L); Status = RpcBindingFree(&BindingHandle); if (Status) { ApiError("Fitzgerald","RpcBindingFree",Status); PrintToConsole("Fitzgerald : FAIL - Unable to Free Binding"); PrintToConsole(" (BindingHandle)\n"); return(1); } HelgaUsingContextHandle(ContextHandle); RpcSsDestroyClientContext(&ContextHandle); if ( ContextHandle != 0 ) { PrintToConsole("Fitzgerald : FAIL - ContextHandle != 0\n"); return(1); } return(0); } void Fitzgerald ( ) /*++ Routine Description: We verify all client side APIs in this routine. The idea is to emphasize complete coverage, rather than indepth coverage. Actually, when I say all client side APIs, I really mean all client side APIs except for security and name service. The following list is the APIs which will be tested by this routine. RpcBindingCopy RpcBindingFree RpcBindingFromStringBinding RpcBindingInqObject RpcBindingSetObject RpcBindingToStringBinding RpcStringBindingCompose RpcStringBindingParse RpcIfInqId RpcNetworkIsProtseqValid RpcMgmtInqComTimeout RpcMgmtSetComTimeout RpcStringFree UuidToString UuidFromString --*/ { RPC_BINDING_HANDLE IsabelleBinding; RPC_IF_ID RpcIfId; UUID Uuid; unsigned char PAPI * String; if ( NumberOfTestsRun++ ) { PauseExecution(TestDelay); } Synchro(FREDRICK) ; PrintToConsole("Fitzgerald : Verify All Client APIs\n"); if ( FitzgeraldContextHandle() != 0 ) { return; } // Test that the routines to convert UUIDs to and from strings work // correctly. GenerateUuidValue(3768,&Uuid); Status = UuidToStringA(&Uuid, &String); if (Status) { ApiError("Fitzgerald", "UuidToString", Status); PrintToConsole("Fitzgerald : FAIL - UuidToString\n"); return; } Status = UuidFromStringA(String, &Uuid); if (Status) { ApiError("Fitzgerald", "UuidFromString", Status); PrintToConsole("Fitzgerald : FAIL - UuidFromString\n"); return; } Status = RpcStringFreeA(&String); if (Status) { ApiError("Fitzgerald", "RpcStringFree", Status); PrintToConsole("Fitzgerald : FAIL - RpcStringFree\n"); return; } if ( CheckUuidValue(3768,&Uuid) != 0 ) { OtherError("Fitzgerald", "CheckUuidValue() != 0"); PrintToConsole("Fitzgerald : FAIL - CheckUuidValue() != 0\n"); return; } Status = UuidFromString(0, &Uuid); if (Status) { ApiError("Fitzgerald", "UuidFromString", Status); PrintToConsole("Fitzgerald : FAIL - UuidFromString\n"); return; } if ( ( Uuid.Data1 != 0 ) || ( Uuid.Data2 != 0 ) || ( Uuid.Data3 != 0 ) || ( Uuid.Data4[0] != 0 ) || ( Uuid.Data4[1] != 0 ) || ( Uuid.Data4[2] != 0 ) || ( Uuid.Data4[3] != 0 ) || ( Uuid.Data4[4] != 0 ) || ( Uuid.Data4[5] != 0 ) || ( Uuid.Data4[6] != 0 ) || ( Uuid.Data4[7] != 0 ) ) { OtherError("Fitzgerald", "Uuid != NIL UUID"); PrintToConsole("Fitzgerald : FAIL - Uuid != NIL UUID\n"); return; } // Test that a null protocol sequence causes RPC_S_INVALID_RPC_PROTSEQ // to be returned rather than RPC_S_PROTSEQ_NOT_SUPPORTED. Status = RpcBindingFromStringBindingA( (unsigned char PAPI *) ":[\\\\pipe\\\\endpoint]", &IsabelleBinding); if (Status != RPC_S_INVALID_RPC_PROTSEQ) { ApiError("Fitzgerald","RpcBindingFromStringBinding",Status); PrintToConsole("Fitzgerald : FAIL - RpcBindingFromStringBinding"); PrintToConsole(" did not fail with RPC_S_INVALID_RPC_PROTSEQ\n"); return; } Status = GetBinding(FREDRICK, &IsabelleBinding); if (Status) { ApiError("Fitzgerald","GetBinding",Status); PrintToConsole("Fitzgerald : FAIL - Unable to Bind"); PrintToConsole(" (Fredrick)"); return; } Status = RpcNsBindingInqEntryNameA(IsabelleBinding, RPC_C_NS_SYNTAX_DCE, &String); if ( Status != RPC_S_NO_ENTRY_NAME ) { ApiError("Fitzgerald","RpcNsBindingInqEntryName",Status); PrintToConsole("Fitzgerald : FAIL - RpcNsBindingInqEntryName"); PrintToConsole(" Did Not Fail"); return; } // This routine will test RpcStringBindingCompose, // RpcStringBindingParse, RpcStringFree for us. if (FitzgeraldComposeAndParse()) return; // We test RpcBindingCopy here. if (FitzgeraldBindingCopy()) return; // This particular routine gets to test RpcBindingToStringBinding, // RpcBindingInqObject, and RpcBindingSetObject. if (FitzgeraldStringBindingAndObject()) return; if (FitzgeraldComTimeout(0,0,1,RPC_C_BINDING_DEFAULT_TIMEOUT, 0,0,1,RPC_C_BINDING_DEFAULT_TIMEOUT)) return; if (FitzgeraldComTimeout(1,RPC_C_BINDING_MAX_TIMEOUT, 1,RPC_C_BINDING_MAX_TIMEOUT,0,0,1,RPC_C_BINDING_MAX_TIMEOUT)) return; if (FitzgeraldComTimeout(0,0,0,0,1,RPC_C_BINDING_MAX_TIMEOUT, 1,RPC_C_BINDING_MAX_TIMEOUT)) return; // We need to test faults. This is done by this routine. if (FitzgeraldTestFault()) return; Status = RpcBindingSetObject(IsabelleBinding, 0); if (Status) { ApiError("Fitzgerald", "RpcBindingSetObject", Status); PrintToConsole("Fitzgerald : FAIL - Unable to Set Object\n"); return; } IsabelleShutdown(IsabelleBinding); if (IsabelleErrors != 0) { PrintToConsole("Fitzgerald : FAIL - Error(s) in Isabelle"); PrintToConsole(" Interface\n"); IsabelleErrors = 0; return; } Status = RpcBindingFree(&IsabelleBinding); if (Status) { ApiError("Fitzgerald","RpcBindingFree",Status); PrintToConsole("Fitzgerald : FAIL - Unable to Free Binding"); PrintToConsole(" (IsabelleBinding)\n"); return; } Status = RpcIfInqId((RPC_IF_HANDLE) &IsabelleInterfaceInformation, &RpcIfId); if (Status) { ApiError("Fitzgerald","RpcIfInqId",Status); PrintToConsole("Fitzgerald : FAIL - Error in RpcIfInqId\n"); return; } if ( (RpcIfId.VersMajor != 1) || (RpcIfId.VersMinor != 1) || (RpcIfId.Uuid.Data1 != 9) || (RpcIfId.Uuid.Data2 != 8) || (RpcIfId.Uuid.Data3 != 8) || (RpcIfId.Uuid.Data4[0] != 7) || (RpcIfId.Uuid.Data4[1] != 7) || (RpcIfId.Uuid.Data4[2] != 7) || (RpcIfId.Uuid.Data4[3] != 7) || (RpcIfId.Uuid.Data4[4] != 7) || (RpcIfId.Uuid.Data4[5] != 7) || (RpcIfId.Uuid.Data4[6] != 7) || (RpcIfId.Uuid.Data4[7] != 7)) { PrintToConsole("Fitzgerald : FAIL - Wrong RpcIfId\n"); return; } Status = RpcNetworkIsProtseqValidA((unsigned char *) "ncacn_np"); if (Status) { ApiError("Fitzgerald","RpcNetworkIsProtseqValid",Status); PrintToConsole("Fitzgerald : FAIL - RpcNetworkIsProtseqValid"); PrintToConsole(" Failed\n"); return; } Status = RpcNetworkIsProtseqValidA((unsigned char *) "nope_np"); if (Status != RPC_S_INVALID_RPC_PROTSEQ) { PrintToConsole("Fitzgerald : FAIL - RpcNetworkIsProtseqValid"); PrintToConsole(" != RPC_S_INVALID_RPC_PROTSEQ\n"); return; } Status = RpcNetworkIsProtseqValidA((unsigned char *) "ncacn_fail"); if (Status != RPC_S_PROTSEQ_NOT_SUPPORTED) { PrintToConsole("Fitzgerald : FAIL - RpcNetworkIsProtseqValid"); PrintToConsole(" != RPC_S_PROTSEQ_NOT_SUPPORTED\n"); return; } PrintToConsole("Fitzgerald : PASS\n"); } void Charles ( ) /*++ Routine Description: This routine works with Christopher in usvr.exe to test all server APIs (all except security and name service APIs). --*/ { RPC_BINDING_HANDLE ChristopherBinding; RPC_BINDING_HANDLE ChristopherHelgaBinding; RPC_BINDING_HANDLE ChristopherIsabelleBinding; RPC_BINDING_HANDLE ChristopherHelgaNoEndpoint; UUID ObjectUuid; if ( NumberOfTestsRun++ ) { PauseExecution(30000); } Synchro(CHRISTOPHER) ; PrintToConsole("Charles : Verify All Server APIs\n"); Status = GetBinding(CHRISTOPHER, &ChristopherBinding); if (Status) { ApiError("Charles","GetBinding",Status); PrintToConsole("Charles : FAIL - Unable to Bind "); PrintToConsole("(Christopher)\n"); return; } GenerateUuidValue(288, &ObjectUuid); Status = RpcBindingSetObject(ChristopherBinding, &ObjectUuid); if (Status) { ApiError("Charles", "RpcBindingSetObject", Status); PrintToConsole("Charles : FAIL - Unable to Set Object\n"); return; } Status = GetBinding(CHRISTOPHERHELGA, &ChristopherHelgaBinding); if (Status) { ApiError("Charles","GetBinding",Status); PrintToConsole("Charles : FAIL - Unable to Bind "); PrintToConsole("(ChristopherHelga)\n"); return; } GenerateUuidValue(288, &ObjectUuid); Status = RpcBindingSetObject(ChristopherHelgaBinding, &ObjectUuid); if (Status) { ApiError("Charles", "RpcBindingSetObject", Status); PrintToConsole("Charles : FAIL - Unable to Set Object\n"); return; } Status = GetBinding(CHRISTOPHERISABELLE, &ChristopherIsabelleBinding); if (Status) { ApiError("Charles","GetBinding",Status); PrintToConsole("Charles : FAIL - Unable to Bind "); PrintToConsole("(ChristopherIsabelle)\n"); return; } GenerateUuidValue(288, &ObjectUuid); Status = RpcBindingSetObject(ChristopherIsabelleBinding, &ObjectUuid); if (Status) { ApiError("Charles", "RpcBindingSetObject", Status); PrintToConsole("Charles : FAIL - Unable to Set Object\n"); return; } Status = GetBinding(NOENDPOINT, &ChristopherHelgaNoEndpoint); if (Status) { ApiError("Charles","GetBinding",Status); PrintToConsole("Charles : FAIL - Unable to Bind "); PrintToConsole("(ChristopherHelgaNoEndpoint)\n"); return; } GenerateUuidValue(288, &ObjectUuid); Status = RpcBindingSetObject(ChristopherHelgaNoEndpoint, &ObjectUuid); if (Status) { ApiError("Charles", "RpcBindingSetObject", Status); PrintToConsole("Charles : FAIL - Unable to Set Object\n"); return; } SylviaBinding = ChristopherBinding; if (SylviaCall(ChristopherBinding,10,5,0) != LocalSylviaCall(10,5,0)) { PrintToConsole("Charles : FAIL - Incorrect result from"); PrintToConsole(" SylviaCall(10,5,0)\n"); return; } SylviaBinding = ChristopherHelgaBinding; if (SylviaCall(ChristopherHelgaBinding,10,5,0) != LocalSylviaCall(10,5,0)) { PrintToConsole("Charles : FAIL - Incorrect result from"); PrintToConsole(" SylviaCall(10,5,0)\n"); return; } SylviaBinding = ChristopherIsabelleBinding; if (SylviaCall(ChristopherIsabelleBinding,10,5,0) != LocalSylviaCall(10,5,0)) { PrintToConsole("Charles : FAIL - Incorrect result from"); PrintToConsole(" SylviaCall(10,5,0)\n"); return; } IsabelleToStringBinding(ChristopherBinding); IsabelleToStringBinding(ChristopherIsabelleBinding); IsabelleToStringBinding(ChristopherHelgaBinding); TestHelgaInterface(ChristopherHelgaNoEndpoint, HelgaMaxSize); Status = RpcBindingReset(ChristopherHelgaNoEndpoint); if (Status) { ApiError("Charles", "RpcBindingReset", Status); PrintToConsole("Charles : FAIL - Unable to Reset"); PrintToConsole(" (ChristopherHelgaNoEndpoint)\n"); return; } Helga(ChristopherHelgaNoEndpoint); Status = RpcBindingReset(ChristopherHelgaNoEndpoint); if (Status) { ApiError("Charles", "RpcBindingReset", Status); PrintToConsole("Charles : FAIL - Unable to Reset"); PrintToConsole(" (ChristopherHelgaNoEndpoint)\n"); return; } Helga(ChristopherHelgaNoEndpoint); Status = RpcBindingReset(ChristopherHelgaNoEndpoint); if (Status) { ApiError("Charles", "RpcBindingReset", Status); PrintToConsole("Charles : FAIL - Unable to Reset"); PrintToConsole(" (ChristopherHelgaNoEndpoint)\n"); return; } IsabelleShutdown(ChristopherBinding); // We need an extra delay in here because Christopher performs some // other tests after RpcServerListen returns. PauseExecution(LONG_TESTDELAY); if (HelgaErrors != 0) { PrintToConsole("Charles : FAIL - Error(s) in Helga Interface\n"); HelgaErrors = 0; return; } if (IsabelleErrors != 0) { PrintToConsole("Charles : FAIL - Error(s) in Isabelle Interface\n"); IsabelleErrors = 0; return; } if (SylviaErrors != 0) { PrintToConsole("Charles : FAIL - Error(s) in Sylvia Interface\n"); SylviaErrors = 0; return; } Status = RpcBindingFree(&ChristopherHelgaBinding); if (Status) { ApiError("Charles","RpcBindingFree",Status); PrintToConsole("Charles : FAIL - Unable to Free Binding"); PrintToConsole(" (ChristopherHelgaBinding)\n"); return; } Status = RpcBindingFree(&ChristopherBinding); if (Status) { ApiError("Charles","RpcBindingFree",Status); PrintToConsole("Charles : FAIL - Unable to Free Binding"); PrintToConsole(" (ChristopherBinding)\n"); return; } Status = RpcBindingFree(&ChristopherHelgaNoEndpoint); if (Status) { ApiError("Charles","RpcBindingFree",Status); PrintToConsole("Charles : FAIL - Unable to Free Binding"); PrintToConsole(" (ChristopherHelgaNoEndpoint)\n"); return; } Status = RpcBindingFree(&ChristopherIsabelleBinding); if (Status) { ApiError("Charles","RpcBindingFree",Status); PrintToConsole("Charles : FAIL - Unable to Free Binding"); PrintToConsole(" (ChristopherIsabelleBinding)\n"); return; } PrintToConsole("Charles : PASS\n"); } int ThomasNtSecurity ( IN char * NetworkOptions ) /*++ Routine Description: Thomas uses this routine to test NT security and RPC. Arguments: NetworkOptions - Supplies the network options to be used for the binding. Return Value: Zero will be returned if the test completes successfully, otherwise, non-zero will be returned. --*/ { RPC_BINDING_HANDLE ThomasNormalBinding; Status = RpcBindingFromStringBindingA( GetStringBinding(TYLER,0,(unsigned char *) NetworkOptions), &ThomasNormalBinding); if (Status) { ApiError("Thomas","RpcBindingFromStringBinding",Status); PrintToConsole("Thomas : FAIL - Unable to Bind (Tyler)\n"); return(1); } IsabelleNtSecurity(ThomasNormalBinding, strlen((char *) NetworkOptions) + 1, NetworkOptions); if (IsabelleErrors != 0) { PrintToConsole("Thomas : FAIL - Error(s) in Isabelle Interface\n"); IsabelleErrors = 0; return(1); } Status = RpcBindingFree(&ThomasNormalBinding); if (Status) { ApiError("Thomas","RpcBindingFree",Status); PrintToConsole("Thomas : FAIL - Unable to Free Binding"); PrintToConsole(" (ThomasNormalBinding)\n"); return(1); } return(0); } int ThomasTestNtSecurity ( ) /*++ Routine Description: This helper routine tests NT security (such as over named pipes and lpc). Return Value: A non-zero return value indicates that the test failed. --*/ { if (ThomasNtSecurity("") != 0) return(1); if (ThomasNtSecurity("Security=Identification Dynamic True") != 0) return(1); if (ThomasNtSecurity("Security=Identification Static True") != 0) return(1); if (ThomasNtSecurity("Security=Identification Dynamic False") != 0) return(1); if (ThomasNtSecurity("Security=Identification Static False") != 0) return(1); if (ThomasNtSecurity("Security=Anonymous Dynamic True") != 0) return(1); if (ThomasNtSecurity("Security=Anonymous Static True") != 0) return(1); if (ThomasNtSecurity("Security=Anonymous Dynamic False") != 0) return(1); if (ThomasNtSecurity("Security=Anonymous Static False") != 0) return(1); if (ThomasNtSecurity("Security=Impersonation Dynamic True") != 0) return(1); if (ThomasNtSecurity("Security=Impersonation Static True") != 0) return(1); if (ThomasNtSecurity("Security=Impersonation Dynamic False") != 0) return(1); if (ThomasNtSecurity("Security=Impersonation Static False") != 0) return(1); return(0); } int ThomasInqSetAuthInfo ( IN unsigned char PAPI * ServerPrincName, IN unsigned long AuthnLevel, IN unsigned long AuthnSvc, IN RPC_AUTH_IDENTITY_HANDLE AuthIdentity, IN unsigned long AuthzSvc, IN RPC_STATUS ExpectedResult, IN unsigned long ExpectedAuthnLevel ) /*++ Routine Description: We test RpcBindingSetAuthInfo and RpcBindingInqAuthInfo in this routine. Arguments: ServerPrincName - Supplies the server principal name to use. AuthnLevel - Supplies the authentication level to use. AuthnSvc - Supplies the authentication service to use. AuthIdentity - Supplies the security context to use. AuthzSvc - Supplies the authorization service to use. ExpectedResult - Supplies the result expected from RpcBindingSetAuthInfo. ExpectedAuthnLevel - Supplies the expected authentication level to be obtained from RpcBindingSetAuthInfo. Return Value: A non-zero result indicates that the test failed. --*/ { RPC_BINDING_HANDLE BindingHandle; unsigned long AuthenticationLevel; unsigned long AuthenticationService; unsigned long AuthorizationService; unsigned char IgnoreString[4]; Status = GetBinding(TYLER, &BindingHandle); if (Status) { ApiError("Thomas", "GetBinding", Status); PrintToConsole("Thomas : FAIL - Unable to Bind (Tyler)\n"); return(1); } if (gPrincName) { ServerPrincName = (unsigned char *)gPrincName; } Status = RpcBindingSetAuthInfoA(BindingHandle, ServerPrincName, AuthnLevel, AuthnSvc, AuthIdentity, AuthzSvc); if ( Status != ExpectedResult ) { ApiError("Thomas", "RpcBindingSetAuthInfo", Status); PrintToConsole("Thomas : FAIL - RpcBindingSetAuthInfo, Unexpected"); PrintToConsole(" Result\n"); return(1); } if (Status) { return(0); } Status = RpcBindingInqAuthInfo(BindingHandle, 0, &AuthenticationLevel, &AuthenticationService, 0, &AuthorizationService); if (Status) { ApiError("Thomas", "RpcBindingInqAuthInfo", Status); PrintToConsole("Thomas : FAIL - RpcBindingInqAuthInfo\n"); return(1); } if ( AuthenticationLevel != ExpectedAuthnLevel ) { PrintToConsole("Thomas : WARNING - "); PrintToConsole("AuthenticationLevel != ExpectedAuthnLevel\n"); } if ( AuthenticationService != AuthnSvc ) { OtherError("Thomas", "AuthenticationService != AuthnSvc"); PrintToConsole("Thomas : FAIL - RpcBindingInqAuthInfo\n"); return(1); } if ( AuthorizationService != AuthzSvc ) { OtherError("Thomas", "AuthorizationService != AuthzSvc"); PrintToConsole("Thomas : FAIL - RpcBindingInqAuthInfo\n"); return(1); } TestHelgaInterface(BindingHandle, HelgaMaxSize); IsabelleNtSecurity(BindingHandle, 1, IgnoreString); Status = RpcBindingFree(&BindingHandle); if (Status) { ApiError("Thomas","RpcBindingFree",Status); PrintToConsole("Thomas : FAIL - Unable to Free Binding"); PrintToConsole(" (BindingHandle)\n"); return(1); } return(0); } int ThomasTestRpcSecurity (BOOL fServerIsNTSystem ) /*++ Routine Description: This routine exercises rpc protocol level security support in the runtime. Return Value: A non-zero return value indicates that the test failed. --*/ { RPC_AUTH_IDENTITY_HANDLE AuthId = NULL; OSVERSIONINFO versionInfo; if(ulSecurityPackage == 123) AuthId = 0 ; // if platform is Win98 and transport is MSMQ, no point of doing security tests // Falcon will try to upgrade connection level authentication to packet, which in turn // will be rejected by the security system. The only possible connection is not authenticated if (TransportType == RPC_TRANSPORT_MSMQ) { memset(&versionInfo, 0, sizeof(versionInfo)); versionInfo.dwOSVersionInfoSize = sizeof(versionInfo); GetVersionEx(&versionInfo); if (versionInfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) return 0; } if ( ThomasInqSetAuthInfo((unsigned char PAPI *) "ServerPrincipal", RPC_C_AUTHN_LEVEL_CONNECT, ulSecurityPackage, AuthId , 0, RPC_S_OK, RPC_C_AUTHN_LEVEL_CONNECT) != 0 ) { return(1); } if(ulSecurityPackage == 123) { if ( ThomasInqSetAuthInfo(0, RPC_C_AUTHN_LEVEL_CONNECT, ulSecurityPackage, (RPC_AUTH_IDENTITY_HANDLE) RPC_CONST_STRING("ClientPrincipal"), 0, RPC_S_OK, RPC_C_AUTHN_LEVEL_CONNECT) != 0 ) { return(1); } } if (!fServerIsNTSystem) return 0; if ( ThomasInqSetAuthInfo((unsigned char PAPI *) "ServerPrincipal", RPC_C_AUTHN_LEVEL_CALL, ulSecurityPackage, AuthId, 0, RPC_S_OK, RPC_C_AUTHN_LEVEL_PKT) != 0 ) { return(1); } if(ulSecurityPackage == 123) { if ( ThomasInqSetAuthInfo(0, RPC_C_AUTHN_LEVEL_CALL, ulSecurityPackage, (RPC_AUTH_IDENTITY_HANDLE) RPC_CONST_STRING("ClientPrincipal"), 0, RPC_S_OK, RPC_C_AUTHN_LEVEL_PKT) != 0 ) { return(1); } } if ( ThomasInqSetAuthInfo((unsigned char PAPI *) "ServerPrincipal", RPC_C_AUTHN_LEVEL_PKT, ulSecurityPackage, AuthId, 0, RPC_S_OK, RPC_C_AUTHN_LEVEL_PKT) != 0 ) { return(1); } if(ulSecurityPackage == 123) { if ( ThomasInqSetAuthInfo(0, RPC_C_AUTHN_LEVEL_PKT, ulSecurityPackage, (RPC_AUTH_IDENTITY_HANDLE) RPC_CONST_STRING("ClientPrincipal"), 0, RPC_S_OK, RPC_C_AUTHN_LEVEL_PKT) != 0 ) { return(1); } } if ( ThomasInqSetAuthInfo((unsigned char PAPI *) "ServerPrincipal", RPC_C_AUTHN_LEVEL_PKT_INTEGRITY, ulSecurityPackage, AuthId, 0, RPC_S_OK, RPC_C_AUTHN_LEVEL_PKT_INTEGRITY) != 0 ) { return(1); } if(ulSecurityPackage == 123) { if ( ThomasInqSetAuthInfo(0, RPC_C_AUTHN_LEVEL_PKT_INTEGRITY, ulSecurityPackage, (RPC_AUTH_IDENTITY_HANDLE) RPC_CONST_STRING("ClientPrincipal"), 0, RPC_S_OK, RPC_C_AUTHN_LEVEL_PKT_INTEGRITY) != 0 ) { return(1); } } if ( ThomasInqSetAuthInfo((unsigned char PAPI *) "ServerPrincipal", RPC_C_AUTHN_LEVEL_PKT_PRIVACY, ulSecurityPackage, AuthId , 0, RPC_S_OK, RPC_C_AUTHN_LEVEL_PKT_PRIVACY) != 0 ) { return(1); } if(ulSecurityPackage == 123) { if ( ThomasInqSetAuthInfo(0, RPC_C_AUTHN_LEVEL_PKT_PRIVACY, ulSecurityPackage, (RPC_AUTH_IDENTITY_HANDLE) RPC_CONST_STRING("ClientPrincipal"), 0, RPC_S_OK, RPC_C_AUTHN_LEVEL_PKT_PRIVACY) != 0 ) { return(1); } } return(0); } #ifdef WIN32RPC int ThomasTestLRpcSecurity ( ) /*++ Routine Description: This routine exercises rpc protocol level security support in the runtime. Return Value: A non-zero return value indicates that the test failed. --*/ { SEC_WINNT_AUTH_IDENTITY ntssp; RPC_AUTH_IDENTITY_HANDLE AuthId = &ntssp; ntssp.User = (RPC_CHAR *) SecurityUser; if (ntssp.User) { ntssp.UserLength = lstrlen((const RPC_SCHAR *) SecurityUser); } else { ntssp.UserLength = 0; } ntssp.Domain = (RPC_CHAR *) SecurityDomain; if (ntssp.Domain) { ntssp.DomainLength = lstrlen((const RPC_SCHAR *) SecurityDomain); } else { ntssp.DomainLength = 0; } ntssp.Password = (RPC_CHAR *) SecurityPassword; if (ntssp.Password) { ntssp.PasswordLength = lstrlen((const RPC_SCHAR *) SecurityPassword); } else { ntssp.PasswordLength = 0; } ntssp.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI; // LRPC can only use 10 ulSecurityPackage = 10 ; unsigned long size = 256; char UserName[256]; char Tmp[256]; // // hack // strcpy(UserName, "redmond\\"); if (GetUserNameA(Tmp, &size) == 0) { return (1); } strcat(UserName, Tmp); if ( ThomasInqSetAuthInfo((unsigned char PAPI *) UserName, RPC_C_AUTHN_LEVEL_CONNECT, ulSecurityPackage, AuthId , 0, RPC_S_OK, RPC_C_AUTHN_LEVEL_PKT_PRIVACY) != 0 ) { return(1); } if ( ThomasInqSetAuthInfo(0, RPC_C_AUTHN_LEVEL_CONNECT, ulSecurityPackage, (RPC_AUTH_IDENTITY_HANDLE) RPC_CONST_STRING("ClientPrincipal"), 0, RPC_S_OK, RPC_C_AUTHN_LEVEL_PKT_PRIVACY) != 0 ) { return(1); } if ( ThomasInqSetAuthInfo((unsigned char PAPI *) UserName, RPC_C_AUTHN_LEVEL_CALL, ulSecurityPackage, AuthId, 0, RPC_S_OK, RPC_C_AUTHN_LEVEL_PKT_PRIVACY) != 0 ) { return(1); } if ( ThomasInqSetAuthInfo(0, RPC_C_AUTHN_LEVEL_CALL, ulSecurityPackage, (RPC_AUTH_IDENTITY_HANDLE) RPC_CONST_STRING("ClientPrincipal"), 0, RPC_S_OK, RPC_C_AUTHN_LEVEL_PKT_PRIVACY) != 0 ) { return(1); } if ( ThomasInqSetAuthInfo((unsigned char PAPI *) UserName, RPC_C_AUTHN_LEVEL_PKT, ulSecurityPackage, AuthId, 0, RPC_S_OK, RPC_C_AUTHN_LEVEL_PKT_PRIVACY) != 0 ) { return(1); } if ( ThomasInqSetAuthInfo(0, RPC_C_AUTHN_LEVEL_PKT, ulSecurityPackage, (RPC_AUTH_IDENTITY_HANDLE) RPC_CONST_STRING("ClientPrincipal"), 0, RPC_S_OK, RPC_C_AUTHN_LEVEL_PKT_PRIVACY) != 0 ) { return(1); } if ( ThomasInqSetAuthInfo((unsigned char PAPI *) UserName, RPC_C_AUTHN_LEVEL_PKT_INTEGRITY, ulSecurityPackage, AuthId, 0, RPC_S_OK, RPC_C_AUTHN_LEVEL_PKT_PRIVACY) != 0 ) { return(1); } if ( ThomasInqSetAuthInfo(0, RPC_C_AUTHN_LEVEL_PKT_INTEGRITY, ulSecurityPackage, (RPC_AUTH_IDENTITY_HANDLE) RPC_CONST_STRING("ClientPrincipal"), 0, RPC_S_OK, RPC_C_AUTHN_LEVEL_PKT_PRIVACY) != 0 ) { return(1); } if ( ThomasInqSetAuthInfo((unsigned char PAPI *) UserName, RPC_C_AUTHN_LEVEL_PKT_PRIVACY, ulSecurityPackage, AuthId , 0, RPC_S_OK, RPC_C_AUTHN_LEVEL_PKT_PRIVACY) != 0 ) { return(1); } if ( ThomasInqSetAuthInfo(0, RPC_C_AUTHN_LEVEL_PKT_PRIVACY, ulSecurityPackage, (RPC_AUTH_IDENTITY_HANDLE) RPC_CONST_STRING("ClientPrincipal"), 0, RPC_S_OK, RPC_C_AUTHN_LEVEL_PKT_PRIVACY) != 0 ) { return(1); } return(0); } #endif void Thomas ( ) /*++ Routine Description: This routine is used to test security, both at the transport level, and at the RPC level. We work with Tyler in usvr.exe. --*/ { RPC_BINDING_HANDLE IsabelleBinding; BOOL fServerIsNTSystem; Synchro(TYLER) ; if ( NumberOfTestsRun++ ) { PauseExecution(TestDelay); } PrintToConsole("Thomas : Test Security\n"); Status = GetBinding(TYLER, &IsabelleBinding); if (Status) { ApiError("Thomas","GetBinding",Status); PrintToConsole("Thomas : FAIL - Unable to Bind (Tyler)\n"); return; } fServerIsNTSystem = IsServerNTSystem(IsabelleBinding); // change here to test rpc security for LRPC also if(TransportType != RPC_LRPC) { if ( ThomasTestRpcSecurity(fServerIsNTSystem) != 0 ) { return; } } if ( TransportType == RPC_TRANSPORT_NAMEPIPE || TransportType == RPC_LRPC ) { if ( ThomasTestNtSecurity() != 0 ) { return; } } IsabelleShutdown(IsabelleBinding); if (IsabelleErrors != 0) { PrintToConsole("Thomas : FAIL - Error(s) in Isabelle Interface\n"); IsabelleErrors = 0; return; } Status = RpcBindingFree(&IsabelleBinding); if (Status) { ApiError("Thomas","RpcBindingFree",Status); PrintToConsole("Thomas : FAIL - Unable to Free Binding"); PrintToConsole(" (IsabelleBinding)\n"); return; } PrintToConsole("Thomas : PASS\n"); } int TimInqSetAuthInfo ( IN unsigned char PAPI * ServerPrincName, IN unsigned long AuthnLevel, IN unsigned long AuthnSvc, IN RPC_AUTH_IDENTITY_HANDLE AuthIdentity, IN unsigned long AuthzSvc, IN RPC_STATUS ExpectedResult, IN unsigned long ExpectedAuthnLevel ) /*++ Routine Description: We test RpcBindingSetAuthInfo and RpcBindingInqAuthInfo in this routine. Arguments: ServerPrincName - Supplies the server principal name to use. AuthnLevel - Supplies the authentication level to use. AuthnSvc - Supplies the authentication service to use. AuthIdentity - Supplies the security context to use. AuthzSvc - Supplies the authorization service to use. ExpectedResult - Supplies the result expected from RpcBindingSetAuthInfo. ExpectedAuthnLevel - Supplies the expected authentication level to be obtained from RpcBindingSetAuthInfo. Return Value: A non-zero result indicates that the test failed. --*/ { RPC_BINDING_HANDLE BindingHandle; unsigned long AuthenticationLevel; unsigned long AuthenticationService; unsigned long AuthorizationService; unsigned char IgnoreString[4]; Status = GetBinding(TYLER, &BindingHandle); if (Status) { ApiError("Tim", "GetBinding", Status); PrintToConsole("Tim : FAIL - Unable to Bind (Tyler)\n"); return(1); } Status = RpcBindingSetAuthInfoA(BindingHandle, ServerPrincName, AuthnLevel, AuthnSvc, AuthIdentity, AuthzSvc); if ( Status != ExpectedResult ) { ApiError("Tim", "RpcBindingSetAuthInfo", Status); PrintToConsole("Tim : FAIL - RpcBindingSetAuthInfo, Unexpected"); PrintToConsole(" Result\n"); return(1); } if (Status) { return(0); } Status = RpcBindingInqAuthInfo(BindingHandle, 0, &AuthenticationLevel, &AuthenticationService, 0, &AuthorizationService); if (Status) { ApiError("Tim", "RpcBindingInqAuthInfo", Status); PrintToConsole("Tim : FAIL - RpcBindingInqAuthInfo\n"); return(1); } if ( AuthenticationLevel != ExpectedAuthnLevel ) { PrintToConsole("Tim : WARNING - "); PrintToConsole("AuthenticationLevel != ExpectedAuthnLevel\n"); } if ( AuthenticationService != AuthnSvc ) { OtherError("Tim", "AuthenticationService != AuthnSvc"); PrintToConsole("Tim : FAIL - RpcBindingInqAuthInfo\n"); return(1); } if ( AuthorizationService != AuthzSvc ) { OtherError("Tim", "AuthorizationService != AuthzSvc"); PrintToConsole("Tim : FAIL - RpcBindingInqAuthInfo\n"); return(1); } TestHelgaInterface(BindingHandle, HelgaMaxSize); IsabelleNtSecurity(BindingHandle, 1, IgnoreString); Status = RpcBindingFree(&BindingHandle); if (Status) { ApiError("Tim","RpcBindingFree",Status); PrintToConsole("Tim : FAIL - Unable to Free Binding"); PrintToConsole(" (BindingHandle)\n"); return(1); } return(0); } int TimTestRpcSecurity ( ) /*++ Routine Description: This routine exercises rpc protocol level security support in the runtime. Return Value: A non-zero return value indicates that the test failed. --*/ { RPC_AUTH_IDENTITY_HANDLE AuthId = NULL; // RPC_C_AUTHN_WINNT to ulSecurityPackage in the intrest of generality if ( TimInqSetAuthInfo((unsigned char PAPI *) "ServerPrincipal", RPC_C_AUTHN_LEVEL_CONNECT, ulSecurityPackage, AuthId, 0, RPC_S_OK, RPC_C_AUTHN_LEVEL_CONNECT) != 0 ) { return(1); } // RPC_C_AUTHN_WINNT to ulSecurityPackage in the intrest of generality if ( TimInqSetAuthInfo(0, RPC_C_AUTHN_LEVEL_CONNECT, ulSecurityPackage, AuthId, 0, RPC_S_OK, RPC_C_AUTHN_LEVEL_CONNECT) != 0 ) { return(1); } return(0); } void Tim ( ) /*++ Routine Description: This routine is used to test security, both at the transport level, and at the RPC level. We work with Terry in usvr.exe. --*/ { RPC_BINDING_HANDLE IsabelleBinding; Synchro(TYLER) ; if ( NumberOfTestsRun++ ) { PauseExecution(TestDelay); } PrintToConsole("Tim : Test Security\n"); Status = GetBinding(TYLER, &IsabelleBinding); if (Status) { ApiError("Tim","GetBinding",Status); PrintToConsole("Tim : FAIL - Unable to Bind (Tyler)\n"); return; } if ( TransportType != RPC_LRPC ) { if ( TimTestRpcSecurity() != 0 ) { return; } } IsabelleShutdown(IsabelleBinding); if (IsabelleErrors != 0) { PrintToConsole("Tim : FAIL - Error(s) in Isabelle Interface\n"); IsabelleErrors = 0; return; } Status = RpcBindingFree(&IsabelleBinding); if (Status) { ApiError("Tim","RpcBindingFree",Status); PrintToConsole("Tim : FAIL - Unable to Free Binding"); PrintToConsole(" (IsabelleBinding)\n"); return; } PrintToConsole("Tim : PASS\n"); } void Robert ( ) /*++ Routine Description: Robert works with Richard (in usvr.cxx) to test call and callback failures. --*/ { RPC_BINDING_HANDLE RichardBinding; RPC_BINDING_HANDLE RichardHelperBinding; unsigned int RetryCount; Synchro(RICHARD) ; if ( NumberOfTestsRun++ ) { PauseExecution(TestDelay); } PrintToConsole("Robert : Test Call and Callback Failures\n"); Status = GetBinding(RICHARD, &RichardBinding); if (Status) { ApiError("Robert","GetBinding",Status); PrintToConsole("Robert : FAIL - Unable to Bind (Richard)\n"); return; } Status = GetBinding(RICHARDHELPER, &RichardHelperBinding); if (Status) { ApiError("Robert","GetBinding",Status); PrintToConsole("Robert : FAIL - Unable to Bind (RichardHelper)\n"); return; } Status = IsabelleRichardHelper(RichardBinding,RICHARDHELPER_EXECUTE); if (Status != RPC_S_OK) { ApiError("Robert","IsabelleRichardHelper",Status); PrintToConsole("Robert : FAIL - "); PrintToConsole("IsabelleRichardHelper(RICHARDHELPER_EXECUTE)\n"); return; } // PauseExecution(30000L); Synchro(RICHARDHELPER) ; for (RetryCount = 0; RetryCount < RETRYCOUNT; RetryCount++) { Status = IsabelleRichardHelper(RichardHelperBinding, RICHARDHELPER_IGNORE); if (Status == RPC_S_OK) break; PauseExecution(RETRYDELAY); } if (Status != RPC_S_OK) { ApiError("Robert","IsabelleRichardHelper",Status); PrintToConsole("Robert : FAIL - "); PrintToConsole("IsabelleRichardHelper(RICHARDHELPER_IGNORE)\n"); return; } Status = IsabelleRichardHelper(RichardHelperBinding, RICHARDHELPER_EXIT); if (Status == RPC_S_OK) { PrintToConsole("Robert : FAIL - "); PrintToConsole("IsabelleRichardHelper(RICHARDHELPER_EXIT) "); PrintToConsole("Succeeded\n"); return; } if (Status != RPC_S_CALL_FAILED) { PrintToConsole("Robert : WARN - "); PrintToConsole("IsabelleRichardHelper(RICHARDHELPER_EXIT) != "); PrintToConsole("RPC_S_CALL_FAILED\n"); } PauseExecution(TestDelay); Status = IsabelleRichardHelper(RichardHelperBinding,RICHARDHELPER_IGNORE); if (Status == RPC_S_OK) { PrintToConsole("Robert : FAIL - "); PrintToConsole("IsabelleRichardHelper(RICHARDHELPER_IGNORE) "); PrintToConsole("Succeeded\n"); return; } PrintToConsole("Robert : Spawning RichardHelper again\n") ; Status = IsabelleRichardHelper(RichardBinding,RICHARDHELPER_EXECUTE); if (Status != RPC_S_OK) { ApiError("Robert","IsabelleRichardHelper",Status); PrintToConsole("Robert : FAIL - "); PrintToConsole("IsabelleRichardHelper(RICHARDHELPER_EXECUTE)\n"); return; } // PauseExecution(30000L); Synchro(RICHARDHELPER) ; for (RetryCount = 0; RetryCount < RETRYCOUNT; RetryCount++) { Status = IsabelleRichardHelper(RichardHelperBinding, RICHARDHELPER_IGNORE); if (Status == RPC_S_OK) break; PauseExecution(RETRYDELAY); } if (Status != RPC_S_OK) { ApiError("Robert","IsabelleRichardHelper",Status); PrintToConsole("Robert : FAIL - "); PrintToConsole("IsabelleRichardHelper(RICHARDHELPER_IGNORE)\n"); return; } IsabelleShutdown(RichardHelperBinding); IsabelleShutdown(RichardBinding); if (IsabelleErrors != 0) { PrintToConsole("Robert : FAIL - Error(s) in Isabelle Interface\n"); IsabelleErrors = 0; return; } Status = RpcBindingFree(&RichardBinding); if (Status) { ApiError("Robert","RpcBindingFree",Status); PrintToConsole("Robert : FAIL - Unable to Free Binding"); PrintToConsole(" (RichardBinding)\n"); return; } Status = RpcBindingFree(&RichardHelperBinding); if (Status) { ApiError("Robert","RpcBindingFree",Status); PrintToConsole("Robert : FAIL - Unable to Free Binding"); PrintToConsole(" (RichardHelperBinding)\n"); return; } PrintToConsole("Robert : PASS\n"); } void Keith ( ) /*++ Routine Description: Keith works with Kenneth (in usvr.cxx) to test auto-reconnect. --*/ { RPC_BINDING_HANDLE KennethBinding; RPC_BINDING_HANDLE KennethHelperBinding; Synchro(KENNETH) ; if ( NumberOfTestsRun++ ) { PauseExecution(TestDelay); } PrintToConsole("Keith : Test Auto Reconnect\n"); Status = GetBinding(KENNETH, &KennethBinding); if (Status) { ApiError("Keith","GetBinding",Status); PrintToConsole("Keith : FAIL - Unable to Bind (Kenneth)\n"); return; } Status = GetBinding(RICHARDHELPER, &KennethHelperBinding); if (Status) { ApiError("Keith","GetBinding",Status); PrintToConsole("Keith : FAIL - Unable to Bind (KennethHelper)\n"); return; } Status = IsabelleRichardHelper(KennethBinding, RICHARDHELPER_EXECUTE); if (Status != RPC_S_OK) { ApiError("Keith","IsabelleRichardHelper",Status); PrintToConsole("Keith : FAIL - "); PrintToConsole("IsabelleRichardHelper(RICHARDHELPER_EXECUTE)\n"); return; } PauseExecution(20000L); Status = IsabelleRichardHelper(KennethHelperBinding, RICHARDHELPER_IGNORE); if (Status != RPC_S_OK) { ApiError("Keith","IsabelleRichardHelper",Status); PrintToConsole("Keith : FAIL - "); PrintToConsole("IsabelleRichardHelper(RICHARDHELPER_IGNORE)\n"); return; } Status = IsabelleRichardHelper(KennethHelperBinding, RICHARDHELPER_DELAY_EXIT); if (Status != RPC_S_OK) { PrintToConsole("Keith : FAIL - "); PrintToConsole("IsabelleRichardHelper(RICHARDHELPER_DELAY_EXIT) "); PrintToConsole("Failed\n"); return; } PauseExecution(30000L); Status = IsabelleRichardHelper(KennethBinding, RICHARDHELPER_EXECUTE); if (Status != RPC_S_OK) { ApiError("Keith","IsabelleRichardHelper",Status); PrintToConsole("Keith : FAIL - "); PrintToConsole("IsabelleRichardHelper(RICHARDHELPER_EXECUTE)\n"); return; } PauseExecution(40000L); Status = IsabelleRichardHelper(KennethHelperBinding, RICHARDHELPER_IGNORE); if (Status != RPC_S_OK) { ApiError("Keith","IsabelleRichardHelper",Status); PrintToConsole("Keith : FAIL - "); PrintToConsole("IsabelleRichardHelper(RICHARDHELPER_IGNORE)\n"); return; } IsabelleShutdown(KennethHelperBinding); IsabelleShutdown(KennethBinding); if (IsabelleErrors != 0) { PrintToConsole("Keith : FAIL - Error(s) in Isabelle Interface\n"); IsabelleErrors = 0; return; } Status = RpcBindingFree(&KennethBinding); if (Status) { ApiError("Keith","RpcBindingFree",Status); PrintToConsole("Keith : FAIL - Unable to Free Binding"); PrintToConsole(" (KennethBinding)\n"); return; } Status = RpcBindingFree(&KennethHelperBinding); if (Status) { ApiError("Keith","RpcBindingFree",Status); PrintToConsole("Keith : FAIL - Unable to Free Binding"); PrintToConsole(" (KennethHelperBinding)\n"); return; } PrintToConsole("Keith : PASS\n"); } void Daniel ( ) /*++ Routine Description: This routine is used to test association context rundown support; it works with David in usvr.exe. --*/ { RPC_BINDING_HANDLE DanielFirst;; RPC_BINDING_HANDLE DanielSecond; CCONTEXT *ContextHandle, *ContextHandle2; Synchro(DAVIDFIRST) ; if ( NumberOfTestsRun++ ) { PauseExecution(TestDelay); } PrintToConsole("Daniel : Association Context and Rundown\n"); Status = GetBinding(DAVIDFIRST, &DanielFirst); if (Status) { ApiError("Daniel","GetBinding",Status); PrintToConsole("Daniel : FAIL - Unable to Bind (DavidFirst)\n"); return; } Status = GetBinding(DAVIDSECOND, &DanielSecond); if (Status) { ApiError("Daniel","GetBinding",Status); PrintToConsole("Daniel : FAIL - Unable to Bind (DavidSecond)\n"); return; } IsabelleSetRundown(DanielSecond); IsabelleCheckContext(DanielSecond); #ifdef DEBUGRPC PrintToDebugger("\n\n\n\nUCLNT: Calling RpcBindingFree\n"); #endif Status = RpcBindingFree(&DanielSecond); if (Status) { ApiError("Daniel","RpcBindingFree",Status); PrintToConsole("Daniel : FAIL - Unable to Free Binding"); PrintToConsole(" (DanielSecond)\n"); return; } PauseExecution(3000L); IsabelleCheckRundown(DanielFirst); ContextHandle = (CCONTEXT *)I_RpcAllocate(sizeof(CCONTEXT)); if (!ContextHandle) { ApiError("Daniel","I_RpcAllocate",Status); PrintToConsole("Daniel : FAIL - Unable to I_RpcAllocate"); PrintToConsole(" (DanielSecond)\n"); return; } OpenContextHandle(DanielFirst, &IsabelleInterfaceInformation, NULL); OpenContextHandle(DanielFirst, &IsabelleInterfaceInformation, ContextHandle); Status = RpcBindingCopy(ContextHandle, (RPC_BINDING_HANDLE *)&ContextHandle2); if (Status) { ApiError("Daniel","RpcBindingCopy",Status); PrintToConsole("Daniel : FAIL - Unable to copy context handle"); PrintToConsole(" (DanielSecond)\n"); return; } Status = RpcBindingSetOption(ContextHandle2, RPC_C_OPT_DONT_LINGER, TRUE); if (Status) { ApiError("Daniel","RpcBindingSetOption",Status); PrintToConsole("Daniel : FAIL - Unable to set context handle options"); PrintToConsole(" (DanielSecond)\n"); return; } RpcSsDestroyClientContext((void **)&ContextHandle); RpcSsDestroyClientContext((void **)&ContextHandle2); OpenContextHandle(DanielFirst, &HelgaInterfaceInformation, NULL); OpenContextHandle(DanielFirst, &HelgaInterfaceInformation, NULL); UnregisterHelgaEx(DanielFirst); IsabelleShutdown(DanielFirst); if (IsabelleErrors != 0) { PrintToConsole("Daniel : FAIL - Error(s) in Isabelle Interface\n"); IsabelleErrors = 0; return; } Status = RpcBindingFree(&DanielFirst); if (Status) { ApiError("Daniel","RpcBindingFree",Status); PrintToConsole("Daniel : FAIL - Unable to Free Binding"); PrintToConsole(" (DanielFirst)\n"); return; } PrintToConsole("Daniel : PASS\n"); } int BenjaminTestBinding ( IN unsigned char PAPI * StringBinding ) /*++ Routine Description: This helper routine will take and convert the string binding into a binding, use the binding to make a remote procedure call, and then free the binding. Arguments: StringBinding - Supplies the string binding to use to convert into a binding. Return Value: If the test passes, zero will be returned; otherwise, non-zero will be returned. --*/ { RPC_BINDING_HANDLE Binding; unsigned char PAPI * ObjUuid; unsigned char PAPI * Protseq; unsigned char PAPI * NetworkAddr; unsigned char PAPI * NetworkOptions; int OldCallbacksFlag = 0; unsigned int TransportType; if ( UseEndpointMapperFlag != 0 ) { Status = RpcStringBindingParseA(StringBinding, &ObjUuid, &Protseq, &NetworkAddr, 0, &NetworkOptions); if (Status) { ApiError("Benjamin", "RpcStringBindingParse", Status); PrintToConsole("Benjamin : RpcStringBindingParse Failed\n"); return(1); } Status = RpcStringBindingComposeA(ObjUuid, Protseq, NetworkAddr, 0, NetworkOptions, &StringBinding); if (Status) { ApiError("Benjamin", "RpcStringBindingCompose", Status); PrintToConsole("Benjamin : RpcStringBindingCompose Failed\n"); return(1); } Status = RpcStringFreeA(&Protseq); if (!Status) RpcStringFreeA(&NetworkOptions); if (!Status) RpcStringFreeA(&ObjUuid); if (Status) { ApiError("Benjamin", "RpcStringFree", Status); PrintToConsole("Benjamin : RpcStringFree Failed\n"); return(1); } } PrintToConsole("Benjamin : "); PrintToConsole("%s - ", StringBinding); Status = RpcBindingFromStringBindingA(StringBinding, &Binding); if (Status) { if (Status == RPC_S_PROTSEQ_NOT_SUPPORTED) { return(0); } ApiError("Benjamin", "RpcBindingFromStringBinding", Status); PrintToConsole("Benjamin : FAIL - Unable to Binding"); PrintToConsole(" (StringBinding)\n"); return(1); } SylviaBinding = Binding; Status = I_RpcBindingInqTransportType(SylviaBinding, &TransportType); if (Status) { ApiError("Benjamin", "I_RpcBindingInqTransportType", Status); PrintToConsole("Benjamin : I_RpcBindingInqTransportType Failed\n"); return(1); } switch(TransportType) { case TRANSPORT_TYPE_CN: PrintToConsole("( cn )\n"); break; case TRANSPORT_TYPE_DG: PrintToConsole(" ( dg )\n"); break; case TRANSPORT_TYPE_LPC: PrintToConsole("( lpc )\n"); break; default: { PrintToConsole("Benjamin : FAIL - Incorrect result"); PrintToConsole("Benjamin : I_RpcBindingInqTransportType Failed\n"); return(1); } } //This is a temporary workaround till dg implements callbacks //What we want to do is if the transport type is datagram, set the no //callback flag even if user didnt specify. Then unset it again! if (TransportType == TRANSPORT_TYPE_DG) { OldCallbacksFlag = NoCallBacksFlag; NoCallBacksFlag = 1; } if ( SylviaCall(SylviaBinding, 5, 0, 0) != LocalSylviaCall(5, 0, 0) ) { PrintToConsole("Benjamin : FAIL - Incorrect result"); PrintToConsole(" from SylviaCall(5,0,0)\n"); return(1); } if (SylviaErrors != 0) { PrintToConsole("Benjamin : FAIL - Error(s) in Sylvia"); PrintToConsole(" Interface\n"); HelgaErrors = 0; return(1); } if (TransportType == TRANSPORT_TYPE_DG) { NoCallBacksFlag = OldCallbacksFlag; } Status = RpcBindingFree(&Binding); if (Status) { ApiError("Benjamin", "RpcBindingFree", Status); PrintToConsole("Benjamin : FAIL - Unable to Free Binding"); PrintToConsole(" (Binding)\n"); return(1); } return(0); } void Benjamin ( ) /*++ Routine Description: This routine works with Bartholomew in usvr.exe to test that dynamic endpoints work. What we actually do is inquire all bindings supported by the server, and then this client binds to each of them, and makes a call. --*/ { RPC_BINDING_HANDLE Bartholomew; unsigned char * StringBinding; Synchro(BARTHOLOMEW) ; if ( NumberOfTestsRun++ ) { PauseExecution(4*LONG_TESTDELAY); } PrintToConsole("Benjamin : Test Dynamic Endpoints\n"); Status = GetBinding(BARTHOLOMEW, &Bartholomew); if (Status) { ApiError("Benjamin", "GetBinding", Status); PrintToConsole("Benjamin : FAIL - Unable to Bind (Bartholomew)\n"); return; } while ((StringBinding = IsabelleGetStringBinding(Bartholomew)) != 0) { if (0 != strstr("http", (char *) StringBinding)) { delete StringBinding; continue; } if (BenjaminTestBinding(StringBinding) != 0) return; delete StringBinding; } IsabelleShutdown(Bartholomew); if (IsabelleErrors != 0) { PrintToConsole("Benjamin : FAIL - Error(s) in Isabelle"); PrintToConsole(" Interface\n"); IsabelleErrors = 0; return; } Status = RpcBindingFree(&Bartholomew); if (Status) { ApiError("Benjamin", "RpcBindingFree", Status); PrintToConsole("Benjamin : FAIL - Unable to Free Binding"); PrintToConsole(" (Bartholomew)\n"); return; } PrintToConsole("Benjamin : PASS\n"); } void Harold ( ) /*++ Routine Description: This routine works with Herman in usvr.exe to test that idle connections get cleaned up properly, and that context is maintained. --*/ { RPC_BINDING_HANDLE Binding, ContextBinding; int seconds; PrintToConsole("Harold : Test Idle Connection Cleanup and Context\n"); Synchro(HERMAN) ; if ( NumberOfTestsRun++ ) { PauseExecution(TestDelay); } Status = RpcMgmtEnableIdleCleanup(); if (Status) { ApiError("Harold","RpcMgmtEnableIdleCleanup",Status); PrintToConsole("Harold : FAIL - RpcMgmtEnableIdleCleanup\n"); return; } Status = GetBinding(HERMAN, &Binding); if (Status) { ApiError("Harold","GetBinding",Status); PrintToConsole("Harold : FAIL - Unable to Bind (Herman)\n"); return; } IsabelleSetRundown(Binding); IsabelleCheckContext(Binding); // We want to wait for eight minutes. This will give enough time for // the cleanup code to get run to cleanup the idle connection. PrintToConsole("Harold : Waiting"); for (seconds = 0; seconds < 30; seconds++) { PauseExecution(1000L); PrintToConsole("."); } PrintToConsole("\n"); IsabelleCheckRundown(Binding); if (IsabelleErrors != 0) { PrintToConsole("Harold : FAIL - Error(s) in Isabelle Interface\n"); IsabelleErrors = 0; return; } Status = I_RpcBindingCopy(Binding, &ContextBinding); if (Status) { ApiError("Harold", "I_RpcBindingCopy", Status); PrintToConsole("Harold : FAIL - I_RpcBindingCopy Failed\n"); return; } Status = RpcBindingFree(&Binding); if (Status) { ApiError("Harold","RpcBindingFree",Status); PrintToConsole("Harold : FAIL - Unable to Free Binding"); PrintToConsole(" (Binding)\n"); return; } IsabelleSetRundown(ContextBinding); IsabelleCheckContext(ContextBinding); // We want to wait for eight minutes. This will give enough time for // the cleanup code to get run to cleanup the idle connection, but this // time the connection should not be cleaned up because we have got // context open. PrintToConsole("Harold : Waiting"); for (seconds = 0; seconds < 30; seconds++) { PauseExecution(1000L); PrintToConsole("."); } PrintToConsole("\n"); IsabelleCheckNoRundown(ContextBinding); if (IsabelleErrors != 0) { PrintToConsole("Harold : FAIL - Error(s) in Isabelle Interface\n"); IsabelleErrors = 0; return; } IsabelleShutdown(ContextBinding); Status = RpcBindingFree(&ContextBinding); if (Status) { ApiError("Harold","RpcBindingFree",Status); PrintToConsole("Harold : FAIL - Unable to Free Binding"); PrintToConsole(" (ContextBinding)\n"); return; } PrintToConsole("Harold : PASS\n"); } unsigned int JamesSize = 128; unsigned int JamesCount = 100; void James ( ) /*++ Routine Description: This routine works with Jason in usvr.exe to perform timing tests of the runtime. --*/ { RPC_BINDING_HANDLE Binding; unsigned int Count; unsigned long StartingTime, EndingTime; unsigned char PAPI * StringBinding; UUID ObjectUuid; PrintToConsole("James : Timing Test (%d) %d times\n", JamesSize, JamesCount); Synchro(JASON) ; if ( NumberOfTestsRun++ ) { PauseExecution(TestDelay); } // // Bind, NullCall, Free // StringBinding = GetStringBinding(JASON,0,0); StartingTime = GetCurrentTime(); for (Count = 0; Count < JamesCount; Count++) { Status = RpcBindingFromStringBindingA(StringBinding,&Binding); if (Status) { ApiError("James","RpcBindingFromStringBinding",Status); PrintToConsole("James : FAIL - Unable to Bind (Jason)\n"); return; } if (fUniqueBinding) { Status = RpcBindingSetOption( Binding, RPC_C_OPT_UNIQUE_BINDING, TRUE ); if (Status != RPC_S_OK) { ApiError("James","RpcBindingSetOption",Status); return; } } Helga(Binding); if (HelgaErrors != 0) { PrintToConsole("James : FAIL - Error(s) in Helga Interface\n"); HelgaErrors = 0; return; } Status = RpcBindingFree(&Binding); if (Status) { ApiError("James","RpcBindingFree",Status); PrintToConsole("James : FAIL - Unable to Free Binding"); PrintToConsole(" (Binding)\n"); return; } } EndingTime = GetCurrentTime(); PrintToConsole(" Bind, NullCall, Free : %d.%d ms [%d in %d milliseconds]\n", (EndingTime - StartingTime) / JamesCount, ((1000 * (EndingTime - StartingTime) / JamesCount) % 1000), JamesCount, (EndingTime - StartingTime)); // // NullCall // Status = GetBinding(JASON, &Binding); if (Status) { ApiError("James","GetBinding",Status); PrintToConsole("James : FAIL - Unable to Bind (Jason)\n"); return; } Helga(Binding); StartingTime = GetCurrentTime(); for (Count = 0; Count < JamesCount; Count++) { Helga(Binding); } EndingTime = GetCurrentTime(); if (HelgaErrors != 0) { PrintToConsole("James : FAIL - Error(s) in Helga Interface\n"); HelgaErrors = 0; return; } Status = RpcBindingFree(&Binding); if (Status) { ApiError("James","RpcBindingFree",Status); PrintToConsole("James : FAIL - Unable to Free Binding"); PrintToConsole(" (Binding)\n"); return; } PrintToConsole(" NullCall : %d.%d ms [%d in %d milliseconds]\n", (EndingTime - StartingTime) / JamesCount, ((1000 * (EndingTime - StartingTime) / JamesCount) % 1000), JamesCount, (EndingTime - StartingTime)); // // InCall // Status = GetBinding(JASON, &Binding); if (Status) { ApiError("James","GetBinding",Status); PrintToConsole("James : FAIL - Unable to Bind (Jason)\n"); return; } Helga(Binding); StartingTime = GetCurrentTime(); for (Count = 0; Count < JamesCount; Count++) { HelgaIN(Binding,JamesSize); } EndingTime = GetCurrentTime(); if (HelgaErrors != 0) { PrintToConsole("James : FAIL - Error(s) in Helga Interface\n"); HelgaErrors = 0; return; } Status = RpcBindingFree(&Binding); if (Status) { ApiError("James","RpcBindingFree",Status); PrintToConsole("James : FAIL - Unable to Free Binding"); PrintToConsole(" (Binding)\n"); return; } PrintToConsole(" InCall(%d) : %d.%d ms [%d in %d milliseconds]\n", JamesSize, (EndingTime - StartingTime) / JamesCount, ((1000 * (EndingTime - StartingTime) / JamesCount) % 1000), JamesCount, (EndingTime - StartingTime)); // // InCall w/Binding Object UUID // Status = GetBinding(JASON, &Binding); if (Status) { ApiError("James","GetBinding",Status); PrintToConsole("James : FAIL - Unable to Bind (Jason)\n"); return; } GenerateUuidValue(8179, &ObjectUuid); Status = RpcBindingSetObject(Binding, &ObjectUuid); if (Status) { ApiError("Graham", "RpcBindingSetObject", Status); PrintToConsole("Graham : FAIL - Unable to Set Object\n"); return; } Helga(Binding); StartingTime = GetCurrentTime(); for (Count = 0; Count < JamesCount; Count++) { HelgaIN(Binding,JamesSize); } EndingTime = GetCurrentTime(); if (HelgaErrors != 0) { PrintToConsole("James : FAIL - Error(s) in Helga Interface\n"); HelgaErrors = 0; return; } Status = RpcBindingFree(&Binding); if (Status) { ApiError("James","RpcBindingFree",Status); PrintToConsole("James : FAIL - Unable to Free Binding"); PrintToConsole(" (Binding)\n"); return; } PrintToConsole(" InCall/WUUID(%d) : %d.%d ms [%d in %d milliseconds]\n", JamesSize, (EndingTime - StartingTime) / JamesCount, ((1000 * (EndingTime - StartingTime) / JamesCount) % 1000), JamesCount, (EndingTime - StartingTime)); // // OUTCall // Status = GetBinding(JASON, &Binding); if (Status) { ApiError("James","GetBinding",Status); PrintToConsole("James : FAIL - Unable to Bind (Jason)\n"); return; } Helga(Binding); StartingTime = GetCurrentTime(); for (Count = 0; Count < JamesCount; Count++) { HelgaOUT(Binding,JamesSize); } EndingTime = GetCurrentTime(); if (HelgaErrors != 0) { PrintToConsole("James : FAIL - Error(s) in Helga Interface\n"); HelgaErrors = 0; return; } Status = RpcBindingFree(&Binding); if (Status) { ApiError("James","RpcBindingFree",Status); PrintToConsole("James : FAIL - Unable to Free Binding"); PrintToConsole(" (Binding)\n"); return; } PrintToConsole(" OutCall(%d) : %d.%d ms [%d in %d milliseconds]\n", JamesSize, (EndingTime - StartingTime) / JamesCount, ((1000 * (EndingTime - StartingTime) / JamesCount) % 1000), JamesCount, (EndingTime - StartingTime)); // // InOutCall // Status = GetBinding(JASON, &Binding); if (Status) { ApiError("James","GetBinding",Status); PrintToConsole("James : FAIL - Unable to Bind (Jason)\n"); return; } Helga(Binding); StartingTime = GetCurrentTime(); for (Count = 0; Count < JamesCount; Count++) { HelgaINOUT(Binding,JamesSize); } EndingTime = GetCurrentTime(); if (HelgaErrors != 0) { PrintToConsole("James : FAIL - Error(s) in Helga Interface\n"); HelgaErrors = 0; return; } Status = RpcBindingFree(&Binding); if (Status) { ApiError("James","RpcBindingFree",Status); PrintToConsole("James : FAIL - Unable to Free Binding"); PrintToConsole(" (Binding)\n"); return; } PrintToConsole(" InOutCall(%d) : %d.%d ms [%d in %d milliseconds]\n", JamesSize, (EndingTime - StartingTime) / JamesCount, ((1000 * (EndingTime - StartingTime) / JamesCount) % 1000), JamesCount, (EndingTime - StartingTime)); Status = GetBinding(JASON, &Binding); if (Status) { ApiError("James","GetBinding",Status); PrintToConsole("James : FAIL - Unable to Bind (Jason)\n"); return; } IsabelleShutdown(Binding); if (IsabelleErrors != 0) { PrintToConsole("James : FAIL - Error(s) in Isabelle Interface\n"); IsabelleErrors = 0; return; } Status = RpcBindingFree(&Binding); if (Status) { ApiError("James","RpcBindingFree",Status); PrintToConsole("James : FAIL - Unable to Free Binding"); PrintToConsole(" (Binding)\n"); return; } PrintToConsole("James : PASS\n"); } int IsaacStressTest ( IN unsigned int Iteration, IN unsigned int InitialSize, IN unsigned int MaximumSize, IN unsigned int Increment ) /*++ Routine Description: This routine performs one iteration of the stress test. We bind with the server, perform one or more remote procedure calls, and then unbind. Arguments: Iteration - Supplies an indication of which iteration of the test is being performed. We will use that information to print out the buffer sizes the first time. InitialSize - Supplies the initial buffer size to use. MaximumSize - Supplies the maximum buffer size to use; when this size is reach, the test will return. Increment - Supplies the amount to increment the buffer size each time. Return Value: Zero will be returned if the test completes successfully; otherwise, non-zero will be returned. --*/ { RPC_BINDING_HANDLE Binding; Status = GetBinding(IVAN, &Binding); if (Status) { ApiError("Isaac","GetBinding",Status); PrintToConsole("Isaac : FAIL - Unable to Bind (Ivan)\n"); return(1); } for (; InitialSize < MaximumSize; InitialSize += Increment) { if (Iteration == 0) { PrintToConsole("%d ",InitialSize); } Helga(Binding); HelgaIN(Binding, InitialSize); HelgaOUT(Binding, InitialSize); HelgaINOUT(Binding, InitialSize); } if (Iteration == 0) { PrintToConsole("\n"); } if (HelgaErrors != 0) { PrintToConsole("Isaac : FAIL - Error(s) in Helga Interface\n"); HelgaErrors = 0; return(1); } Status = RpcBindingFree(&Binding); if (Status) { ApiError("Isaac","RpcBindingFree",Status); PrintToConsole("Isaac : FAIL - Unable to Free Binding"); PrintToConsole(" (Binding)\n"); return(1); } return(0); } unsigned int IsaacIterations = 100; unsigned int IsaacInitialSize = 128; unsigned int IsaacMaximumSize = 4096; unsigned int IsaacIncrement = 512; void Isaac ( ) /*++ Routine Description: This routine works to Ivan in usvr.exe to stress test the runtime. --*/ { RPC_BINDING_HANDLE Binding; unsigned int Count; PrintToConsole("Isaac : Stress Test (%d to %d by %d) %d times\n", IsaacInitialSize, IsaacMaximumSize, IsaacIncrement, IsaacIterations); Synchro(IVAN) ; if ( NumberOfTestsRun++ ) { PauseExecution(TestDelay); } for (Count = 0; Count < IsaacIterations ; Count++) { if ( IsaacStressTest(Count, IsaacInitialSize, IsaacMaximumSize, IsaacIncrement) != 0 ) { return; } PrintToConsole("."); } PrintToConsole("\n"); // this piece of code was below the loop Status = GetBinding(IVAN, &Binding); if (Status) { ApiError("Isaac","GetBinding",Status); PrintToConsole("Isaac : FAIL - Unable to Bind (Ivan)\n"); return; } IsabelleShutdown(Binding); if (IsabelleErrors != 0) { PrintToConsole("Isaac : FAIL - Error(s) in Isabelle Interface\n"); IsabelleErrors = 0; return; } Status = RpcBindingFree(&Binding); if (Status) { ApiError("Isaac","RpcBindingFree",Status); PrintToConsole("Isaac : FAIL - Unable to Free Binding"); PrintToConsole(" (Binding)\n"); return; } PrintToConsole("Isaac : PASS\n"); } void ExtendedError ( ) { RPC_BINDING_HANDLE Binding ; RPC_SECURITY_QOS QOS; UUID ObjectUuid; Status = GetBinding(TYLER, &Binding); if (Status) { ApiError("ExtendedError", "GetBinding", Status); PrintToConsole("ExtendedError : FAIL - Unable to Bind (Tyler)\n"); return; } QOS.Version = RPC_C_SECURITY_QOS_VERSION; QOS.ImpersonationType = RPC_C_IMP_LEVEL_IMPERSONATE; QOS.Capabilities = RPC_C_QOS_CAPABILITIES_MUTUAL_AUTH; QOS.IdentityTracking = RPC_C_QOS_IDENTITY_DYNAMIC; Status = RpcBindingSetAuthInfoEx( Binding, (RPC_CHAR *) L"ServerPrincipal", RPC_C_AUTHN_LEVEL_CONNECT, 10, NULL, 0, &QOS); if (Status != RPC_S_OK) { ApiError("ExtendedError","RpcBindingSetAuthInfoEx",Status); return; } Helga(Binding); if (HelgaErrors) { PrintToConsole("RPC extended error: %d", I_RpcGetExtendedError()); } else { PrintToConsole("RPC call passed\n"); } RpcBindingFree( &Binding ); // // check propagation of extended-error packets // Status = GetBinding(TYLER, &Binding); if (Status) { ApiError("Async", "GetBinding", Status); PrintToConsole("Async : FAIL - Unable to Bind (Async)\n"); return; } // // see usvr.cxx: activates the extended error info in "ThreadProc" // GenerateUuidValue(UUID_EXTENDED_ERROR, &ObjectUuid); Status = RpcBindingSetObject(Binding, &ObjectUuid); if (Status) { ApiError("Async", "BindingSetObject", Status); PrintToConsole("Async : FAIL - Unable to Bind (Async)\n"); return; } int i; // // make a few calls on the helga interface // this should cause an alter context // for (i=0; i<3; i++) { __try { int inbuf[1]; int sizeout = 0; int * bufferout; // // FooSync will force an exception on the server if the in-size is zero. // FooSync( Binding, sizeof(int), inbuf, &sizeout, &bufferout); } __except(1) { Status = GetExceptionCode(); } if (Status != EXTENDED_ERROR_EXCEPTION) { PrintToConsole("eeinfo: call returned status %d instead of %d\n", Status, EXTENDED_ERROR_EXCEPTION); } DumpEeInfo(1); } } void TestYield(void) { RPC_BINDING_HANDLE Binding ; RPC_MESSAGE Caller; Synchro(TESTYIELD) ; Caller.BufferLength = 0; Caller.ProcNum = 5 | HackForOldStubs ; Caller.RpcInterfaceInformation = &HelgaInterfaceInformation ; Caller.RpcFlags = 0; Status = GetBinding(TESTYIELD, &Binding); if (Status) { ApiError("TestYield","GetBinding",Status); PrintToConsole("TestYield: FAIL - Unable to Bind\n"); return; } // new code end Caller.Handle = Binding; while(UclntGetBuffer(&Caller)) { Caller.Handle = Binding ; PauseExecution(1000) ; } if(UclntSendReceive(&Caller) != 0) { ApiError("TestYield","GetBinding",Status); PrintToConsole("TestYield: FAIL - Unable to Bind\n"); return; } Status = I_RpcFreeBuffer(&Caller); if (Status) ApiError("TestYield","I_RpcFreeBuffer",Status); Status = RpcBindingFree(&Binding); if (Status) { ApiError("TestYield","RpcBindingFree",Status); PrintToConsole("TestYield: FAIL - Unable to Free Binding"); return; } } char *GetNextCard ( char **Ptr ) { char *Card = *Ptr ; if (*Card == 0) { return NULL ; } while (**Ptr) (*Ptr)++ ; (*Ptr)++ ; ASSERT(*Card == '\\') ; Card++ ; while (*Card != '\\') Card++ ; Card++ ; return Card ; } char *GetNextIPAddress( char **Ptr ) { char *Address = *Ptr ; if (*Address == 0) { return NULL ; } while (**Ptr) (*Ptr)++ ; (*Ptr)++ ; return Address ; } void PrintAddresses( char *Card ) { char szBuf[512] ; HKEY hKey; RPC_STATUS Status; char Buffer[512] ; DWORD Size = 512; char *address ; char *temp1 ; DWORD Type; // Create the key string sprintf(szBuf, "System\\CurrentControlSet\\Services\\%s\\Parameters\\Tcpip", Card) ; Status = RegOpenKeyExA( HKEY_LOCAL_MACHINE, szBuf, 0, KEY_READ, &hKey); if ( Status != ERROR_SUCCESS && Status != ERROR_FILE_NOT_FOUND ) { ASSERT(0); return; } // Get DHCP Address if (Status == ERROR_SUCCESS) { Status = RegQueryValueExA( hKey, "DhcpIPAddress", 0, &Type, (unsigned char *) Buffer, &Size); } if ( Status != ERROR_SUCCESS && Status != ERROR_FILE_NOT_FOUND ) { ASSERT(0); return ; } PrintToConsole("\tDHCP: %s\n", Buffer) ; Status = RegQueryValueExA( hKey, "IPAddress", 0, &Type, (unsigned char *) Buffer, &Size); if ( Status != ERROR_SUCCESS && Status != ERROR_FILE_NOT_FOUND ) { ASSERT(0); return ; } int i ; for (i =0, temp1 = Buffer; address = GetNextIPAddress(&temp1); i++) { PrintToConsole("\tStatic IP Address [%d]: %s\n", i, address) ; } } void RegLookup() { char *temp ; char *Card ; char Buffer[512] ; RPC_STATUS Status; HKEY hKey; DWORD Size = 512; DWORD Type; PrintToConsole("RegLookup\n") ; NumberOfTestsRun++ ; Status = RegOpenKeyExA( HKEY_LOCAL_MACHINE, "System\\CurrentControlSet\\Services\\Rpc\\Linkage", 0, KEY_READ, &hKey); if ( Status != ERROR_SUCCESS && Status != ERROR_FILE_NOT_FOUND ) { ASSERT(0); return; } if (Status == ERROR_SUCCESS) { Status = RegQueryValueExA( hKey, "Bind", 0, &Type, (unsigned char *) Buffer, &Size); } if ( Status != ERROR_SUCCESS && Status != ERROR_FILE_NOT_FOUND ) { ASSERT(0); return ; } char *temp1; char *address; PrintToConsole("Cards:") ; for (temp = Buffer; Card = GetNextCard(&temp);) { PrintToConsole("%s:\n", Card) ; PrintAddresses(Card) ; } } void Except() { int i ; for (i =0; i <100; i++) { RpcTryExcept { RpcRaiseException(10) ; } RpcExcept(I_RpcExceptionFilter(RpcExceptionCode())) { PrintToConsole("exception raised!") ; } RpcEndExcept } } char *osf_ptype[] = { "rpc_request", "bad packet", "rpc_response", "rpc_fault", "bad packet", "bad packet", "bad packet", "bad packet", "bad packet", "bad packet", "bad packet", "rpc_bind", "rpc_bind_ack", "rpc_bind_nak", "rpc_alter_context", "rpc_alter_context_resp", "rpc_auth_3", "rpc_shutdown", "rpc_cancel", "rpc_orphaned" }; void PrintUuid(UUID *Uuid) { unsigned long PAPI * Vector; Vector = (unsigned long PAPI *) Uuid; if ( (Vector[0] == 0) && (Vector[1] == 0) && (Vector[2] == 0) && (Vector[3] == 0)) { PrintToConsole("(Null Uuid)"); } else { PrintToConsole("%08lx-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", Uuid->Data1, Uuid->Data2, Uuid->Data3, Uuid->Data4[0], Uuid->Data4[1], Uuid->Data4[2], Uuid->Data4[3], Uuid->Data4[4], Uuid->Data4[5], Uuid->Data4[6], Uuid->Data4[7] ); } return; } void do_copacket ( rpcconn_common *Packet ) { sec_trailer *SecurityTrailer; // // Dump the common header first // PrintToConsole("\n"); PrintToConsole ("rpc_vers\t\t- 0x%x\n", Packet->rpc_vers); PrintToConsole ("rpc_vers_minor\t\t- 0x%x\n", Packet->rpc_vers_minor); PrintToConsole ("PTYPE\t\t\t- 0x%x, %s\n", Packet->PTYPE, osf_ptype[Packet->PTYPE]); PrintToConsole ("pfc_flags\t\t- 0x%x\n", Packet->pfc_flags); PrintToConsole ("drep\t\t\t- 0x%x\n", (DWORD) *((DWORD *) &(Packet->drep))); PrintToConsole ("frag_length\t\t- 0x%x\n", Packet->frag_length); PrintToConsole ("auth_length\t\t- 0x%x\n", Packet->auth_length); PrintToConsole ("call_id\t\t\t- 0x%x\n", Packet->call_id); // // // Dump the packet specific stuff // switch (Packet->PTYPE) { case rpc_request: PrintToConsole ("alloc_hint\t\t- 0x%x\n", ((rpcconn_request *) Packet)->alloc_hint); PrintToConsole ("p_cont_id\t\t- 0x%x\n", ((rpcconn_request *) Packet)->p_cont_id); PrintToConsole ("opnum\t\t\t- 0x%x\n", ((rpcconn_request *) Packet)->opnum); if (Packet->pfc_flags & PFC_OBJECT_UUID) { PrintToConsole("UUID\t\t -\n"); PrintUuid((UUID *) (((char *)Packet)+sizeof(rpcconn_common))); PrintToConsole("\n"); PrintToConsole ("Stub Data\t\t- 0x%p\n", (char *) Packet+sizeof(rpcconn_request)+sizeof(UUID)); } else { PrintToConsole ("Stub Data\t\t- 0x%p\n", (char *) Packet+sizeof(rpcconn_request)); } break; case rpc_response: PrintToConsole ("alloc_hint\t\t- 0x%x\n", ((rpcconn_response *) Packet)->alloc_hint); PrintToConsole ("p_cont_id\t\t- 0x%x\n", ((rpcconn_response *) Packet)->p_cont_id); PrintToConsole ("alert_count\t\t- 0x%x\n", ((rpcconn_response *) Packet)->alert_count); PrintToConsole ("reserved\t\t- 0x%x\n", ((rpcconn_response *) Packet)->reserved); PrintToConsole ("Stub Data\t\t- 0x%p\n", (char *) Packet+sizeof(rpcconn_response)); break; case rpc_fault: PrintToConsole ("alloc_hint\t\t- 0x%x\n", ((rpcconn_fault *) Packet)->alloc_hint); PrintToConsole ("p_cont_id\t\t- 0x%x\n", ((rpcconn_fault *) Packet)->p_cont_id); PrintToConsole ("alert_count\t\t- 0x%x\n", ((rpcconn_fault *) Packet)->alert_count); PrintToConsole ("reserved\t\t- 0x%x\n", ((rpcconn_fault *) Packet)->reserved); PrintToConsole ("status\t\t- 0x%x\n", ((rpcconn_fault *) Packet)->status); PrintToConsole ("reserved2\t\t- 0x%x\n", ((rpcconn_fault *) Packet)->reserved2); break; case rpc_bind: case rpc_alter_context: PrintToConsole ("max_xmit_frag\t\t- 0x%x\n", ((rpcconn_bind *) Packet)->max_xmit_frag); PrintToConsole ("max_recv_frag\t\t- 0x%x\n", ((rpcconn_bind *) Packet)->max_recv_frag); PrintToConsole ("assoc_group_id\t\t- 0x%x\n", ((rpcconn_bind *) Packet)->assoc_group_id); break; case rpc_bind_ack: PrintToConsole ("max_xmit_frag\t\t- 0x%x\n", ((rpcconn_bind_ack *) Packet)->max_xmit_frag); PrintToConsole ("max_recv_frag\t\t- 0x%x\n", ((rpcconn_bind_ack *) Packet)->max_recv_frag); PrintToConsole ("assoc_group_id\t\t- 0x%x\n", ((rpcconn_bind_ack *) Packet)->assoc_group_id); PrintToConsole ("sec_addr_length\t\t- 0x%x\n", ((rpcconn_bind_ack *) Packet)->sec_addr_length); break; case rpc_bind_nak: PrintToConsole ("provider_reject_reason\t\t- 0x%x\n", ((rpcconn_bind_nak *) Packet)->provider_reject_reason); PrintToConsole ("versions\t\t- 0x%x\n", ((rpcconn_bind_nak *) Packet)->versions); break; case rpc_alter_context_resp: PrintToConsole ("max_xmit_frag\t\t- 0x%x\n", ((rpcconn_alter_context_resp *) Packet)->max_xmit_frag); PrintToConsole ("max_recv_frag\t\t- 0x%x\n", ((rpcconn_alter_context_resp *) Packet)->max_recv_frag); PrintToConsole ("assoc_group_id\t\t- 0x%x\n", ((rpcconn_alter_context_resp *) Packet)->assoc_group_id); PrintToConsole ("sec_addr_length\t\t- 0x%x\n", ((rpcconn_alter_context_resp *) Packet)->sec_addr_length); PrintToConsole ("pad\t\t- 0x%x\n", ((rpcconn_alter_context_resp *) Packet)->pad); break; case rpc_auth_3: case rpc_shutdown: case rpc_cancel: case rpc_orphaned: break; default: PrintToConsole ("Bad Packet\n"); break; } // // Dump the security trailer // if (Packet->auth_length) { SecurityTrailer = (sec_trailer *) ((char *) Packet+Packet->frag_length -Packet->auth_length - sizeof(sec_trailer)); PrintToConsole("Security trailer: 0x%p\n", SecurityTrailer); PrintToConsole ("auth_type\t\t- 0x%x\n", SecurityTrailer->auth_type); PrintToConsole ("auth_level\t\t- 0x%x\n", SecurityTrailer->auth_level); PrintToConsole ("auth_pad_length\t\t- 0x%x\n", SecurityTrailer->auth_pad_length); PrintToConsole ("auth_reserved\t\t- 0x%x\n", SecurityTrailer->auth_reserved); PrintToConsole ("auth_context_id\t\t- 0x%x\n", SecurityTrailer->auth_context_id); PrintToConsole ("trailer\t\t-0x%p\n", SecurityTrailer+1); } } void RpcPduFilter ( IN void *Buffer, IN unsigned int BufferLength, IN BOOL fDatagram ) { if (fDatagram == 0) { do_copacket((rpcconn_common *) Buffer); } else { PrintToConsole("UCNT: Datagram PDU\n"); } } void SetPDUFilter ( ) { HMODULE hLibrary; RPC_SETFILTER_FUNC pSetFilterFunc; hLibrary = LoadLibraryA("rpcrt4.dll"); if (hLibrary == 0) { PrintToConsole("UCLNT: Cannot set PDU filter\n"); return; } pSetFilterFunc = (RPC_SETFILTER_FUNC) GetProcAddress( hLibrary, "I_RpcltDebugSetPDUFilter"); if (pSetFilterFunc == 0) { PrintToConsole("UCLNT: Cannot set PDU filter\n"); return; } (*pSetFilterFunc) (RpcPduFilter); } extern void Async ( int testnum ) ; extern void SendAck ( int testnum ) ; extern void AsyncAll ( void ) ; int __cdecl main ( int argc, char * argv[] ) /* Transports: Update this to add a new transport. */ { int argscan; RPC_STATUS RpcStatus = RPC_S_OK; char *option ; int testnum = 0; DWORD dwTickCount; dwTickCount = GetTickCount(); InitializeCriticalSection(&TestMutex); // Normally, this routine will be called by the DLL initialization // routine. However, we are linking in our own copy of the threads // package, so we need to call this to initialize it. RpcMgmtSetCancelTimeout(20) ; ASSERT( RpcStatus == RPC_S_OK ); PrintToConsole("RPC Runtime Client Build Verification Test\n"); TransportType = RPC_TRANSPORT_NAMEPIPE; for (argscan = 1; argscan < argc; argscan++) { if (strcmp(argv[argscan], "-p") == 0) { ulSecurityPackage = (unsigned long) atol(argv[argscan+1]); argscan++; } else if (strcmp(argv[argscan],"-princ") == 0) { gPrincName = argv[argscan + 1]; argscan ++; } else if (strcmp(argv[argscan],"-warn") == 0) { WarnFlag = 1; } else if (strcmp(argv[argscan],"-noncausal") == 0) { fNonCausal = 1; } else if (strcmp(argv[argscan],"-unique") == 0) { fUniqueBinding = 1; } else if (strcmp(argv[argscan],"-v") == 0) { Verbose = 1; } else if (strcmp(argv[argscan],"-verbose") == 0) { Verbose = 1; } else if (strcmp(argv[argscan],"-error") == 0) { ErrorFlag = 1; } else if (strcmp(argv[argscan],"-rpcss") == 0) { UseEndpointMapperFlag = 1; } else if (strcmp(argv[argscan],"-nosecuritytests") == 0) { NoSecurityTests = 1; } else if (strcmp(argv[argscan],"-nocallbacks") == 0) { NoCallBacksFlag = 1; } else if (strcmp(argv[argscan],"-small") == 0) { HelgaMaxSize = 1024; } else if (strcmp(argv[argscan],"-medium") == 0) { HelgaMaxSize = 8*1024; } else if (strcmp(argv[argscan],"-exceptfail") == 0) { RpcRaiseException(437); } else if (strcmp(argv[argscan],"-idempotent") == 0) { HackForOldStubs = RPC_FLAGS_VALID_BIT; } else if (strcmp(argv[argscan],"-theodore") == 0) { Theodore(); } else if (strcmp(argv[argscan],"-sebastian") == 0) { Sebastian(); } else if (strcmp(argv[argscan],"-hybrid") == 0) { Hybrid(); } else if (strcmp(argv[argscan],"-lpcsecurity") == 0) { LpcSecurity(); } else if (strcmp(argv[argscan],"-objuuid") == 0) { TestObjectUuids(); } else if (strcmp(argv[argscan],"-connid") == 0) { TestConnId(); } else if (strcmp(argv[argscan],"-graham") == 0) { Graham(); } else if (strcmp(argv[argscan],"-edward") == 0) { Edward(); } else if (strcmp(argv[argscan],"-astro") == 0) { Astro(); } else if (strcmp(argv[argscan],"-fitzgerald") == 0) { Fitzgerald(); } else if (strcmp(argv[argscan],"-charles") == 0) { Charles(); } else if (strcmp(argv[argscan],"-daniel") == 0) { Daniel(); } else if (strcmp(argv[argscan],"-thomas") == 0) { Thomas(); } else if (strcmp(argv[argscan],"-tim") == 0) { Tim(); } else if (strcmp(argv[argscan],"-robert") == 0) { Robert(); } else if (strcmp(argv[argscan],"-benjamin") == 0) { Benjamin(); } else if (strcmp(argv[argscan],"-harold") == 0) { Harold(); } else if (strcmp(argv[argscan],"-isaac") == 0) { Isaac(); } else if (strcmp(argv[argscan],"-james") == 0) { James(); } else if (strcmp(argv[argscan],"-keith") == 0) { Keith(); } else if (strcmp(argv[argscan],"-exerror") == 0) { ExtendedError(); } else if (strcmp(argv[argscan],"-eeinfo") == 0) { ExtendedErrorInfo(); } else if (strcmp(argv[argscan],"-async") == 0) { Async(testnum); } else if (strcmp(argv[argscan],"-mutextest") == 0) { PerformMultiThreadAstroTest(AstroDontBind, AstroMutex, 0); } else if (strcmp(argv[argscan],"-asynctest") == 0) { argscan++ ; if (strcmp(argv[argscan], "?") == 0) { testnum = 100 ; } else { testnum = atoi(argv[argscan]) ; } } else if (strcmp(argv[argscan],"-sendack") == 0) { argscan++ ; if (argscan == argc) { PrintToConsole("-sendack: you must specify a test #, or zero for all, or '?' for help\n"); return 1; } if (strcmp(argv[argscan], "?") == 0) { testnum = 100 ; } else { testnum = atoi(argv[argscan]) ; } SendAck( testnum ); } else if (strcmp(argv[argscan],"-dgtransport") == 0) { argscan++ ; if (argscan == argc) { PrintToConsole("-dgtransport: you must specify a test #, or zero for all, or '?' for help\n"); return 1; } if (strcmp(argv[argscan], "?") == 0) { testnum = 100 ; } else { testnum = atoi(argv[argscan]) ; } DgTransport( testnum ); } else if (strcmp(argv[argscan],"-securityerror") == 0) { PrintToConsole("security provider error tests \n"); argscan++ ; if (argscan == argc) { PrintToConsole("-securityerror: you must specify a test #, or zero for all, or '?' for help\n"); return 1; } if (strcmp(argv[argscan], "?") == 0) { testnum = 100 ; } else { testnum = atoi(argv[argscan]) ; } SecurityErrorWrapper(testnum); } else if (strcmp(argv[argscan],"-reg") == 0) { RegLookup() ; } else if (strcmp(argv[argscan],"-pipe") == 0) { Pipe() ; } else if (strcmp(argv[argscan],"-except") == 0) { Except(); } else if (strcmp(argv[argscan],"-namepipe") == 0) { TransportType = RPC_TRANSPORT_NAMEPIPE; } else if (strcmp(argv[argscan],"-lrpc") == 0) { TransportType = RPC_LRPC; } else if (strcmp(argv[argscan],"-tcp") == 0) { TransportType = RPC_TRANSPORT_TCP; } else if (strcmp(argv[argscan],"-udp") == 0) { DatagramTests = 1; NoCallBacksFlag = 1; TransportType = RPC_TRANSPORT_UDP; } else if (strcmp(argv[argscan],"-dnet") == 0) { TransportType = RPC_TRANSPORT_DNET; } else if (strcmp(argv[argscan],"-netbios") == 0) { TestDelay = LONG_TESTDELAY; TransportType = RPC_TRANSPORT_NETBIOS; } else if (strcmp(argv[argscan],"-spx") == 0) { TransportType = RPC_TRANSPORT_SPX; } else if (strcmp(argv[argscan], "-dsp") == 0) { TransportType = RPC_TRANSPORT_DSP ; } else if (strcmp(argv[argscan], "-autolisten") == 0) { AutoListenFlag = 1 ; } else if (strcmp(argv[argscan], "-ifsecurity") == 0) { IFSecurityFlag = 1 ; } else if (strcmp(argv[argscan],"-ipx") == 0) { DatagramTests = 1; NoCallBacksFlag = 1; TransportType = RPC_TRANSPORT_IPX; } else if (strcmp(argv[argscan],"-vns") == 0) { TransportType = RPC_TRANSPORT_VNS; } else if (strcmp(argv[argscan],"-msmq") == 0) { DatagramTests = 1; NoCallBacksFlag = 1; TransportType = RPC_TRANSPORT_MSMQ; } else if (strcmp(argv[argscan],"-pdufilter") == 0) { SetPDUFilter(); } else if (strcmp(argv[argscan],"-protocol") == 0) { strcpy(NetBiosProtocol+sizeof("ncacn_nb_")-1, argv[argscan+1]); argscan++; } else if (strncmp(argv[argscan],"-server:",strlen("-server:")) == 0) { Server = argv[argscan] + strlen("-server:"); } else if (strncmp(argv[argscan],"-su:", strlen("-su:")) == 0) { SecurityUser = (char *)(argv[argscan] + strlen("-su:")); } else if (strncmp(argv[argscan],"-sd:", strlen("-sd:")) == 0) { SecurityDomain = (char *) (argv[argscan] + strlen("-sd:")); } else if (strncmp(argv[argscan],"-sp:", strlen("-sp:")) == 0) { SecurityPassword = (char *) (argv[argscan] + strlen("-sp:")); } else if (strncmp(argv[argscan],"-threads:",strlen("-threads:")) == 0) { AstroThreads = atoi(argv[argscan] + strlen("-threads:")); if (AstroThreads == 0) { AstroThreads = 1; } } else if (strncmp(argv[argscan],"-iterations:",strlen("-iterations:")) == 0) { IsaacIterations = atoi(argv[argscan] + strlen("-iterations:")); if (IsaacIterations == 0) { IsaacIterations = 100; } } else if (strncmp(argv[argscan],"-initial:",strlen("-initial:")) == 0) { IsaacInitialSize = atoi(argv[argscan] + strlen("-initial:")); if (IsaacInitialSize < 4) { IsaacInitialSize = 128; } } else if (strncmp(argv[argscan],"-maximum:",strlen("-maximum:")) == 0) { IsaacMaximumSize = atoi(argv[argscan] + strlen("-maximum:")); if (IsaacMaximumSize < IsaacInitialSize) { IsaacMaximumSize = 4096; } } else if (strncmp(argv[argscan],"-increment:",strlen("-increment:")) == 0) { IsaacIncrement = atoi(argv[argscan] + strlen("-increment:")); if (IsaacIncrement == 0) { IsaacIncrement = 512; } } else if (strncmp(argv[argscan],"-size:",strlen("-size:")) == 0) { JamesSize = atoi(argv[argscan] + strlen("-size:")); if (JamesSize <4) { JamesSize = 4; } } else if (strncmp(argv[argscan],"-count:",strlen("-count:")) == 0) { JamesCount = atoi(argv[argscan] + strlen("-count:")); if (JamesCount == 0) { JamesCount = 100; } } else if ( (strcmp(argv[argscan],"-usage") == 0) || (strcmp(argv[argscan],"-?") == 0)) { PrintToConsole("Usage : uclnt\n"); PrintToConsole(" -warn : turn on warning messages\n"); PrintToConsole(" -error : turn on error messages\n"); PrintToConsole(" -nocallbacks\n"); PrintToConsole(" -nosecuritytests\n"); PrintToConsole(" -theodore\n"); PrintToConsole(" -exceptfail\n"); PrintToConsole(" -sebastian\n"); PrintToConsole(" -graham\n"); PrintToConsole(" -edward\n"); PrintToConsole(" -astro\n"); PrintToConsole(" -fitzgerald\n"); PrintToConsole(" -charles\n"); PrintToConsole(" -daniel\n"); PrintToConsole(" -thomas\n"); PrintToConsole(" -tim\n"); PrintToConsole(" -robert\n"); PrintToConsole(" -benjamin\n"); PrintToConsole(" -harold\n"); PrintToConsole(" -isaac\n"); PrintToConsole(" -james\n"); PrintToConsole(" -keith\n"); PrintToConsole(" -hybrid\n"); PrintToConsole(" -connid\n"); PrintToConsole(" -pipe\n") ; PrintToConsole(" -namepipe\n"); PrintToConsole(" -lrpc\n"); PrintToConsole(" -tcp\n"); PrintToConsole(" -udp [-idempotent -maybe -broadcast]\n"); PrintToConsole(" -dnet\n"); PrintToConsole(" -netbios\n"); PrintToConsole(" -server:\n"); PrintToConsole(" -spx\n"); PrintToConsole(" -ipx\n"); PrintToConsole(" -dsp\n") ; PrintToConsole(" -msmq\n") ; PrintToConsole(" -threads:\n"); PrintToConsole(" -iterations:\n"); PrintToConsole(" -initial:\n"); PrintToConsole(" -maximum:\n"); PrintToConsole(" -increment:\n"); PrintToConsole(" -size:\n"); PrintToConsole(" -count:\n"); PrintToConsole(" -rpcss\n"); PrintToConsole(" -p \n"); PrintToConsole(" -su:\n"); PrintToConsole(" -sd:\n"); PrintToConsole(" -sp:\n"); PrintToConsole(" -unique (enables RPC_C_OPT_UNIQUE_BINDING)\n"); PrintToConsole(" -noncausal (enables RPC_C_OPT_BINDING_NONCAUSAL)\n"); return(1); } else if (argv[argscan][0] == '-') { PrintToConsole("unknown option '%s'\n", argv[argscan]); return 1; } else Server = argv[argscan]; } if ( NumberOfTestsRun == 0 ) { Theodore(); Sebastian(); Graham(); Edward(); Astro(); Fitzgerald(); Charles(); Daniel(); if ( NoSecurityTests == 0) { Thomas(); } if ( TransportType != RPC_LRPC ) { Robert(); } Keith(); Benjamin(); Async(0); } return(0); // To keep the compiler happy. } // // BVT for Async RPC // // // Client side code // // // the following routines outline the client side code for a simple async // function // #define TRACE(_x) { \ if (Verbose) \ {\ PrintToConsole _x;\ }\ } int OutstandingCalls ; int FooProcnum = 16 ; int FooPipeProcnum = 17 ; void * FooInterface = &IsabelleInterfaceInformation; #if 0 // // Begin, Approximate idl file // interface FooInterface { int Foo (handle_t hBinding, [in] int sizein, [in] int *bufferin, [in, out] int *sizeout, [out] int **bufferout) ; } // End, idl file // // Begin, Corresponding ACF file // interface FooInterface { [async] Foo () ; } // End, acf file // // look at asyncstub.h for the generated header // file for function Foo // #endif //////////////////////////////////////////////////////////// // Begin, stubs for Foo // //////////////////////////////////////////////////////////// HANDLE SyncEvent ; typedef struct { RPC_ASYNC_STUB_STATE StubState ; void *state ; int *sizeout ; int **bufferout ; } FOO_ASYNC_CLIENT_STATE; RPC_STATUS FooComplete( IN PRPC_ASYNC_STATE pAsync, OUT void *Reply ) /*++ Routine Description: The completion routine corresponding to the function Foo. This routine is called to get the out parameters from an async function. Arguments: pAsync - Async Handle. The async handle is always the first parameter of every async routine. --*/ { RPC_STATUS Status ; RPC_MESSAGE Message ; int *ptr ; FOO_ASYNC_CLIENT_STATE *StubInfo = (FOO_ASYNC_CLIENT_STATE *) pAsync->StubInfo ; Message.RpcInterfaceInformation = FooInterface ; Message.RpcFlags = RPC_BUFFER_ASYNC; Message.Handle = StubInfo->StubState.CallHandle ; Message.Buffer = StubInfo->StubState.Buffer ; Message.BufferLength = StubInfo->StubState.BufferLength ; Status = I_RpcReceive(&Message, 0) ; if (Status) { return Status ; } ptr = (int *) Message.Buffer ; *((int *) Reply) = *ptr++ ; *(StubInfo->sizeout) = *ptr++ ; *(StubInfo->bufferout) = (int *) I_RpcAllocate(*(StubInfo->sizeout)) ; if (*(StubInfo->bufferout) == 0) { return RPC_S_OUT_OF_MEMORY ; } RpcpMemoryCopy(*(StubInfo->bufferout), ptr, *(StubInfo->sizeout)) ; I_RpcFreeBuffer(&Message) ; I_RpcFree(StubInfo) ; return RPC_S_OK ; } void Foo ( PRPC_ASYNC_STATE pAsync, RPC_BINDING_HANDLE hBinding, /* [in] */ int sizein, /* [in] */ int *bufferin, /* [in, out] */ int *sizeout, /* [out] */ int **bufferout ) /*++ Routine Description: Client stub for function Foo. Arguments: pAsync - Async Handle. The async handle is always the first parameter of every async routine. --*/ { RPC_STATUS RpcStatus ; RPC_MESSAGE Message ; FOO_ASYNC_CLIENT_STATE *StubInfo ; int *Ptr ; StubInfo = (FOO_ASYNC_CLIENT_STATE *) I_RpcAllocate ( sizeof(FOO_ASYNC_CLIENT_STATE)) ; if (StubInfo == 0) { RpcRaiseException(RPC_S_OUT_OF_MEMORY) ; } pAsync->StubInfo = (void *) StubInfo ; StubInfo->StubState.CallHandle = hBinding ; Message.Handle = hBinding ; Message.BufferLength = 8+sizein+(sizein%4) ; Message.ProcNum = FooProcnum | HackForOldStubs | RPC_FLAGS_VALID_BIT ; Message.RpcInterfaceInformation = FooInterface ; Message.RpcFlags = RPC_BUFFER_ASYNC ; RpcStatus = I_RpcGetBuffer(&Message) ; if (RpcStatus) { RpcRaiseException(RpcStatus) ; } // marshal ;-) Ptr = (int *) Message.Buffer ; *Ptr++ = sizein ; RpcpMemoryCopy(Ptr, bufferin, sizein) ; Ptr += (sizein+3)/sizeof(int) ; *Ptr = *sizeout ; StubInfo->StubState.Flags = 0; StubInfo->sizeout = sizeout ; StubInfo->bufferout = bufferout ; RpcStatus = I_RpcAsyncSetHandle(&Message, (PRPC_ASYNC_STATE) pAsync) ; if (RpcStatus) { RpcRaiseException(RpcStatus) ; } StubInfo->StubState.CompletionRoutine = FooComplete ; Message.RpcFlags = RPC_BUFFER_ASYNC; RpcStatus = I_RpcSend(&Message) ; if (RpcStatus) { RpcRaiseException(RpcStatus) ; } StubInfo->StubState.CallHandle = Message.Handle ; StubInfo->StubState.Buffer = Message.Buffer ; StubInfo->StubState.BufferLength = Message.BufferLength ; // return to the app } int FooSync ( RPC_BINDING_HANDLE hBinding, /* [in] */ int sizein, /* [in] */ int *bufferin, /* [in, out] */ int *sizeout, /* [out] */ int **bufferout ) /*++ Routine Description: Client stub for function Foo. Arguments: pAsync - Async Handle. The async handle is always the first parameter of every async routine. --*/ { RPC_STATUS RpcStatus ; RPC_MESSAGE Message ; int *Ptr ; int retval ; Message.Handle = hBinding ; Message.BufferLength = 8+sizein+(sizein%4) ; Message.ProcNum = FooProcnum | HackForOldStubs | RPC_FLAGS_VALID_BIT ; Message.RpcInterfaceInformation = &IsabelleInterfaceInformation ; Message.RpcFlags = 0; RpcStatus = I_RpcGetBuffer(&Message) ; if (RpcStatus) { RpcRaiseException(RpcStatus) ; } Ptr = (int *) Message.Buffer ; *Ptr++ = sizein ; RpcpMemoryCopy(Ptr, bufferin, sizein) ; Ptr += (sizein+3)/sizeof(int) ; *Ptr = *sizeout ; Message.RpcFlags = 0; RpcStatus = I_RpcSendReceive(&Message) ; if (RpcStatus) { RpcRaiseException(RpcStatus) ; } *bufferout = (int *) I_RpcAllocate(*sizeout) ; if (*bufferout == 0) { RpcRaiseException(RPC_S_OUT_OF_MEMORY) ; } Ptr = (int *) Message.Buffer ; retval = *Ptr++ ; *sizeout = *Ptr++; RpcpMemoryCopy(*bufferout, Ptr, *sizeout) ; I_RpcFreeBuffer(&Message) ; return retval ; } //////////////////////////////////////////////////////////// // End, stubs for Foo // //////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////// // Begin, Application // ////////////////////////////////////////////////////////// typedef struct { RPC_ASYNC_STATE Async ; int SizeOut ; int *BufferOut ; BOOL CallFinished ; } CALL_COOKIE ; void ThreadProc( IN CALL_COOKIE *Cookie ) /*++ Routine Description: completion routine is called in another thread. To prove that it can be. Arguments: pAsync - Async Handle. The async handle is always the first parameter of every async routine. --*/ { int retval ; TRACE(("Foo: waiting for aync reply\n")) ; RpcTryExcept { WaitForSingleObject(Cookie->Async.u.hEvent, INFINITE) ; Status = MyRpcCompleteAsyncCall(&Cookie->Async, &retval) ; if (Status != RPC_S_OK) { RpcRaiseException(Status) ; } TRACE(("Async: MyRpcCompleteAsyncCall returned %d\n", retval)) ; if (retval != 1) { RpcRaiseException(APP_ERROR) ; } I_RpcFree(Cookie->BufferOut) ; } RpcExcept(I_RpcExceptionFilter(RpcExceptionCode())) { PrintToConsole("Foo: Exception 0x%lX\n", GetExceptionCode()) ; IsabelleError() ; } RpcEndExcept SetEvent(SyncEvent) ; } void WaitForReply ( IN BOOL *pfCallFinished ) { do { if (SleepEx(INFINITE, TRUE) != WAIT_IO_COMPLETION) { RpcRaiseException(APP_ERROR); } } while (*pfCallFinished == 0); } void FooAPCRoutine ( IN PRPC_ASYNC_STATE pAsync, IN void *Context, IN RPC_ASYNC_EVENT Event ) /*++ Routine Description: description Arguments: arg1 - description --*/ { CALL_COOKIE *Cookie = (CALL_COOKIE *) pAsync->UserInfo ; switch (Event) { case RpcCallComplete: Cookie->CallFinished = 1; OutstandingCalls--; break; } } void CallFoo ( RPC_BINDING_HANDLE Binding, CALL_COOKIE *Cookie, RPC_NOTIFICATION_TYPES NotificationType, int SizeIn, int SizeOut ) /*++ Routine Description: description Arguments: arg1 - description --*/ { int *BufferIn ; BufferIn = (int *) new char[SizeIn] ; if (BufferIn == 0) { RpcRaiseException(APP_ERROR) ; } Cookie->SizeOut = SizeOut ; Cookie->Async.Size = sizeof(RPC_ASYNC_STATE) ; Cookie->Async.Flags = 0; Cookie->Async.Lock = 0; Cookie->Async.NotificationType = NotificationType ; switch (NotificationType) { case RpcNotificationTypeNone: break; case RpcNotificationTypeEvent: Cookie->Async.u.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL) ; if (Cookie->Async.u.hEvent == 0) { RpcRaiseException(APP_ERROR) ; } Cookie->Async.NotificationType = RpcNotificationTypeEvent ; break; case RpcNotificationTypeApc: Cookie->Async.NotificationType = RpcNotificationTypeApc ; Cookie->Async.u.APC.NotificationRoutine = FooAPCRoutine ; Cookie->Async.u.APC.hThread = 0; Cookie->CallFinished = 0; break; default: PrintToConsole("Async: bad notification type\n") ; break; } Cookie->Async.UserInfo = (void *) Cookie ; // call the async function // the buffers supplied for the [out] and the [in, out] params // should be valid until the logical RPC call has completed. Foo(&Cookie->Async, Binding, SizeIn, BufferIn, &Cookie->SizeOut, &Cookie->BufferOut) ; delete BufferIn ; } void AsyncUsingEvent( IN RPC_BINDING_HANDLE Binding, int SizeIn, int SizeOut ) /*++ Routine Description: The code that calls the async function. Arguments: Binding - the binding handle. --*/ { RPC_STATUS Status ; int userstate = 10; unsigned long ThreadIdentifier; HANDLE HandleToThread ; CALL_COOKIE *Cookie = 0; RpcTryExcept { Cookie =new CALL_COOKIE ; if (Cookie == 0) { RpcRaiseException(RPC_S_OUT_OF_MEMORY) ; } CallFoo (Binding, Cookie, RpcNotificationTypeEvent, SizeIn, SizeOut) ; HandleToThread = CreateThread( 0, DefaultThreadStackSize, (LPTHREAD_START_ROUTINE) ThreadProc, Cookie, 0, &ThreadIdentifier); if (HandleToThread == 0) { PrintToConsole("Foo: Error, couldn't create thread\n") ; RpcRaiseException(RPC_S_OUT_OF_MEMORY) ; } // wait for the other guy to finish TRACE(("Foo: Waiting...\n")) ; WaitForSingleObject(SyncEvent, INFINITE) ; } RpcExcept(I_RpcExceptionFilter(RpcExceptionCode())) { PrintToConsole("Foo: Exception 0x%lX\n", GetExceptionCode()) ; IsabelleError() ; } RpcEndExcept if (Cookie && Cookie->Async.u.hEvent) { CloseHandle(Cookie->Async.u.hEvent) ; } } void AsyncUsingAPC( RPC_BINDING_HANDLE Binding, int SizeIn, int SizeOut ) /*++ Routine Description: The code that calls the async function. Arguments: Binding - the binding handle. --*/ { RPC_STATUS Status ; CALL_COOKIE Cookie ; int retval ; RpcTryExcept { CallFoo(Binding, &Cookie, RpcNotificationTypeApc, SizeIn, SizeOut) ; WaitForReply(&(Cookie.CallFinished)); Status = MyRpcCompleteAsyncCall(&Cookie.Async, &retval) ; if (Status != RPC_S_OK) { RpcRaiseException(Status) ; } TRACE(("Async: MyRpcCompleteAsyncCall returned %d\n", retval)) ; if (retval != 1) { RpcRaiseException(APP_ERROR) ; } I_RpcFree(Cookie.BufferOut) ; } RpcExcept(I_RpcExceptionFilter(RpcExceptionCode())) { PrintToConsole("Foo: Exception 0x%lX\n", GetExceptionCode()) ; Status = GetExceptionCode() ; if (Status == SYNC_EXCEPT || Status == ASYNC_EXCEPT) { RpcRaiseException(Status) ; } else { IsabelleError() ; } } RpcEndExcept } void AsyncUsingPolling( RPC_BINDING_HANDLE Binding, int SizeIn, int SizeOut ) /*++ Routine Description: The code that calls the async function. Arguments: Binding - the binding handle. --*/ { RPC_STATUS Status ; CALL_COOKIE Cookie ; int retval ; RpcTryExcept { CallFoo(Binding, &Cookie, RpcNotificationTypeNone, SizeIn, SizeOut) ; while ((Status = RpcAsyncGetCallStatus(&Cookie.Async)) == RPC_S_ASYNC_CALL_PENDING) { Sleep(1) ; } if (Status != RPC_S_OK) { RpcRaiseException(Status) ; } Status = MyRpcCompleteAsyncCall(&Cookie.Async, &retval) ; if (Status != RPC_S_OK) { RpcRaiseException(Status) ; } TRACE(("Async: MyRpcCompleteAsyncCall returned %d\n", retval)) ; if (retval != 1) { RpcRaiseException(APP_ERROR) ; } I_RpcFree(Cookie.BufferOut) ; } RpcExcept(I_RpcExceptionFilter(RpcExceptionCode())) { PrintToConsole("Foo: Exception 0x%lX\n", GetExceptionCode()) ; Status = GetExceptionCode() ; if (Status == SYNC_EXCEPT || Status == ASYNC_EXCEPT) { RpcRaiseException(Status) ; } else { IsabelleError() ; } } RpcEndExcept } /////////////////////////////////////////////////////////// // End, Application // ////////////////////////////////////////////////////////// // // The following routines outline the client side code for a simple async function // using pipes. // #if 0 // // Begin, Approximate idl file // interface FooInterface { typedef pipe int aysnc_intpipe ; int FooPipe (handle_t hBinding, [in] int checksum_in, [in] async_intpipe *inpipe, [out] async_intpipe *outpipe, [out] int *checksum_out) ; } ; // End, idl file // // Begin, corresponding acf file // interface FooInterface { [async] Foo () ; } ; // // End, acf file // // // look at asyncstub.h for generated header // file for function FooPipe // #endif //////////////////////////////////////////////////////////// // Begin, stubs for FooPipe // //////////////////////////////////////////////////////////// // declare the async handle typedef struct { RPC_ASYNC_STUB_STATE StubState ; void *state ; async_intpipe outpipe ; int *checksum_out; } FOOPIPE_ASYNC_CLIENT_STATE, *FOOPIPE_ASYNC_CLIENT_HANDLE ; #define ASYNC_CHUNK_SIZE 1000 #define ASYNC_NUM_CHUNKS 20 RPC_STATUS PipeReceiveFunction ( IN PRPC_ASYNC_STATE pAsync, IN int *buffer, IN int requested_count, IN int *actual_count ) /*++ Function Name:PipeReceiveFunction Parameters: Description: Returns: --*/ { int num_elements = 0; RPC_MESSAGE Callee ; FOOPIPE_ASYNC_CLIENT_STATE *StubInfo = (FOOPIPE_ASYNC_CLIENT_STATE *) pAsync->StubInfo ; PIPE_STATE *state = &(StubInfo->StubState.PipeState); DWORD size = (DWORD) requested_count * state->PipeElementSize ; *actual_count = 0 ; if (state->EndOfPipe) { return RPC_S_OK; } I_RpcReadPipeElementsFromBuffer( state, (char *) buffer, size, &num_elements) ; *actual_count += num_elements ; size -= num_elements * state->PipeElementSize ; if (state->EndOfPipe == 0 && num_elements < requested_count) { Callee.ProcNum = RPC_FLAGS_VALID_BIT ; Callee.Handle = StubInfo->StubState.CallHandle ; Callee.RpcFlags = RPC_BUFFER_PARTIAL | RPC_BUFFER_ASYNC ; if (num_elements) { Callee.RpcFlags |= RPC_BUFFER_NONOTIFY; } Callee.Buffer = 0 ; Callee.BufferLength = 0 ; Status = I_RpcReceive(&Callee, size) ; if (Status) { if (num_elements && Status == RPC_S_ASYNC_CALL_PENDING) { num_elements = 0 ; return RPC_S_OK; } if (Status != RPC_S_ASYNC_CALL_PENDING) { ApiError("PipePull", "I_RpcReceive", Status) ; } num_elements = 0 ; return Status; } state->Buffer = Callee.Buffer ; state->BufferLength = Callee.BufferLength ; state->CurPointer = (char *) Callee.Buffer ; state->BytesRemaining = Callee.BufferLength ; buffer = (pipe_element_t *) ((char *) buffer + num_elements * state->PipeElementSize) ; num_elements = 0 ; I_RpcReadPipeElementsFromBuffer( state, (char *) buffer, size, &num_elements) ; *actual_count += num_elements ; } return RPC_S_OK; } RPC_STATUS PipeSendFunction ( IN PRPC_ASYNC_STATE pAsync, IN void *context, IN int *buffer, IN int num_elements ) /*++ Routine Description: this function is always implemented by the stubs. This routine is called by the application, to send pipe data. Arguments: pAsync - Async Handle. The async handle is always the first parameter of every async routine. --*/ { unsigned int Flags = 0; RPC_STATUS RpcStatus ; RPC_MESSAGE Message ; FOOPIPE_ASYNC_CLIENT_STATE *StubInfo = (FOOPIPE_ASYNC_CLIENT_STATE *) pAsync->StubInfo ; int calculated_length = num_elements * sizeof(int) + sizeof(int); char *ptr ; Message.ProcNum = FooPipeProcnum | HackForOldStubs; Message.RpcInterfaceInformation = &IsabelleInterfaceInformation ; Message.Handle = StubInfo->StubState.CallHandle ; Message.Buffer = StubInfo->StubState.Buffer ; Message.BufferLength = StubInfo->StubState.BufferLength; if (StubInfo->StubState.State == SEND_INCOMPLETE) { calculated_length += StubInfo->StubState.BufferLength ; } Message.RpcFlags = RPC_BUFFER_ASYNC ; RpcStatus = I_RpcReallocPipeBuffer (&Message, calculated_length) ; if (RpcStatus != RPC_S_OK) { return RpcStatus; } ptr = (char *) Message.Buffer ; if (StubInfo->StubState.State == SEND_INCOMPLETE) { ptr += StubInfo->StubState.BufferLength ; } *((int *) ptr) = num_elements ; RpcpMemoryCopy(ptr+sizeof(int), buffer, num_elements *sizeof(int)) ; if (num_elements) // || !lastpipe { Message.RpcFlags = RPC_BUFFER_PARTIAL ; } else { // we are making a simplifying assumption // that there is a single [in] pipe. Message.RpcFlags = 0; } Message.RpcFlags |= RPC_BUFFER_ASYNC; RpcStatus = I_RpcSend(&Message) ; if (RpcStatus == RPC_S_OK) { StubInfo->StubState.State = SEND_COMPLETE ; } else if (RpcStatus == RPC_S_SEND_INCOMPLETE) { StubInfo->StubState.State = SEND_INCOMPLETE ; } else { return RpcStatus; } StubInfo->StubState.Buffer = Message.Buffer ; StubInfo->StubState.BufferLength = Message.BufferLength ; return RPC_S_OK; } RPC_STATUS FooPipeComplete( IN PRPC_ASYNC_STATE pAsync, IN void *Reply ) /*++ Routine Description: Stub for the completion routine of FooPipe Arguments: pAsync - Async Handle. The async handle is always the first parameter of every async routine. --*/ { RPC_STATUS Status ; RPC_MESSAGE Message ; void *ptr ; int retval; UINT_PTR offset ; FOOPIPE_ASYNC_CLIENT_STATE *StubInfo = (FOOPIPE_ASYNC_CLIENT_STATE *) pAsync->StubInfo ; Message.RpcInterfaceInformation = &IsabelleInterfaceInformation ; Message.Handle = StubInfo->StubState.CallHandle ; Message.Buffer = StubInfo->StubState.PipeState.Buffer; Message.BufferLength = 0; if (StubInfo->StubState.PipeState.BytesRemaining < 8) { Message.RpcFlags = RPC_BUFFER_ASYNC|RPC_BUFFER_EXTRA; Status = I_RpcReceive(&Message, 8) ; if (Status) { return Status ; } // just being paranoid here. I didn't want an overflow. offset = StubInfo->StubState.PipeState.CurPointer - (char *) StubInfo->StubState.PipeState.Buffer ; ptr = (char *) Message.Buffer + offset ; } else { ptr = StubInfo->StubState.PipeState.CurPointer ; if (!ptr) { return RPC_S_OUT_OF_MEMORY ; } } *((int *) Reply) = *((int *) ptr) ; *(StubInfo->checksum_out) = *(((int *) ptr)+1) ; I_RpcFreeBuffer(&Message) ; I_RpcFree(StubInfo) ; return RPC_S_OK ; } int tempint ; void FooPipe ( PRPC_ASYNC_STATE pAsync, RPC_BINDING_HANDLE hBinding, /* [in] */ int checksum_in, /* [in] */ async_intpipe *inpipe, /* [out] */ async_intpipe *outpipe, /* [out] */ int *checksum_out ) /*++ Routine Description: The stub routine for FooPipe function. Arguments: pAsync - Async Handle. The async handle is always the first parameter of every async routine. --*/ { RPC_STATUS RpcStatus ; RPC_MESSAGE Message ; FOOPIPE_ASYNC_CLIENT_STATE *StubInfo ; StubInfo = (FOOPIPE_ASYNC_CLIENT_STATE *) I_RpcAllocate ( sizeof(FOOPIPE_ASYNC_CLIENT_STATE)) ; if (StubInfo == 0) { RpcRaiseException(RPC_S_OUT_OF_MEMORY) ; } pAsync->StubInfo = (void *) StubInfo ; StubInfo->StubState.CallHandle = hBinding ; Message.Handle = hBinding ; Message.BufferLength = 4 ; Message.ProcNum = FooPipeProcnum | HackForOldStubs | RPC_FLAGS_VALID_BIT ; Message.RpcInterfaceInformation = &IsabelleInterfaceInformation ; Message.RpcFlags = RPC_BUFFER_ASYNC | RPC_BUFFER_PARTIAL ; RpcStatus = I_RpcGetBuffer(&Message) ; if (RpcStatus) { RpcRaiseException(RpcStatus) ; } // initialize the async handle and register it with the // RPC runtime. StubInfo->StubState.PipeState.Buffer = 0; StubInfo->StubState.PipeState.CurrentState = start; StubInfo->StubState.PipeState.CurPointer = 0; StubInfo->StubState.PipeState.BytesRemaining = 0; StubInfo->StubState.PipeState.EndOfPipe = 0; StubInfo->StubState.PipeState.PipeElementSize = sizeof(int); StubInfo->StubState.PipeState.PartialPipeElement = &tempint; StubInfo->StubState.PipeState.PreviousBuffer = 0; RpcStatus = I_RpcAsyncSetHandle(&Message, pAsync) ; if (RpcStatus) { RpcRaiseException(RpcStatus) ; } *((int *) Message.Buffer) = checksum_in ; inpipe->PipeSend = PipeSendFunction ; outpipe->PipeReceive = PipeReceiveFunction; StubInfo->StubState.CompletionRoutine = FooPipeComplete ; StubInfo->checksum_out = checksum_out ; Message.RpcFlags = RPC_BUFFER_PARTIAL| RPC_BUFFER_ASYNC; RpcStatus = I_RpcSend(&Message) ; if (RpcStatus == RPC_S_OK) { StubInfo->StubState.State = SEND_COMPLETE ; } else if (RpcStatus == RPC_S_SEND_INCOMPLETE) { StubInfo->StubState.State = SEND_INCOMPLETE ; } else { RpcRaiseException(RpcStatus) ; } StubInfo->StubState.CallHandle = Message.Handle ; StubInfo->StubState.Buffer = Message.Buffer ; StubInfo->StubState.BufferLength = Message.BufferLength ; } //////////////////////////////////////////////////////////// // End, stubs for FooPipe // //////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////// // Begin, Application // //////////////////////////////////////////////////////////// typedef struct { RPC_ASYNC_STATE Async ; async_intpipe inpipe ; async_intpipe outpipe ; BOOL CallFinished ; BOOL PipeDataSent; int checksum_out; int PipeChecksum ; int PipeBuffer[ASYNC_CHUNK_SIZE] ; int ExpectedValue; int i ; } PIPE_CALL_COOKIE ; int PipeCount = 0; void FooPipeAPCRoutine ( IN PRPC_ASYNC_STATE pAsync, IN void *Context, IN RPC_ASYNC_EVENT Event ) /*++ Routine Description: description Arguments: arg1 - description --*/ { PIPE_CALL_COOKIE *Cookie = (PIPE_CALL_COOKIE *) pAsync->UserInfo ; switch (Event) { case RpcSendComplete: if (Cookie->i % 7) { Sleep(10); } if (Cookie->i i++ ; Status = Cookie->inpipe.PipeSend( pAsync, 0, (int *) Cookie->PipeBuffer, ASYNC_CHUNK_SIZE) ; } else { ASSERT(Cookie->PipeDataSent == 0); pAsync->Flags = 0; Status = Cookie->inpipe.PipeSend( pAsync, 0, 0, 0) ; Cookie->PipeDataSent = 1; } if (Status != RPC_S_OK) { PrintToConsole("FooPipeAPCRoutine: PipeSend failed\n"); IsabelleError(); } break; case RpcCallComplete: Cookie->CallFinished = 1; OutstandingCalls-- ; break; } } void CallFooPipe ( RPC_BINDING_HANDLE Binding, PIPE_CALL_COOKIE *Cookie, RPC_NOTIFICATION_TYPES NotificationType ) /*++ Routine Description: description Arguments: arg1 - description --*/ { int Checksum = 0; int n ; int *ptr ; Cookie->Async.Size = sizeof(RPC_ASYNC_STATE) ; Cookie->Async.UserInfo = (void *) Cookie ; Cookie->outpipe.state = 0; Cookie->inpipe.state = 0; Cookie->PipeChecksum = 0; Cookie->CallFinished = 0; Cookie->i = 0; Cookie->PipeDataSent = 0; Cookie->Async.Flags = 0; Cookie->Async.Lock = 0; Cookie->ExpectedValue = 0; switch (NotificationType) { case RpcNotificationTypeNone: break; case RpcNotificationTypeEvent: Cookie->Async.NotificationType = RpcNotificationTypeEvent ; Cookie->Async.u.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL) ; if (Cookie->Async.u.hEvent == 0) { RpcRaiseException(APP_ERROR) ; } break; case RpcNotificationTypeApc: Cookie->Async.Flags = RPC_C_NOTIFY_ON_SEND_COMPLETE; Cookie->Async.NotificationType = RpcNotificationTypeApc ; Cookie->Async.u.APC.NotificationRoutine = FooPipeAPCRoutine ; Cookie->Async.u.APC.hThread = 0 ; break; default: PrintToConsole("Async: bad notification type\n") ; break; } ptr = Cookie->PipeBuffer ; for (n = 0; n Async), Binding, Checksum, &(Cookie->inpipe), &(Cookie->outpipe), &(Cookie->checksum_out)) ; } void AsyncPipesUsingAPC( RPC_BINDING_HANDLE Binding ) /*++ Routine Description: Call the async function. Arguments: Binding - Binding handle. --*/ { RPC_STATUS Status ; PIPE_CALL_COOKIE *Cookie; int retval ; BOOL fDone = 0; int num_elements; int i; RpcTryExcept { Cookie = new PIPE_CALL_COOKIE ; if (Cookie == 0) { RpcRaiseException(RPC_S_OUT_OF_MEMORY) ; } CallFooPipe (Binding, Cookie, RpcNotificationTypeApc) ; while (Cookie->PipeDataSent == 0) { if (SleepEx(INFINITE, TRUE) != WAIT_IO_COMPLETION) { RpcRaiseException(APP_ERROR) ; } } while (!fDone) { Status = Cookie->outpipe.PipeReceive( &(Cookie->Async), (int *) Cookie->PipeBuffer, ASYNC_CHUNK_SIZE, &num_elements); switch (Status) { case RPC_S_ASYNC_CALL_PENDING: if (SleepEx(INFINITE, TRUE) != WAIT_IO_COMPLETION) { RpcRaiseException(APP_ERROR) ; } break; case RPC_S_OK: if (num_elements == 0) { fDone = 1; } else { for (i = 0; i PipeChecksum += Cookie->PipeBuffer[i] ; if (Cookie->PipeBuffer[i] != Cookie->ExpectedValue) { printf("pipe recv fn: elt %d contains %lx, expected %lx\n", i, Cookie->PipeBuffer[i], Cookie->ExpectedValue); DebugBreak(); } Cookie->ExpectedValue = (Cookie->PipeBuffer[i]+1) % ASYNC_CHUNK_SIZE; } } break; default: fDone = 1; break; } // // This code is for testing flow control // PipeCount++; if (PipeCount % 3) { Sleep(100); } } if (Status != RPC_S_OK) { RpcRaiseException(Status); } while (Cookie->CallFinished == 0) { if (SleepEx(INFINITE, TRUE) != WAIT_IO_COMPLETION) { RpcRaiseException(APP_ERROR) ; } } Status = MyRpcCompleteAsyncCall(&Cookie->Async, &retval) ; if (Status != RPC_S_OK) { RpcRaiseException(Status) ; } if (retval != 1) { RpcRaiseException(APP_ERROR) ; } if (Cookie->PipeChecksum != Cookie->checksum_out) { PrintToConsole("FooPipe: Checksum Error, expected: %d, checksum: %d\n", Cookie->checksum_out, Cookie->PipeChecksum) ; RpcRaiseException(APP_ERROR) ; } } RpcExcept(I_RpcExceptionFilter(RpcExceptionCode())) { PrintToConsole("FooPipe: Exception 0x%lX\n", GetExceptionCode()) ; IsabelleError() ; } RpcEndExcept if (Cookie) { delete Cookie ; } } void MultipleOutstandingCalls ( IN RPC_BINDING_HANDLE Binding, IN int NumCalls ) /*++ Routine Description: tests multiple outstanding calls and causal ordering Arguments: Binding - Binding on which to make the calls NumCalls - Number of outstanding calls --*/ { RPC_STATUS Status ; PIPE_CALL_COOKIE *PipeCookies; CALL_COOKIE *Cookies ; int retval ; int i ; int SizeIn, SizeOut ; RpcTryExcept { Cookies = new CALL_COOKIE[NumCalls] ; if (Cookies == 0) { RpcRaiseException(APP_ERROR) ; } PipeCookies = new PIPE_CALL_COOKIE[NumCalls] ; if (PipeCookies == 0) { RpcRaiseException(APP_ERROR) ; } OutstandingCalls = 0; SizeIn = 10; SizeOut = 10 ; for (i = 0; i < NumCalls; i++) { CallFoo(Binding, &Cookies[i], RpcNotificationTypeApc, SizeIn, SizeOut) ; SizeIn += 100 ; SizeOut+= 100 ; OutstandingCalls++ ; } while (OutstandingCalls) { if (SleepEx(INFINITE, TRUE) != WAIT_IO_COMPLETION) { RpcRaiseException(APP_ERROR) ; } } for (i = 0; i < NumCalls; i++) { Status = MyRpcCompleteAsyncCall(&Cookies[i].Async, &retval) ; if (Status != RPC_S_OK) { PrintToConsole("Call %d on handle %p returned %d\n", i, &Cookies[i].Async, Status); continue; } TRACE(("Async: MyRpcCompleteAsyncCall returned %d\n", retval)) ; if (retval != 1) { RpcRaiseException(APP_ERROR) ; } I_RpcFree(Cookies[i].BufferOut) ; } } RpcExcept(I_RpcExceptionFilter(RpcExceptionCode())) { PrintToConsole("MultipeOutstandingCalls: Exception 0x%lX\n", GetExceptionCode()) ; IsabelleError() ; } RpcEndExcept if (Cookies) { delete Cookies ; } if (PipeCookies) { delete PipeCookies ; } } void SyncAsyncInterop ( IN RPC_BINDING_HANDLE Binding, IN int SizeIn, IN int SizeOut ) /*++ Routine Description: description Arguments: arg1 - description --*/ { int retval ; int *bufferout ; int *bufferin ; RpcTryExcept { bufferin = (int *) I_RpcAllocate(SizeIn) ; if (bufferin == 0) { RpcRaiseException(APP_ERROR) ; } // sync client, async server retval = FooSync (Binding, SizeIn, bufferin, &SizeOut, &bufferout) ; if (retval != 1) { RpcRaiseException(APP_ERROR) ; } I_RpcFree(bufferout) ; // ugly hack alert FooProcnum = 18 ; // async client, sync server (calling FooBar) AsyncUsingAPC(Binding, SizeIn, SizeOut) ; FooProcnum = 16 ; // sync client, async server using pipes // async client, sync server using pipes } RpcExcept(I_RpcExceptionFilter(RpcExceptionCode())) { PrintToConsole("SyncAsyncInterop: Exception 0x%lX\n", GetExceptionCode()) ; IsabelleError() ; } RpcEndExcept } void InitLsaString( PLSA_UNICODE_STRING LsaString, LPWSTR String ) { DWORD StringLength; if (String == NULL) { LsaString->Buffer = NULL; LsaString->Length = 0; LsaString->MaximumLength = 0; return; } StringLength = lstrlenW(String); LsaString->Buffer = String; LsaString->Length = (USHORT) StringLength * sizeof(WCHAR); LsaString->MaximumLength=(USHORT)(StringLength+1) * sizeof(WCHAR); } NTSTATUS SetPrivilegeOnAccount( LSA_HANDLE PolicyHandle, // open policy handle PSID AccountSid, // SID to grant privilege to LPWSTR PrivilegeName, // privilege to grant (Unicode) BOOL bEnable // enable or disable ) { LSA_UNICODE_STRING PrivilegeString; // // Create a LSA_UNICODE_STRING for the privilege name. // InitLsaString(&PrivilegeString, PrivilegeName); // // grant or revoke the privilege, accordingly // if(bEnable) { return LsaAddAccountRights( PolicyHandle, // open policy handle AccountSid, // target SID &PrivilegeString, // privileges 1 // privilege count ); } else { return LsaRemoveAccountRights( PolicyHandle, // open policy handle AccountSid, // target SID FALSE, // do not disable all rights &PrivilegeString, // privileges 1 // privilege count ); } } DWORD AddServicePrivToAccount( LPWSTR MachineName, LPWSTR pAccount ) /*++ Routine Description: Enables the appropriate privileges for the cluster account and sets up the cluster service to run in the specified account. Arguments: None Return Value: ERROR_SUCCESS if successful Win32 error code otherwise --*/ { LSA_HANDLE PolicyHandle; LSA_OBJECT_ATTRIBUTES ObjectAttributes; LSA_UNICODE_STRING ServerString; PLSA_UNICODE_STRING Server = NULL; NTSTATUS Status; WCHAR domain[MAX_PATH]; PSID pSid; SID_NAME_USE sidType; DWORD nBytes; DWORD maxDomain; if (MachineName != NULL) { InitLsaString(&ServerString, MachineName); Server = &ServerString; } PrintToConsole("Machine: %ls, Account: %ls.\n",MachineName,pAccount); nBytes=0; maxDomain=MAX_PATH*sizeof(WCHAR); if (LookupAccountName(MachineName,pAccount,NULL,&nBytes, domain,&maxDomain,&sidType)) { PrintToConsole("AddServicePrivToAccount: LookupAccountName(NULL) failed.\n"); return ERROR_INVALID_PARAMETER; } pSid=LocalAlloc(LPTR,nBytes); if (NULL == pSid) { PrintToConsole("AddServicePrivToAccount: LocalAlloc failed.\n"); return GetLastError(); } if (!LookupAccountName(MachineName,pAccount,pSid,&nBytes, domain,&maxDomain,&sidType)) { PrintToConsole( "AddServicePrivToAccount: LookupAccountName(%ls) failed.\n", pAccount); return GetLastError(); } // // Always initialize the object attributes to all zeroes. // ZeroMemory(&ObjectAttributes, sizeof(ObjectAttributes)); // // Attempt to open the local policy. // Status = LsaOpenPolicy(Server, &ObjectAttributes, POLICY_CREATE_ACCOUNT | POLICY_LOOKUP_NAMES, &PolicyHandle); if (MachineName != NULL) { if (!NT_SUCCESS(Status)) { // // We could not contact the PDC to configure the service account. // Put up a nice informative popup and let the user run setup // again when the PDC is back. // PrintToConsole("AddServicePrivToAccount: LsaOpenPolicy failed.\n"); return(Status); } } else { if (!NT_SUCCESS(Status)) { PrintToConsole( "AddServicePrivToAccount: LsaOpenPolicy failed 2.\n"); return(Status); } } // // Add the SeTcbPriviledge // Status = SetPrivilegeOnAccount(PolicyHandle, pSid, SE_TCB_NAME, TRUE); if (!NT_SUCCESS(Status)) { PrintToConsole( "AddServicePrivToAccount: SetPrivilegeOnAccount(tcb).\n"); goto AddServicePrivToAccount_Bail; } // // Add the SeServiceLogonRight // Status = SetPrivilegeOnAccount(PolicyHandle, pSid, SE_SERVICE_LOGON_NAME, TRUE); if (!NT_SUCCESS(Status)) { PrintToConsole( "AddServicePrivToAccount: SetPrivilegeOnAccount(logon).\n"); goto AddServicePrivToAccount_Bail; } // // Add the SeBackupPrivilege // Status = SetPrivilegeOnAccount(PolicyHandle, pSid, SE_BACKUP_NAME, TRUE); if (!NT_SUCCESS(Status)) { PrintToConsole( "AddServicePrivToAccount: SetPrivilegeOnAccount(backup).\n"); goto AddServicePrivToAccount_Bail; } // // Add the SeRestorePrivilege // Status = SetPrivilegeOnAccount(PolicyHandle, pSid, SE_RESTORE_NAME, TRUE); if (!NT_SUCCESS(Status)) { PrintToConsole( "AddServicePrivToAccount: SetPrivilegeOnAccount(restore).\n"); goto AddServicePrivToAccount_Bail; } // // Add the lock memory privilege // Status = SetPrivilegeOnAccount(PolicyHandle, pSid, SE_LOCK_MEMORY_NAME, TRUE); if (!NT_SUCCESS(Status)) { PrintToConsole( "AddServicePrivToAccount: SetPrivilegeOnAccount(memory).\n"); goto AddServicePrivToAccount_Bail; } // // Add the increase quota privilege // Status = SetPrivilegeOnAccount(PolicyHandle, pSid, SE_INCREASE_QUOTA_NAME, TRUE); if (!NT_SUCCESS(Status)) { PrintToConsole( "AddServicePrivToAccount: SetPrivilegeOnAccount(quota).\n"); goto AddServicePrivToAccount_Bail; } // // Add the load driver privilege // Status = SetPrivilegeOnAccount(PolicyHandle, pSid, SE_LOAD_DRIVER_NAME, TRUE); if (!NT_SUCCESS(Status)) { PrintToConsole( "AddServicePrivToAccount: SetPrivilegeOnAccount(driver).\n"); goto AddServicePrivToAccount_Bail; } // // Add the increase base priority privilege // Status = SetPrivilegeOnAccount(PolicyHandle, pSid, SE_INC_BASE_PRIORITY_NAME, TRUE); if (!NT_SUCCESS(Status)) { PrintToConsole( "AddServicePrivToAccount: SetPrivilegeOnAccount(priority)\n"); goto AddServicePrivToAccount_Bail; } Status=ERROR_SUCCESS; AddServicePrivToAccount_Bail: // // Close the policy handle. // LsaClose(PolicyHandle); return(Status); } void AsyncSecurity ( IN RPC_BINDING_HANDLE Binding ) /*++ Routine Description: description Arguments: arg1 - description --*/ { HANDLE hToken; WCHAR FullName[512]; wsprintf((PWSTR) &FullName[0], L"%hs\\%hs", SecurityDomain, SecurityUser); AddServicePrivToAccount(L"", &FullName[0]); while (1) { if (LogonUserA(SecurityUser, SecurityDomain, SecurityPassword, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, &hToken) == 0) { PrintToConsole("LogonUser failed: %d\n", GetLastError()); break; } ImpersonateLoggedOnUser(hToken); // set auth info to various levels // and impersonate on the server Status = RpcBindingSetAuthInfo(Binding, NULL, RPC_C_AUTHN_DEFAULT, RPC_C_AUTHN_WINNT, NULL, NULL); AsyncUsingAPC(Binding, 20, 20); CloseHandle(hToken); } } void AsyncSecurityThreads() { int i; unsigned long ThreadIdentifier; HANDLE HandleToThread ; RPC_BINDING_HANDLE Binding; UUID ObjectUuid; GenerateUuidValue(UUID_TEST_CANCEL, &ObjectUuid); for (i = 0; i<3; i++) { Status = GetBinding(BARTHOLOMEW, &Binding); if (Status) { ApiError("Async", "GetBinding", Status); PrintToConsole("Async : FAIL - Unable to Bind (Async)\n"); return; } Status = RpcBindingSetObject(Binding, &ObjectUuid); if (Status) { ApiError("Async", "RpcBindingSetObject", Status); PrintToConsole("Async : FAIL - Unable to Set Object\n"); return; } HandleToThread = CreateThread( 0, DefaultThreadStackSize, (LPTHREAD_START_ROUTINE) AsyncSecurity, Binding, 0, &ThreadIdentifier); if (HandleToThread == 0) { PrintToConsole("AsyncSecurity: Error, couldn't create thread\n") ; IsabelleError(); return; } CloseHandle(HandleToThread); } Status = GetBinding(BARTHOLOMEW, &Binding); if (Status) { ApiError("Async", "GetBinding", Status); PrintToConsole("Async : FAIL - Unable to Bind (Async)\n"); return; } Status = RpcBindingSetObject(Binding, &ObjectUuid); if (Status) { ApiError("Async", "RpcBindingSetObject", Status); PrintToConsole("Async : FAIL - Unable to Set Object\n"); return; } AsyncSecurity(Binding); } void AsyncExceptions ( IN RPC_BINDING_HANDLE Binding ) /*++ Routine Description: description Arguments: arg1 - description --*/ { BOOL ExceptionOccured ; int ExceptionCode ; UUID SavedUuid; UUID ExceptionUuid; // // object UUID is used to control server-side exceptions: save the original one. // Status = RpcBindingInqObject(Binding, &SavedUuid); if (Status) { ApiError("Async", "RpcBindingInqObject", Status); PrintToConsole("Async : FAIL - Unable to save original object UUID\n"); return; } // test sync exceptions (async server) RpcTryExcept { ExceptionOccured = 0; ExceptionCode = 0; GenerateUuidValue(UUID_SYNC_EXCEPTION, &ExceptionUuid); Status = RpcBindingSetObject(Binding, &ExceptionUuid); if (Status) { ApiError("Async", "RpcBindingSetObject", Status); PrintToConsole("Async : FAIL - Unable to Set Object\n"); return; } AsyncUsingAPC(Binding, 0, 10) ; } RpcExcept(I_RpcExceptionFilter(RpcExceptionCode())) { ExceptionOccured = 1; ExceptionCode = GetExceptionCode() ; } RpcEndExcept if (ExceptionOccured == 0 || ExceptionCode != SYNC_EXCEPT) { PrintToConsole("Async: wrong exception value 0x%x\n", ExceptionCode ); IsabelleError() ; Status = RpcBindingSetObject(Binding, &SavedUuid); if (Status) { ApiError("Async", "RpcBindingSetObject", Status); PrintToConsole("Async : FAIL - Unable to restore original object UUID\n"); } return ; } // test sync exceptions (sync server) RpcTryExcept { ExceptionOccured = 0; ExceptionCode = 0; // ugly hack alert FooProcnum = 18 ; GenerateUuidValue(UUID_SYNC_EXCEPTION, &ExceptionUuid); Status = RpcBindingSetObject(Binding, &ExceptionUuid); if (Status) { ApiError("Async", "RpcBindingSetObject", Status); PrintToConsole("Async : FAIL - Unable to Set Object\n"); return; } // async client, sync server (calling FooBar) AsyncUsingAPC(Binding, 0, 10) ; } RpcExcept(I_RpcExceptionFilter(RpcExceptionCode())) { ExceptionOccured = 1; ExceptionCode = GetExceptionCode() ; } RpcEndExcept FooProcnum = 16 ; if (ExceptionOccured == 0 || ExceptionCode != SYNC_EXCEPT) { PrintToConsole("Async: wrong exception value 0x%x\n", ExceptionCode ); IsabelleError() ; Status = RpcBindingSetObject(Binding, &SavedUuid); if (Status) { ApiError("Async", "RpcBindingSetObject", Status); PrintToConsole("Async : FAIL - Unable to restore original object UUID\n"); } return ; } // test async exceptions RpcTryExcept { ExceptionOccured = 0; ExceptionCode = 0; GenerateUuidValue(UUID_ASYNC_EXCEPTION, &ExceptionUuid); Status = RpcBindingSetObject(Binding, &ExceptionUuid); if (Status) { ApiError("Async", "RpcBindingSetObject", Status); PrintToConsole("Async : FAIL - Unable to Set Object\n"); return; } AsyncUsingAPC(Binding, 10, 0) ; } RpcExcept(I_RpcExceptionFilter(RpcExceptionCode())) { ExceptionOccured = 1; ExceptionCode = GetExceptionCode() ; } RpcEndExcept if (ExceptionOccured == 0 || ExceptionCode != ASYNC_EXCEPT) { PrintToConsole("Async: wrong exception value 0x%x\n", ExceptionCode ); IsabelleError() ; } Status = RpcBindingSetObject(Binding, &SavedUuid); if (Status) { ApiError("Async", "RpcBindingSetObject", Status); PrintToConsole("Async : FAIL - Unable to restore original object UUID\n"); } } //////////////////////////////////////////////////////////// // Begin, stubs for FooCH // //////////////////////////////////////////////////////////// typedef struct { RPC_ASYNC_STUB_STATE StubState ; void *state ; int *sizeout ; int **bufferout ; } FOOCH_ASYNC_CLIENT_STATE; RPC_STATUS FooCHComplete( IN PRPC_ASYNC_STATE pAsync, OUT void *Reply ) /*++ Routine Description: The completion routine corresponding to the function Foo. This routine is called to get the out parameters from an async function. Arguments: pAsync - Async Handle. The async handle is always the first parameter of every async routine. --*/ { RPC_STATUS Status ; RPC_MESSAGE Message ; int *ptr ; FOOCH_ASYNC_CLIENT_STATE *StubInfo = (FOOCH_ASYNC_CLIENT_STATE *) pAsync->StubInfo ; Message.RpcInterfaceInformation = &IsabelleInterfaceInformation ; Message.RpcFlags = RPC_BUFFER_ASYNC; Message.Handle = StubInfo->StubState.CallHandle ; Message.Buffer = StubInfo->StubState.Buffer ; Message.BufferLength = StubInfo->StubState.BufferLength ; Status = I_RpcReceive(&Message, 0) ; if (Status) { return Status ; } ptr = (int *) Message.Buffer ; *((int *) Reply) = *ptr++ ; *(StubInfo->sizeout) = *ptr++ ; *(StubInfo->bufferout) = (int *) I_RpcAllocate(*(StubInfo->sizeout)) ; if (*(StubInfo->bufferout) == 0) { return RPC_S_OUT_OF_MEMORY ; } RpcpMemoryCopy(*(StubInfo->bufferout), ptr, *(StubInfo->sizeout)) ; I_RpcFreeBuffer(&Message) ; I_RpcFree(StubInfo) ; return RPC_S_OK ; } void FooCH ( PRPC_ASYNC_STATE pAsync, /* [in] */ void PAPI *ContextHandle, /* [in] */ int sizein, /* [in] */ int *bufferin, /* [in, out] */ int *sizeout, /* [out] */ int **bufferout ) /*++ Routine Description: Client stub for function FooCH. Arguments: pAsync - Async Handle. The async handle is always the first parameter of every async routine. --*/ { RPC_STATUS RpcStatus ; RPC_MESSAGE Message ; FOOCH_ASYNC_CLIENT_STATE *StubInfo ; int *Ptr ; StubInfo = (FOOCH_ASYNC_CLIENT_STATE *) I_RpcAllocate ( sizeof(FOOCH_ASYNC_CLIENT_STATE)) ; if (StubInfo == 0) { RpcRaiseException(RPC_S_OUT_OF_MEMORY) ; } pAsync->StubInfo = (void *) StubInfo ; StubInfo->StubState.CallHandle = NDRCContextBinding(ContextHandle) ; Message.Handle = StubInfo->StubState.CallHandle; Message.BufferLength = 20+8+sizein+(sizein%4) ; Message.ProcNum = 19 | HackForOldStubs | RPC_FLAGS_VALID_BIT ; Message.RpcInterfaceInformation = &IsabelleInterfaceInformation ; Message.RpcFlags = RPC_BUFFER_ASYNC ; RpcStatus = I_RpcGetBuffer(&Message) ; if (RpcStatus) { RpcRaiseException(RpcStatus) ; } // marshal ;-) Ptr = (int *) Message.Buffer ; NDRCContextMarshall(ContextHandle, Ptr) ; Ptr += 20 / sizeof(int) ; *Ptr++ = sizein ; RpcpMemoryCopy(Ptr, bufferin, sizein) ; Ptr += (sizein+3)/sizeof(int) ; *Ptr = *sizeout ; StubInfo->StubState.Flags = 0; StubInfo->sizeout = sizeout ; StubInfo->bufferout = bufferout ; RpcStatus = I_RpcAsyncSetHandle(&Message, (PRPC_ASYNC_STATE) pAsync) ; if (RpcStatus) { RpcRaiseException(RpcStatus) ; } StubInfo->StubState.CompletionRoutine = FooCHComplete ; Message.RpcFlags = RPC_BUFFER_ASYNC; RpcStatus = I_RpcSend(&Message) ; if (RpcStatus) { RpcRaiseException(RpcStatus) ; } StubInfo->StubState.CallHandle = Message.Handle ; StubInfo->StubState.Buffer = Message.Buffer ; StubInfo->StubState.BufferLength = Message.BufferLength ; // return to the app } typedef struct { RPC_ASYNC_STATE Async ; int SizeOut ; int *BufferOut ; BOOL CallFinished ; void PAPI *ContextHandle ; } FOOCH_CALL_COOKIE ; void FooCHAPCRoutine ( IN PRPC_ASYNC_STATE pAsync, IN void *Context, IN RPC_ASYNC_EVENT Event ) /*++ Routine Description: description Arguments: arg1 - description --*/ { FOOCH_CALL_COOKIE *Cookie = (FOOCH_CALL_COOKIE *) pAsync->UserInfo ; switch (Event) { case RpcCallComplete: Cookie->CallFinished = 1; OutstandingCalls--; break; } } void CallFooCH ( RPC_BINDING_HANDLE BindingHandle, FOOCH_CALL_COOKIE *Cookie, RPC_NOTIFICATION_TYPES NotificationType, int SizeIn, int SizeOut ) /*++ Routine Description: description Arguments: arg1 - description --*/ { int *BufferIn ; unsigned long ContextUuid[5]; Cookie->ContextHandle = 0; ContextUuid[0] = 0; ContextUuid[1] = 1; ContextUuid[2] = 2; ContextUuid[3] = 3; ContextUuid[4] = 4; NDRCContextUnmarshall(&(Cookie->ContextHandle), BindingHandle, ContextUuid, 0x00L | 0x10L | 0x0000L); BufferIn = (int *) new char[SizeIn] ; if (BufferIn == 0) { RpcRaiseException(APP_ERROR) ; } Cookie->SizeOut = SizeOut ; Cookie->Async.Size = sizeof(RPC_ASYNC_STATE) ; Cookie->Async.Flags = 0; Cookie->Async.Lock = 0; Cookie->Async.NotificationType = NotificationType ; switch (NotificationType) { case RpcNotificationTypeNone: break; case RpcNotificationTypeEvent: Cookie->Async.u.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL) ; if (Cookie->Async.u.hEvent == 0) { RpcRaiseException(APP_ERROR) ; } Cookie->Async.NotificationType = RpcNotificationTypeEvent ; break; case RpcNotificationTypeApc: Cookie->Async.NotificationType = RpcNotificationTypeApc ; Cookie->Async.u.APC.NotificationRoutine = FooCHAPCRoutine ; Cookie->Async.u.APC.hThread = 0; Cookie->CallFinished = 0; break; default: PrintToConsole("Async: bad notification type\n") ; break; } Cookie->Async.UserInfo = (void *) Cookie ; // call the async function // the buffers supplied for the [out] and the [in, out] params // should be valid until the logical RPC call has completed. FooCH(&Cookie->Async, Cookie->ContextHandle, SizeIn, BufferIn, &Cookie->SizeOut, &Cookie->BufferOut) ; delete BufferIn ; } void ContextHandles( RPC_BINDING_HANDLE Binding, int SizeIn, int SizeOut ) /*++ Routine Description: The code that calls the async function. Arguments: Binding - the binding handle. --*/ { RPC_STATUS Status ; FOOCH_CALL_COOKIE Cookie ; int retval ; RpcTryExcept { CallFooCH(Binding, &Cookie, RpcNotificationTypeApc, SizeIn, SizeOut) ; WaitForReply(&(Cookie.CallFinished)); Status = MyRpcCompleteAsyncCall(&Cookie.Async, &retval) ; if (Status != RPC_S_OK) { RpcRaiseException(Status) ; } TRACE(("Async: MyRpcCompleteAsyncCall returned %d\n", retval)) ; if (retval != 1) { RpcRaiseException(APP_ERROR) ; } RpcSsDestroyClientContext(&(Cookie.ContextHandle)); if ( Cookie.ContextHandle != 0 ) { PrintToConsole("Async : ContextHandle != 0\n"); RpcRaiseException(APP_ERROR) ; } I_RpcFree(Cookie.BufferOut) ; } RpcExcept(I_RpcExceptionFilter(RpcExceptionCode())) { PrintToConsole("FooCH: Exception 0x%lX\n", GetExceptionCode()) ; Status = GetExceptionCode() ; if (Status == SYNC_EXCEPT || Status == ASYNC_EXCEPT) { RpcRaiseException(Status) ; } else { IsabelleError() ; } } RpcEndExcept } int AsyncSizes[] = { 20, 100, 256, 1024, 10000, 100000 } ; #define CHECK_ERRORS \ if (IsabelleErrors != 0)\ {\ PrintToConsole("Async : FAIL - Error(s) in Isabelle");\ PrintToConsole(" Interface\n");\ IsabelleShutdown(Async);\ IsabelleErrors = 0;\ return;\ } void PingServer ( RPC_BINDING_HANDLE Binding ) { RPC_MESSAGE Caller; Caller.Handle = Binding; Caller.BufferLength = 0; Caller.ProcNum = 4 | HackForOldStubs ; Caller.RpcInterfaceInformation = &HelgaInterfaceInformation ; Caller.RpcFlags = 0; if (UclntGetBuffer(&Caller) != RPC_S_OK) { IsabelleError(); return ; } if (UclntSendReceive(&Caller) != RPC_S_OK) { IsabelleError(); return; } if (I_RpcFreeBuffer(&Caller) != RPC_S_OK) { IsabelleError(); } } long PendingCalls; void AsyncPingProc( IN PRPC_MESSAGE Message ) { if (UclntSendReceive(Message) != RPC_S_OK) { IsabelleError(); InterlockedDecrement(&PendingCalls); return; } InterlockedDecrement(&PendingCalls); } void AsyncPingServer ( RPC_BINDING_HANDLE Binding ) { RPC_MESSAGE Caller[20]; unsigned long ThreadIdentifier; HANDLE HandleToThread ; int i; for (i = 0; i <20; i++) { Caller[i].Handle = Binding; Caller[i].BufferLength = 0; Caller[i].ProcNum = 4 | HackForOldStubs ; Caller[i].RpcInterfaceInformation = &HelgaInterfaceInformation ; Caller[i].RpcFlags = 0; if (UclntGetBuffer(&Caller[i]) != RPC_S_OK) { IsabelleError(); return ; } } PendingCalls = 20; for (i = 0; i<20; i++) { HandleToThread = CreateThread( 0, DefaultThreadStackSize, (LPTHREAD_START_ROUTINE) AsyncPingProc, &Caller[i], 0, &ThreadIdentifier); if (HandleToThread == 0) { PrintToConsole("AsyncPingServer: Error, couldn't create thread\n") ; IsabelleError(); return; } } while (PendingCalls) { Sleep(1000); } for (i = 0; i < 20; i++) { if (I_RpcFreeBuffer(&Caller[i]) != RPC_S_OK) { IsabelleError(); } } } void AsyncCancels ( IN RPC_BINDING_HANDLE Binding ) { RPC_STATUS Status ; CALL_COOKIE Cookie ; int retval ; RpcTryExcept { // // Test non abortive cancels // CallFoo(Binding, &Cookie, RpcNotificationTypeApc, 20, 20) ; Sleep(10); // // non abortive cancel // Status = RpcAsyncCancelCall(&Cookie.Async, 0); if (Status != RPC_S_OK) { RpcRaiseException(Status); } WaitForReply(&(Cookie.CallFinished)); Status = MyRpcCompleteAsyncCall(&Cookie.Async, &retval) ; if (Status != RPC_S_OK) { RpcRaiseException(Status) ; } TRACE(("Async: MyRpcCompleteAsyncCall returned %d\n", retval)) ; // // Test abortive cancels // CallFoo(Binding, &Cookie, RpcNotificationTypeApc, 20, 20) ; Sleep(10); // // Abortive cancel // Status = RpcAsyncCancelCall(&Cookie.Async, 1); if (Status != RPC_S_OK) { RpcRaiseException(Status); } WaitForReply(&(Cookie.CallFinished)); Status = MyRpcCompleteAsyncCall(&Cookie.Async, &retval) ; if (Status != RPC_S_CALL_CANCELLED) { RpcRaiseException(Status) ; } TRACE(("Async: MyRpcCompleteAsyncCall returned %d\n", retval)) ; } RpcExcept(I_RpcExceptionFilter(RpcExceptionCode())) { PrintToConsole("Foo: Exception 0x%lX\n", GetExceptionCode()) ; Status = GetExceptionCode() ; if (Status == SYNC_EXCEPT || Status == ASYNC_EXCEPT) { RpcRaiseException(Status) ; } else { IsabelleError() ; } } RpcEndExcept } #define LAST 15 extern void AsyncAll ( void ) /*++ Routine Description: Loop through all Async tests. --*/ { int i; for( i = 0; i < LAST; i ++) { Async(i); } } void Async ( int testnum ) /*++ Routine Description: Invoke the tests. --*/ { int i ; UUID ObjectUuid; UUID CancelUuid; RPC_BINDING_HANDLE Async; RPC_BINDING_HANDLE AsyncBind; if (testnum > LAST) { PrintToConsole("Async tests:\n") ; PrintToConsole("0: Run all the tests\n") ; PrintToConsole("1: Async using APCs, events and polling\n") ; PrintToConsole("2: Async pipes using events\n") ; PrintToConsole("3: Async pipes using APC, and flow control\n") ; PrintToConsole("4: Async with security\n") ; PrintToConsole("5: Sync and async exceptions\n") ; PrintToConsole("6: Multiple outstanding calls and causal ordering\n") ; PrintToConsole("7: Context handles\n") ; PrintToConsole("8: Sync/Async interop\n") ; PrintToConsole("9: Async ping server") ; PrintToConsole("10: Alter context during async calls\n") ; PrintToConsole("11: Async cancels\n") ; PrintToConsole("12: Multiple outstanding non causal calls\n") ; PrintToConsole("13: Rebinds on secure calls with uuids\n") ; NumberOfTestsRun++ ; return ; } Synchro(BARTHOLOMEW) ; if ( NumberOfTestsRun++ ) { PauseExecution(TestDelay); } PrintToConsole("Async : Test Async RPC\n"); Status = GetBinding(BARTHOLOMEW, &Async); if (Status) { ApiError("Async", "GetBinding", Status); PrintToConsole("Async : FAIL - Unable to Bind (Async)\n"); return; } #if 0 PingServer(Async); CHECK_ERRORS; #endif SyncEvent = CreateEvent(NULL, FALSE, FALSE, NULL) ; if (SyncEvent == 0) { ApiError("Async", "CreateEvent", Status); return; } GenerateUuidValue(UUID_TEST_CANCEL, &ObjectUuid); Status = RpcBindingSetObject(Async, &ObjectUuid); if (Status) { ApiError("Async", "RpcBindingSetObject", Status); PrintToConsole("Async : FAIL - Unable to Set Object\n"); return; } if (fNonCausal) { Status = RpcBindingSetOption(Async, RPC_C_OPT_BINDING_NONCAUSAL, 1); if (Status) { ApiError("Async", "RpcBindingSetOption", Status); PrintToConsole("Async : FAIL - Unable to Set Option\n"); return; } } switch (testnum) { case 0: case 1: PrintToConsole("Async: Testing async using APCs, events and polling\n") ; for (i = 0; i < sizeof(AsyncSizes)/sizeof(int); i++) { AsyncUsingAPC(Async, AsyncSizes[i], AsyncSizes[i]) ; CHECK_ERRORS; AsyncUsingEvent(Async, AsyncSizes[i], AsyncSizes[i]) ; CHECK_ERRORS; AsyncUsingPolling(Async, AsyncSizes[i], AsyncSizes[i]) ; CHECK_ERRORS; } if (testnum != 0) { break; } case 2: PrintToConsole("Async: Testing async pipes using events\n") ; CHECK_ERRORS; if (testnum != 0) { break; } case 3: PrintToConsole("Async: Testing async async pipes using APC, and flow control\n") ; AsyncPipesUsingAPC(Async) ; CHECK_ERRORS; if (testnum != 0) { break; } case 4: if (testnum != 0) { PrintToConsole("Async: Testing security\n") ; AsyncSecurityThreads() ; CHECK_ERRORS; break; } case 5: PrintToConsole("Async: Testing sync and async exceptions\n") ; AsyncExceptions(Async) ; CHECK_ERRORS; if (testnum != 0) { break; } case 6: PrintToConsole("Async: Testing multiple outstanding calls and causal ordering\n") ; MultipleOutstandingCalls(Async, 20) ; CHECK_ERRORS; if (testnum != 0) { break; } case 7: PrintToConsole("Async: Testing context handles\n") ; ContextHandles(Async, 20, 20) ; if (testnum != 0) { break; } case 8: PrintToConsole("Async: Testing Sync/Async interop\n") ; for (i = 0; i < sizeof(AsyncSizes)/sizeof(int); i++) { SyncAsyncInterop(Async, AsyncSizes[i], AsyncSizes[i]) ; CHECK_ERRORS; } if (testnum != 0) { break; } case 9: AsyncPingServer(Async); CHECK_ERRORS; if (testnum != 0) { break; } case 10: // // make a few calls on the Isabelle interface // for (i=0; i<3; i++) { AsyncUsingAPC(Async, AsyncSizes[i], AsyncSizes[i]) ; CHECK_ERRORS; } FooProcnum = 7; FooInterface = &HelgaInterfaceInformation; // // make a few calls on the helga interface // this should cause an alter context // for (i=0; i<3; i++) { AsyncUsingAPC(Async, AsyncSizes[i], AsyncSizes[i]) ; CHECK_ERRORS; } FooProcnum = 16; FooInterface = &IsabelleInterfaceInformation; // // make a few calls on the Isabelle interface // for (i=0; i<3; i++) { AsyncUsingAPC(Async, AsyncSizes[i], AsyncSizes[i]) ; CHECK_ERRORS; } if (testnum != 0) { break; } case 11: PrintToConsole("Async: Test async cancels\n"); GenerateUuidValue(UUID_SLEEP_1000, &ObjectUuid); Status = RpcBindingSetObject(Async, &ObjectUuid); if (Status) { ApiError("Async", "RpcBindingSetObject", Status); PrintToConsole("Async : FAIL - Unable to Set Object\n"); return; } AsyncCancels(Async); CHECK_ERRORS; if (testnum != 0) { break; } case 12: PrintToConsole("Async: Testing multiple outstanding calls and causal ordering\n") ; Status = RpcBindingSetOption(Async, RPC_C_OPT_BINDING_NONCAUSAL, TRUE); if (Status) { ApiError("Async", "RpcBindingSetOption", Status); return; } MultipleOutstandingCalls(Async, 20) ; CHECK_ERRORS; if (testnum != 0) { break; } case 13: RpcBindingFree(&Async); Status = GetBinding(BARTHOLOMEW, &Async); if (Status) { ApiError("Async", "GetBinding", Status); PrintToConsole("Async : FAIL - Unable to Bind (Async)\n"); return; } PrintToConsole("Async: Bind and async calls\n") ; for (i = 0; i < 10; i++) { Status = GetBinding(BARTHOLOMEW, &AsyncBind); if (Status) { ApiError("Async", "GetBinding", Status); PrintToConsole("Async : FAIL - Unable to Bind (Async)\n"); return; } Status = RpcBindingSetObject(AsyncBind, &ObjectUuid); if (Status) { ApiError("Async", "RpcBindingSetObject", Status); PrintToConsole("Async : FAIL - Unable to Set Object\n"); return; } Status = RpcBindingSetAuthInfoA(AsyncBind, (unsigned char *) "ServerPrincipal", RPC_C_AUTHN_LEVEL_CONNECT, 10, NULL, 0); if (Status) { ApiError("Async", "RpcBindingSetAuthInfo", Status); PrintToConsole("Async : FAIL - Unable to Set AuthInfo\n"); return; } AsyncUsingAPC(AsyncBind, 10, 10) ; CHECK_ERRORS; RpcBindingFree(&AsyncBind); } if (testnum != 0) { break; } case 14: Status = GetBinding(BARTHOLOMEW, &Async); if (Status) { ApiError("Async", "GetBinding", Status); PrintToConsole("Async : FAIL - Unable to Bind (Async)\n"); return; } FooProcnum = 7; FooInterface = &HelgaInterfaceInformation; // // make a few calls on the helga interface // this should cause an alter context // for (i=0; i<3; i++) { AsyncUsingAPC(Async, AsyncSizes[i], AsyncSizes[i]) ; CHECK_ERRORS; } if (testnum != 0) { break; } case LAST: PrintToConsole("hacked-up test\n"); GenerateUuidValue(UUID_SLEEP_2000, &ObjectUuid); Status = RpcBindingSetObject(Async, &ObjectUuid); if (Status) { ApiError("Async", "RpcBindingSetObject", Status); PrintToConsole("Async : FAIL - Unable to Set Object\n"); return; } AsyncUsingEvent( Async, 100, 100 ); if (testnum != 0) { break; } default: PrintToConsole("Async tests:\n") ; PrintToConsole("0: Run all the tests\n") ; PrintToConsole("1: Async using APCs, events and polling\n") ; PrintToConsole("2: Async pipes using events\n") ; PrintToConsole("3: Async pipes using APC, and flow control\n") ; PrintToConsole("4: Async with security\n") ; PrintToConsole("5: Sync and async exceptions\n") ; PrintToConsole("6: Multiple outstanding calls and causal ordering\n") ; PrintToConsole("7: Context handles\n") ; PrintToConsole("8: Sync/Async interop\n") ; PrintToConsole("9: Async ping server") ; PrintToConsole("10: Alter context during async calls\n") ; PrintToConsole("11: Async cancels\n") ; PrintToConsole("12: Multiple outstanding non causal calls\n") ; PrintToConsole("13: Rebinds on secure calls with uuids\n") ; NumberOfTestsRun++ ; return ; break; } if (Async) { IsabelleShutdown(Async); } CHECK_ERRORS; CloseHandle(SyncEvent) ; RpcBindingFree(&Async); PrintToConsole("Async : PASS\n"); } // // datagram SendAck test data // #include "dgpkt.hxx" typedef DWORD (RPCRTAPI RPC_ENTRY *SET_TEST_HOOK_FN)( RPC_TEST_HOOK_ID id, RPC_TEST_HOOK_FN fn ); SET_TEST_HOOK_FN SetTestHookFn; PVOID ChosenConnection; RPC_TEST_HOOK_ID BasicHookId; void BasicPokeEventFn( RPC_TEST_HOOK_ID id, PVOID arg1, PVOID arg2 ) { PrintToConsole("PokeEventFn: conn = %p, setting the sync event\n", arg1); SetEvent( SyncEvent ); } void BasicSendAckTest( int Hook ) { RPC_BINDING_HANDLE binding; // housekeeping // DWORD Status = 0; ++NumberOfTestsRun; ChosenConnection = 0; Status = GetBinding(BARTHOLOMEW, &binding); if (Status) { ApiError("SendAck", "GetBinding", Status); PrintToConsole("SetAsync : FAIL - Unable to Bind \n"); return; } SyncEvent = CreateEvent(NULL, FALSE, FALSE, NULL) ; if (SyncEvent == 0) { ApiError("SendAck", "CreateEvent", Status); return; } HMODULE hRpc = GetModuleHandle(L"RPCRT4.DLL"); if (!hRpc) { ApiError("SendAck","GetModuleHandle",GetLastError()); return; } SetTestHookFn = (SET_TEST_HOOK_FN) GetProcAddress( hRpc, "I_RpcSetTestHook" ); if (!SetTestHookFn) { ApiError("SendAck", "GetProcAddress: I_RpcSetTestHook", GetLastError()); if (GetLastError() == ERROR_PROC_NOT_FOUND) { PrintToConsole("you need to recompile with -DRPC_ENABLE_TEST_HOOKS\n"); } return; } BasicHookId = MAKE_TEST_HOOK_ID( TH_DG_SEND_ACK, Hook ); (*SetTestHookFn)( BasicHookId, BasicPokeEventFn ); // make first call // PrintToConsole("SendAck: first call...\n") ; Helga( binding ); // wait for the ACK to complete // TRACE(("SendAck: Waiting...\n")) ; WaitForSingleObject(SyncEvent, INFINITE) ; // make second call // PrintToConsole("SendAck: second call...\n") ; Helga( binding ); // clear the hook // (*SetTestHookFn)( BasicHookId, 0 ); PrintToConsole("PASS\n"); } void Test5EventFn( RPC_TEST_HOOK_ID id, PVOID arg1, PVOID arg2 ) { // release the app thread to make calls // PrintToConsole("PokeEventFn: conn = %p, setting the sync event\n", arg1); SetEvent( SyncEvent ); // wait for it to finish // WaitForSingleObject(SyncEvent, INFINITE); PrintToConsole("PokeEventFn: signalled\n"); } void AckTest5() { RPC_BINDING_HANDLE binding; // housekeeping // DWORD Status = 0; ++NumberOfTestsRun; ChosenConnection = 0; Status = GetBinding(BARTHOLOMEW, &binding); if (Status) { ApiError("SendAck", "GetBinding", Status); PrintToConsole("SetAsync : FAIL - Unable to Bind \n"); return; } SyncEvent = CreateEvent(NULL, FALSE, FALSE, NULL) ; if (SyncEvent == 0) { ApiError("SendAck", "CreateEvent", Status); return; } HMODULE hRpc = GetModuleHandle(L"RPCRT4.DLL"); if (!hRpc) { ApiError("SendAck","GetModuleHandle",GetLastError()); return; } SetTestHookFn = (SET_TEST_HOOK_FN) GetProcAddress( hRpc, "I_RpcSetTestHook" ); if (!SetTestHookFn) { ApiError("SendAck", "GetProcAddress: I_RpcSetTestHook", GetLastError()); if (GetLastError() == ERROR_PROC_NOT_FOUND) { PrintToConsole("you need to recompile with -DRPC_ENABLE_TEST_HOOKS\n"); } return; } // set hook for beginning of procedure // (*SetTestHookFn)( MAKE_TEST_HOOK_ID( TH_DG_SEND_ACK, 1 ), Test5EventFn ); // make first call // PrintToConsole("SendAck: first call, will cause a delayed ACK\n") ; Helga( binding ); // wait for the ACK to start // TRACE(("SendAck: Waiting...\n")) ; WaitForSingleObject(SyncEvent, INFINITE) ; // make a couple of calls // PrintToConsole("SendAck: second call, completes quickly\n") ; Helga( binding ); PrintToConsole("SendAck: third call, completes quickly\n") ; Helga( binding ); // clear the hook and add one for the end of the ACK proc. // (*SetTestHookFn)( MAKE_TEST_HOOK_ID( TH_DG_SEND_ACK, 1 ), 0 ); (*SetTestHookFn)( MAKE_TEST_HOOK_ID( TH_DG_SEND_ACK, 6 ), BasicPokeEventFn ); // release the ACK thread PrintToConsole("SendAck: releasing orphaned delayed-ACK call and waiting for completion\n") ; SetEvent( SyncEvent ); WaitForSingleObject(SyncEvent, INFINITE) ; // make a couple of calls // PrintToConsole("SendAck: first post-ACK call...\n") ; Helga( binding ); PrintToConsole("SendAck: second post-ACK call...\n") ; Helga( binding ); // wait for the ACK to finish // TRACE(("SendAck: waiting for delayed ACK to complete\n")) ; WaitForSingleObject(SyncEvent, INFINITE) ; // clear the hook. // (*SetTestHookFn)( MAKE_TEST_HOOK_ID( TH_DG_SEND_ACK, 6 ), 0 ); PrintToConsole("PASS\n"); } void SendAck ( int testnum ) { switch (testnum) { default: { PrintToConsole("unknown send-ack case!\n"); // no break here } case 100: { // // wants a list // PrintToConsole("cases:\n" "\n" " 1 - make 2nd call after delayed-ACK proc has finished\n" " 2 - make 2nd call before ACK proc can take connection mutex\n" " 3 - make 2nd call just after ACK proc takes conn mutex\n" " 4 - make 2nd call after ACK proc decrements AckPending\n" " 5 - ACK proc blocks just before taking mutex - other calls proceed.\n" ); return; } case 0: { PrintToConsole("SendAck: testing each case\n"); // no break here } case 1: { // // 1. thread makes one call // 2. ACK is sent // 3. thread makes second call // PrintToConsole("case 1 - make 2nd call after delayed-ACK proc has finished\n"); BasicSendAckTest( 6 ); if (testnum != 0) { break; } } case 2: { // 1. thread makes a call // 2. ACK proc is launched but has not yet taken mutex // 3. thread makes second call PrintToConsole("case 2 - make 2nd call before ACK proc can take connection mutex\n"); BasicSendAckTest( 1 ); if (testnum != 0) { break; } } case 3: { // 1. thread makes a call // 2. ACK proc is launched, takes connection mutex // 3. thread makes second call PrintToConsole("case 3 - make 2nd call just after ACK proc takes conn mutex\n"); BasicSendAckTest( 2 ); if (testnum != 0) { break; } } case 4: { // 1. thread makes a call // 2. ACK proc is launched, sends ACK, decrements AckPending // 3. thread makes second call PrintToConsole("case 4 - make 2nd call after ACK proc decrements AckPending\n"); BasicSendAckTest( 4 ); if (testnum != 0) { break; } } case 5: { // 1. make a call, and wait for the ACK. // 3, ACK proc runs in delayed-proc thread , and signals the first thread // 4. first thread makes a couple of calls, calling CancelDelayedAck several times. // 5. ACK proc finishes. // 6. Make anther call, and wait for the ACK. // 6. Make anther call, and wait for the ACK. PrintToConsole("case 5 - test orphaned ACK proc handling"); AckTest5(); if (testnum != 0) { break; } } } } void SendErrorHook( RPC_TEST_HOOK_ID id, PVOID arg1, PVOID arg2 ) { ASSERT( id == TH_X_DG_SEND ); NCA_PACKET_HEADER * header = (NCA_PACKET_HEADER *) arg1; DWORD * pStatus = (DWORD *) arg2; TRACE(("SendErrorHook called: pkt type %d, serial %d\n", header->PacketType, header->SerialLo)); switch (Subtest) { case 1: { // first request is dropped with RPC_P_SEND_FAILED // if (header->PacketType == DG_REQUEST && header->SerialLo == 0) { *pStatus = RPC_P_SEND_FAILED; } break; } case 2: { // first request is dropped with RPC_S_OUT_OF_RESOURCES // if (header->PacketType == DG_REQUEST && header->SerialLo == 0) { *pStatus = RPC_S_OUT_OF_RESOURCES; } break; } case 3: { // first request is dropped with ERROR_NOT_ENOUGH_MEMORY // if (header->PacketType == DG_REQUEST && header->SerialLo == 0) { *pStatus = ERROR_NOT_ENOUGH_MEMORY; } break; } case 4: { // first request is dropped with RPC_P_HOST_DOWN // if (header->PacketType == DG_REQUEST && header->SerialLo == 0) { *pStatus = RPC_P_HOST_DOWN; } break; } default: { PrintToConsole("SendErrorHook: subtest %d is not defined\n", Subtest); } } TRACE(("status is %d (0x%x)\n", *pStatus, *pStatus)); } void DgTransport ( int testnum ) { RPC_BINDING_HANDLE binding; // housekeeping // DWORD Status = 0; ++NumberOfTestsRun; char * name = "DgTransport"; ChosenConnection = 0; Status = GetBinding(BARTHOLOMEW, &binding); if (Status) { ApiError(name, "GetBinding", Status); PrintToConsole("%s : FAIL - Unable to Bind \n", name); return; } SyncEvent = CreateEvent(NULL, FALSE, FALSE, NULL) ; if (SyncEvent == 0) { ApiError(name, "CreateEvent", Status); return; } HMODULE hRpc = GetModuleHandle(L"RPCRT4.DLL"); if (!hRpc) { ApiError(name, "GetModuleHandle",GetLastError()); return; } SetTestHookFn = (SET_TEST_HOOK_FN) GetProcAddress( hRpc, "I_RpcSetTestHook" ); if (!SetTestHookFn) { PrintToConsole("%s: can't find rpcrt4!I_RpcSetTestHook.\nRecompile RPCRT4.DLL with MSC_OPTIMIZATION=-DRPC_ENABLE_TEST_HOOKS\n"); ApiError(name, "GetProcAddress: I_RpcSetTestHook", GetLastError()); return; } switch (testnum) { default: { PrintToConsole("unknown DG transport case!\n"); // no break here } case 100: { // // wants a list // PrintToConsole("cases:\n"); PrintToConsole("case 1 - first request dropped with RPC_P_SEND_FAILED \n"); PrintToConsole("case 2 - first request dropped with RPC_S_OUT_OF_RESOURCES \n"); PrintToConsole("case 3 - first request dropped with ERROR_NOT_ENOUGH_MEMORY \n"); PrintToConsole("case 4 - first request dropped with RPC_P_HOST_DOWN \n"); PrintToConsole("case 5 - simulate ICMP reject on first request \n"); return; } case 0: { PrintToConsole("DgTransport: testing each case\n"); // no break here } case 1: { PrintToConsole("case 1 - first request dropped with RPC_P_SEND_FAILED \n"); Subtest = testnum; (*SetTestHookFn)( TH_X_DG_SEND, SendErrorHook ); // make first call // PrintToConsole("%s: calling...", name) ; Helga( binding ); PrintToConsole("done\n"); (*SetTestHookFn)( TH_X_DG_SEND, 0 ); PrintToConsole("PASS\n"); if (testnum != 0) { break; } } case 2: { PrintToConsole("case 2 - first request dropped with RPC_S_OUT_OF_RESOURCES \n"); Subtest = testnum; (*SetTestHookFn)( TH_X_DG_SEND, SendErrorHook ); // make first call // PrintToConsole("%s: calling...", name) ; Helga( binding ); PrintToConsole("done\n"); (*SetTestHookFn)( TH_X_DG_SEND, 0 ); PrintToConsole("PASS\n"); if (testnum != 0) { break; } } case 3: { PrintToConsole("case 3 - first request dropped with ERROR_NOT_ENOUGH_MEMORY \n"); Subtest = testnum; (*SetTestHookFn)( TH_X_DG_SEND, SendErrorHook ); // make first call // PrintToConsole("%s: calling...", name) ; Helga( binding ); PrintToConsole("done\n"); (*SetTestHookFn)( TH_X_DG_SEND, 0 ); PrintToConsole("PASS\n"); if (testnum != 0) { break; } } case 4: { PrintToConsole("case 4 - first request dropped with RPC_P_HOST_DOWN \n"); Subtest = testnum; (*SetTestHookFn)( TH_X_DG_SEND, SendErrorHook ); // make first call // PrintToConsole("%s: calling...", name) ; Status = HelgaSendReceiveFailure( binding, 0 ); PrintToConsole("done\n"); (*SetTestHookFn)( TH_X_DG_SEND, 0 ); if (Status != RPC_S_SERVER_UNAVAILABLE) { PrintToConsole("FAIL: wrong error code %d (0x%x)\n", Status, Status); } else { PrintToConsole("PASS\n"); } if (testnum != 0) { break; } } case 5: { PrintToConsole("case 4 - first request dropped with RPC_P_HOST_DOWN \n"); Subtest = testnum; (*SetTestHookFn)( TH_X_DG_SEND, SendErrorHook ); // make first call // PrintToConsole("%s: calling...", name) ; Status = HelgaSendReceiveFailure( binding, 0 ); PrintToConsole("done\n"); (*SetTestHookFn)( TH_X_DG_SEND, 0 ); if (Status != RPC_S_SERVER_UNAVAILABLE) { PrintToConsole("FAIL: wrong error code %d (0x%x)\n", Status, Status); } else { PrintToConsole("PASS\n"); } if (testnum != 0) { break; } } } } PVOID LastConnectionCreated = 0; PVOID MySecurityContext = 0; DWORD ChosenErrorCode = 0; void ShutdownHookFn( DWORD id, PVOID subject, PVOID object ) { switch (id) { case TH_RPC_LOG_EVENT: { RPC_EVENT * event = (RPC_EVENT *) subject; // TRACE((" hook: %c %c %p %p\n", event->Subject, event->Verb, event->SubjectPointer, event->ObjectPointer)); // // Record sconnection creation. // if (event->Subject == SU_CCONN && event->Verb == EV_CREATE) { TRACE((" hook: created connection %p\n", event->SubjectPointer)); LastConnectionCreated = event->SubjectPointer; } break; } default: { break; } } } void SecurityContextHook( DWORD id, PVOID subject, PVOID object ) { if (subject == MySecurityContext) { TRACE((" hook executed: context %p, hook ID %x, error code is 0x%x\n", subject, id, ChosenErrorCode)); DWORD * pStatus = (DWORD *) object; *pStatus = ChosenErrorCode; } else { TRACE((" hook: ignoring notification, my cxt = %p, context %p, hook ID %x, error code is 0x%x\n", MySecurityContext, subject, id, ChosenErrorCode)); } } void SecurityErrorWrapper( int subtest ) { RPC_BINDING_HANDLE binding; // housekeeping // DWORD Status = 0; ++NumberOfTestsRun; char * name = "security error test"; ChosenConnection = 0; Status = GetBinding(SECURITY_ERROR, &binding); if (Status) { ApiError(name, "GetBinding", Status); PrintToConsole("%s : FAIL - Unable to Bind \n", name); return; } Status = RpcBindingSetAuthInfo( binding, NULL, RPC_C_AUTHN_LEVEL_PKT_PRIVACY, ulSecurityPackage, NULL, RPC_C_AUTHZ_NONE ); if (Status) { ApiError(name, "SetAuthInfo", Status); PrintToConsole("%s : FAIL\n", name); return; } // // Set up the test hook. // { HMODULE hRpc = GetModuleHandle(L"RPCRT4.DLL"); if (!hRpc) { ApiError("","GetModuleHandle",GetLastError()); return; } SetTestHookFn = (SET_TEST_HOOK_FN) GetProcAddress( hRpc, "I_RpcSetTestHook" ); if (!SetTestHookFn) { ApiError("", "GetProcAddress: I_RpcSetTestHook", GetLastError()); } } switch (subtest) { default: { PrintToConsole("unknown security-error case!\n"); // no break here } case 100: { // // wants a list // PrintToConsole("cases:\n" "\n" " 1 - AcceptFirstTime returns SEC_E_SHUTDOWN_IN_PROGRESS\n" " 2 - AcceptThirdLeg returns SEC_E_SHUTDOWN_IN_PROGRESS\n" ); return; } case 0: { PrintToConsole("running all sub tests\n"); } case 1: { PrintToConsole("subtest 1: AcceptFirstTime returns SEC_E_SHUTDOWN_IN_PROGRESS\n"); Synchro(SECURITY_ERROR); // make first call // PrintToConsole("%s: calling...", name) ; Status = HelgaSendReceiveFailure( binding, 0 ); PrintToConsole("done\n"); DWORD ExpectedStatus; if (TransportType == RPC_TRANSPORT_UDP || TransportType == RPC_TRANSPORT_IPX) { ExpectedStatus = RPC_S_SERVER_UNAVAILABLE; } else { ExpectedStatus = RPC_S_UNKNOWN_AUTHN_SERVICE; } if (Status != ExpectedStatus) { PrintToConsole("FAIL: expected error %d, received error code %d (0x%x)\n", ExpectedStatus, Status, Status); } else { PrintToConsole("PASS\n"); } IsabelleShutdown(binding); if (subtest) { break; } } case 2: { PrintToConsole("subtest 2: AcceptThirdLeg returns SEC_E_SHUTDOWN_IN_PROGRESS\n"); Synchro(SECURITY_ERROR); // make first call // PrintToConsole("%s: calling...", name) ; Status = HelgaSendReceiveFailure( binding, 0 ); PrintToConsole("done\n"); DWORD ExpectedStatus; if (TransportType == RPC_TRANSPORT_UDP || TransportType == RPC_TRANSPORT_IPX) { ExpectedStatus = RPC_S_SERVER_UNAVAILABLE; } else { ExpectedStatus = RPC_S_UNKNOWN_AUTHN_SERVICE; } if (Status != ExpectedStatus) { PrintToConsole("FAIL: expected error %d, received error code %d (0x%x)\n", ExpectedStatus, Status, Status); } else { PrintToConsole("PASS\n"); } IsabelleShutdown(binding); if (subtest) { break; } } } } EVENT::EVENT ( IN OUT RPC_STATUS PAPI * RpcStatus, IN int ManualReset, IN BOOL fDelayInit ) { EventHandle = NULL; // DelayInit events are auto reset ASSERT(ManualReset == FALSE || fDelayInit == FALSE); if (!fDelayInit && *RpcStatus == RPC_S_OK ) { EventHandle = CreateEvent(NULL, ManualReset, 0, NULL); if ( EventHandle != NULL ) { *RpcStatus = RPC_S_OK; } else { *RpcStatus = RPC_S_OUT_OF_MEMORY; } } } EVENT::~EVENT ( ) { if ( EventHandle ) { BOOL bResult; bResult = CloseHandle(EventHandle); ASSERT(bResult != 0); } } int EVENT::Wait ( long timeout ) { DWORD result; if (NULL == EventHandle) { InitializeEvent(); } result = WaitForSingleObject(EventHandle, timeout); if (result == WAIT_TIMEOUT) return(1); return(0); } void EVENT::InitializeEvent ( ) // Used when fDelayInit is TRUE in the c'tor. { if (EventHandle) { return; } HANDLE event = CreateEvent(0, FALSE, FALSE, 0); if (event) { if (InterlockedCompareExchangePointer(&EventHandle, event, 0) != 0) { CloseHandle(event); } return; } // Can't allocate an event. RpcRaiseException(RPC_S_OUT_OF_RESOURCES); } void Indent( int indentlevel ) { const int SPACES_PER_INDENT = 4; int i; for (i=0; i < SPACES_PER_INDENT * indentlevel; ++i) { PrintToConsole(" "); } } DWORD DumpEeInfo( int indentlevel ) { RPC_STATUS Status2; RPC_ERROR_ENUM_HANDLE EnumHandle; Status2 = RpcErrorStartEnumeration(&EnumHandle); if (Status2 == RPC_S_ENTRY_NOT_FOUND) { PrintToConsole("eeinfo: no extended error info available\n"); } else if (Status2 != RPC_S_OK) { PrintToConsole("Couldn't get EEInfo: %d\n", Status2); } else { RPC_EXTENDED_ERROR_INFO ErrorInfo; int Records; BOOL Result; BOOL CopyStrings = TRUE; PVOID Blob; size_t BlobSize; BOOL fUseFileTime = TRUE; SYSTEMTIME *SystemTimeToUse; SYSTEMTIME SystemTimeBuffer; Status2 = RpcErrorGetNumberOfRecords(&EnumHandle, &Records); if (Status2 == RPC_S_OK) { Indent(indentlevel); PrintToConsole("Number of records is: %d\n", Records); } while (Status2 == RPC_S_OK) { ErrorInfo.Version = RPC_EEINFO_VERSION; ErrorInfo.Flags = 0; ErrorInfo.NumberOfParameters = 4; if (fUseFileTime) { ErrorInfo.Flags |= EEInfoUseFileTime; } Status2 = RpcErrorGetNextRecord(&EnumHandle, CopyStrings, &ErrorInfo); if (Status2 == RPC_S_ENTRY_NOT_FOUND) { RpcErrorResetEnumeration(&EnumHandle); break; } else if (Status2 != RPC_S_OK) { PrintToConsole("Couldn't finish enumeration: %d\n", Status2); break; } else { int i; if (ErrorInfo.ComputerName) { Indent(indentlevel+1); PrintToConsole("ComputerName is %S\n", ErrorInfo.ComputerName); if (CopyStrings) { Result = HeapFree(GetProcessHeap(), 0, ErrorInfo.ComputerName); ASSERT(Result); } } Indent(indentlevel+1); PrintToConsole("ProcessID is %d\n", ErrorInfo.ProcessID); if (fUseFileTime) { Result = FileTimeToSystemTime(&ErrorInfo.u.FileTime, &SystemTimeBuffer); ASSERT(Result); SystemTimeToUse = &SystemTimeBuffer; } else SystemTimeToUse = &ErrorInfo.u.SystemTime; Indent(indentlevel+1); PrintToConsole("System Time is: %d/%d/%d %d:%d:%d:%d\n", SystemTimeToUse->wMonth, SystemTimeToUse->wDay, SystemTimeToUse->wYear, SystemTimeToUse->wHour, SystemTimeToUse->wMinute, SystemTimeToUse->wSecond, SystemTimeToUse->wMilliseconds); Indent(indentlevel+1); PrintToConsole("Generating component is %d\n", ErrorInfo.GeneratingComponent); Indent(indentlevel+1); PrintToConsole("Status is %d\n", ErrorInfo.Status); Indent(indentlevel+1); PrintToConsole("Detection location is %d\n", (int)ErrorInfo.DetectionLocation); Indent(indentlevel+1); PrintToConsole("Flags is %d\n", ErrorInfo.Flags); Indent(indentlevel+1); PrintToConsole("NumberOfParameters is %d\n", ErrorInfo.NumberOfParameters); for (i = 0; i < ErrorInfo.NumberOfParameters; i ++) { switch(ErrorInfo.Parameters[i].ParameterType) { case eeptAnsiString: Indent(indentlevel+1); PrintToConsole("Ansi string: %s\n", ErrorInfo.Parameters[i].u.AnsiString); if (CopyStrings) { Result = HeapFree(GetProcessHeap(), 0, ErrorInfo.Parameters[i].u.AnsiString); ASSERT(Result); } break; case eeptUnicodeString: Indent(indentlevel+1); PrintToConsole("Unicode string: %S\n", ErrorInfo.Parameters[i].u.UnicodeString); if (CopyStrings) { Result = HeapFree(GetProcessHeap(), 0, ErrorInfo.Parameters[i].u.UnicodeString); ASSERT(Result); } break; case eeptLongVal: Indent(indentlevel+1); PrintToConsole("Long val: %d\n", ErrorInfo.Parameters[i].u.LVal); break; case eeptShortVal: Indent(indentlevel+1); PrintToConsole("Short val: %d\n", (int)ErrorInfo.Parameters[i].u.SVal); break; case eeptPointerVal: Indent(indentlevel+1); PrintToConsole("Pointer val: %d\n", ErrorInfo.Parameters[i].u.PVal); break; case eeptNone: Indent(indentlevel+1); PrintToConsole("Truncated\n"); break; default: Indent(indentlevel+1); PrintToConsole("Invalid type: %d\n", ErrorInfo.Parameters[i].ParameterType); return ERROR_INVALID_PARAMETER; } } } } Status2 = RpcErrorSaveErrorInfo(&EnumHandle, &Blob, &BlobSize); if (Status2) { PrintToConsole("RpcErrorSaveErrorInfo: %d", Status2); } RpcErrorClearInformation(); RpcErrorEndEnumeration(&EnumHandle); Status2 = RpcErrorLoadErrorInfo(Blob, BlobSize, &EnumHandle); if (Status2) { PrintToConsole("RpcErrorLoadErrorInfo: %d", Status2); } } return Status2; }