static void test_WsReceiveMessage( int port ) { WS_XML_STRING req = {9, (BYTE *)"req_test1"}, resp = {10, (BYTE *)"resp_test1"}, ns = {2, (BYTE *)"ns"}; WS_CHANNEL *channel; WS_MESSAGE *msg; WS_ELEMENT_DESCRIPTION body; WS_MESSAGE_DESCRIPTION desc_req, desc_resp; const WS_MESSAGE_DESCRIPTION *desc[1]; INT32 val = -1; HRESULT hr; hr = create_channel( port, &channel ); ok( hr == S_OK, "got %08x\n", hr ); hr = WsCreateMessageForChannel( channel, NULL, 0, &msg, NULL ); ok( hr == S_OK, "got %08x\n", hr ); body.elementLocalName = &req; body.elementNs = &ns; body.type = WS_INT32_TYPE; body.typeDescription = NULL; desc_req.action = &req; desc_req.bodyElementDescription = &body; hr = WsSendMessage( channel, msg, &desc_req, WS_WRITE_REQUIRED_VALUE, &val, sizeof(val), NULL, NULL ); ok( hr == S_OK, "got %08x\n", hr ); WsFreeMessage( msg ); hr = WsCreateMessageForChannel( channel, NULL, 0, &msg, NULL ); ok( hr == S_OK, "got %08x\n", hr ); body.elementLocalName = &resp; desc_resp.action = &resp; desc_resp.bodyElementDescription = &body; desc[0] = &desc_resp; hr = WsReceiveMessage( NULL, msg, desc, 1, WS_RECEIVE_REQUIRED_MESSAGE, WS_READ_REQUIRED_VALUE, NULL, &val, sizeof(val), NULL, NULL, NULL ); ok( hr == E_INVALIDARG, "got %08x\n", hr ); hr = WsReceiveMessage( channel, NULL, desc, 1, WS_RECEIVE_REQUIRED_MESSAGE, WS_READ_REQUIRED_VALUE, NULL, &val, sizeof(val), NULL, NULL, NULL ); ok( hr == E_INVALIDARG, "got %08x\n", hr ); hr = WsReceiveMessage( channel, msg, NULL, 1, WS_RECEIVE_REQUIRED_MESSAGE, WS_READ_REQUIRED_VALUE, NULL, &val, sizeof(val), NULL, NULL, NULL ); ok( hr == E_INVALIDARG, "got %08x\n", hr ); hr = WsReceiveMessage( channel, msg, desc, 1, WS_RECEIVE_REQUIRED_MESSAGE, WS_READ_REQUIRED_VALUE, NULL, &val, sizeof(val), NULL, NULL, NULL ); ok( hr == S_OK, "got %08x\n", hr ); ok( val == -2, "got %d\n", val ); hr = WsCloseChannel( channel, NULL, NULL ); ok( hr == S_OK, "got %08x\n", hr ); WsFreeChannel( channel ); WsFreeMessage( msg ); }
static void test_WsSendMessage( int port, WS_XML_STRING *action ) { WS_XML_STRING req = {9, (BYTE *)"req_test1"}, ns = {2, (BYTE *)"ns"}; WS_CHANNEL *channel; WS_MESSAGE *msg; WS_ELEMENT_DESCRIPTION body; WS_MESSAGE_DESCRIPTION desc; INT32 val = -1; HRESULT hr; hr = create_channel( port, &channel ); ok( hr == S_OK, "got %08x\n", hr ); hr = WsCreateMessageForChannel( channel, NULL, 0, &msg, NULL ); ok( hr == S_OK, "got %08x\n", hr ); body.elementLocalName = &req; body.elementNs = &ns; body.type = WS_INT32_TYPE; body.typeDescription = NULL; desc.action = action; desc.bodyElementDescription = &body; hr = WsSendMessage( NULL, msg, &desc, WS_WRITE_REQUIRED_VALUE, &val, sizeof(val), NULL, NULL ); ok( hr == E_INVALIDARG, "got %08x\n", hr ); hr = WsSendMessage( channel, NULL, &desc, WS_WRITE_REQUIRED_VALUE, &val, sizeof(val), NULL, NULL ); ok( hr == E_INVALIDARG, "got %08x\n", hr ); hr = WsSendMessage( channel, msg, NULL, WS_WRITE_REQUIRED_VALUE, &val, sizeof(val), NULL, NULL ); ok( hr == E_INVALIDARG, "got %08x\n", hr ); hr = WsSendMessage( channel, msg, &desc, WS_WRITE_REQUIRED_VALUE, &val, sizeof(val), NULL, NULL ); ok( hr == S_OK, "got %08x\n", hr ); hr = WsCloseChannel( channel, NULL, NULL ); ok( hr == S_OK, "got %08x\n", hr ); WsFreeChannel( channel ); WsFreeMessage( msg ); }
HRESULT SendFailureMessage( __in WS_CHANNEL* channel, __in WS_MESSAGE* replyMessage, __in ULONG statusCode, __in_z WCHAR* statusText, __in_opt WS_ERROR* error) { HRESULT hr; // Add status code/text to the reply hr = SetStatus( replyMessage, statusCode, statusText, error); if (FAILED(hr)) { goto Exit; } // Send the reply hr = WsSendMessage( channel, replyMessage, &emptyMessageDescription, WS_WRITE_REQUIRED_VALUE, NULL, 0, NULL, error); if (FAILED(hr)) { goto Exit; } Exit: return hr; }
HRESULT CALLBACK ProcessMessage( __in const WS_OPERATION_CONTEXT* context, __in_opt const WS_ASYNC_CONTEXT* asyncContext, __in_opt WS_ERROR* error) { UNREFERENCED_PARAMETER(asyncContext); WS_CHANNEL* channel = NULL; HRESULT hr = S_OK; WS_MESSAGE* requestMessage = NULL; WS_MESSAGE* replyMessage = NULL; WS_HEAP* heap; // Get the request mesasge hr = WsGetOperationContextProperty( context, WS_OPERATION_CONTEXT_PROPERTY_INPUT_MESSAGE, &requestMessage, sizeof(requestMessage), error); if (FAILED(hr)) { return hr; } // Get the channel hr = WsGetOperationContextProperty( context, WS_OPERATION_CONTEXT_PROPERTY_CHANNEL, &channel, sizeof(channel), error); if (FAILED(hr)) { return hr; } // Get the heap hr = WsGetOperationContextProperty( context, WS_OPERATION_CONTEXT_PROPERTY_HEAP, &heap, sizeof(heap), error); if (FAILED(hr)) { return hr; } // Create a reply message hr = WsCreateMessageForChannel( channel, NULL, 0, &replyMessage, error); if (FAILED(hr)) { goto Exit; } // Initialize reply message hr = WsInitializeMessage(replyMessage, WS_REPLY_MESSAGE, requestMessage, error); if (FAILED(hr)) { goto Exit; } // Get the HTTP Verb WS_STRING verb; hr = WsGetMappedHeader( requestMessage, &verbHeaderName, WS_SINGLETON_HEADER, 0, WS_STRING_TYPE, WS_READ_REQUIRED_VALUE, NULL, &verb, sizeof(verb), error); if (FAILED(hr)) { goto Exit; } wprintf(L"Verb: %.*s\n", verb.length, verb.chars); if (CompareString(LOCALE_INVARIANT, NORM_IGNORECASE, verb.chars, verb.length, L"GET", 3) != CSTR_EQUAL) { // Unrecognized verb hr = SendFailureMessage(channel, replyMessage, 405, L"Method Not Allowed", error); goto Exit; } // Read end of request message hr = WsReadMessageEnd(channel, requestMessage, NULL, error); if (FAILED(hr)) { goto Exit; } // Set content type header of reply hr = WsAddMappedHeader( replyMessage, &contentTypeHeaderName, WS_STRING_TYPE, WS_WRITE_REQUIRED_VALUE, &replyContentType, sizeof(replyContentType), error); if (FAILED(hr)) { goto Exit; } // Set status of reply hr = SetStatus(replyMessage, 200, L"OK", error); if (FAILED(hr)) { goto Exit; } // Set up the bytes to return in the HTTP body WS_BYTES body; body.bytes = const_cast<BYTE*>(replyBodyBytes); body.length = sizeof(replyBodyBytes); // Send the reply message hr = WsSendMessage( channel, replyMessage, &bytesMessageDescription, WS_WRITE_REQUIRED_VALUE, &body, sizeof(body), NULL, error); if (FAILED(hr)) { goto Exit; } Exit: if (replyMessage != NULL) { WsFreeMessage(replyMessage); } return hr; }
// Main entry point int __cdecl wmain() { HRESULT hr = S_OK; WS_ERROR* error = NULL; WS_CHANNEL* channel = NULL; WS_MESSAGE* message = NULL; static const WS_STRING serviceUrl = WS_STRING_VALUE(L"soap.udp://localhost:809"); // Create an error object for storing rich error information hr = WsCreateError( NULL, 0, &error); if (FAILED(hr)) { goto Exit; } // Create a UDP duplex channel hr = WsCreateChannel( WS_CHANNEL_TYPE_DUPLEX, WS_UDP_CHANNEL_BINDING, NULL, 0, NULL, &channel, error); if (FAILED(hr)) { goto Exit; } // Initialize address of service WS_ENDPOINT_ADDRESS address; address.url = serviceUrl; address.headers = NULL; address.extensions = NULL; address.identity = NULL; // Open channel to address hr = WsOpenChannel(channel, &address, NULL, error); if (FAILED(hr)) { goto Exit; } hr = WsCreateMessageForChannel( channel, NULL, 0, &message, error); if (FAILED(hr)) { goto Exit; } // Send some messages for (int i = 0; i < 5; i++) { // Initialize body data _PurchaseOrderType purchaseOrder; purchaseOrder.quantity = 100; purchaseOrder.productName = L"Pencil"; // Send a message hr = WsSendMessage( channel, message, &PurchaseOrder_wsdl.messages.PurchaseOrder, WS_WRITE_REQUIRED_VALUE, &purchaseOrder, sizeof(purchaseOrder), NULL, error); if (FAILED(hr)) { goto Exit; } // Reset message so it can be used again hr = WsResetMessage(message, error); if (FAILED(hr)) { goto Exit; } } Exit: if (FAILED(hr)) { // Print out the error PrintError(hr, error); } if (channel != NULL) { // Close the channel WsCloseChannel(channel, NULL, error); } if (message != NULL) { WsFreeMessage(message); } if (channel != NULL) { WsFreeChannel(channel); } if (error != NULL) { WsFreeError(error); } fflush(stdout); return SUCCEEDED(hr) ? 0 : -1; }