HRESULT CALLBACK AuthorizationCallback( __in const WS_OPERATION_CONTEXT* context, __out BOOL* authorized, __in_opt WS_ERROR* error) { HRESULT hr = S_OK; const WS_STRING fixedUsername = WS_STRING_VALUE(L"usr1"); WS_MESSAGE* message = NULL; WS_STRING usernameIdentity = {}; *authorized = FALSE; hr = WsGetOperationContextProperty(context, WS_OPERATION_CONTEXT_PROPERTY_INPUT_MESSAGE, &message, sizeof(message), error); if (FAILED(hr)) { return hr; } hr = WsGetMessageProperty(message, WS_MESSAGE_PROPERTY_USERNAME, &usernameIdentity, sizeof(usernameIdentity), error); if (FAILED(hr)) { return hr; } *authorized = CompareWsString(&usernameIdentity, &fixedUsername); return S_OK; }
HRESULT CALLBACK GetOrderStatusImpl( __in const WS_OPERATION_CONTEXT* context, __inout unsigned int* orderID, __out_opt __deref __nullterminated WCHAR** status, __in_opt const WS_ASYNC_CONTEXT* asyncContext, __in_opt WS_ERROR* error) { UNREFERENCED_PARAMETER(asyncContext); WS_HEAP* heap = NULL; HRESULT hr = S_OK; *orderID = *orderID; hr = WsGetOperationContextProperty(context, WS_OPERATION_CONTEXT_PROPERTY_HEAP, &heap, sizeof(heap), error); if (FAILED(hr)) { return hr; } hr = WsAlloc(heap, sizeof(OrderStatusString), (void**)status, error); if (FAILED(hr)) { return hr; } hr = StringCbCopyW(*status, sizeof(OrderStatusString), OrderStatusString); if (FAILED(hr)) { return hr; } return S_OK; }
// In this sample, wsutil is used with the /string:WS_STRING command line option // to compile the schema files. When /string:WS_STRING is used, wsutil generates stubs // using WS_STRING (instead of WCHAR*) type for strings. HRESULT CALLBACK PurchaseOrderImpl( _In_ const WS_OPERATION_CONTEXT* context, _In_ int quantity, _In_ WS_STRING productName, _Out_ unsigned int* orderID, _In_ WS_STRING* expectedShipDate, _In_ const WS_ASYNC_CONTEXT* asyncContext, _In_ WS_ERROR* error) { UNREFERENCED_PARAMETER(asyncContext); WS_HEAP* heap = NULL; HRESULT hr = S_OK; wprintf(L"%ld, %.*s\n", quantity, productName.length, productName.chars); fflush(stdout); hr = WsGetOperationContextProperty( context, WS_OPERATION_CONTEXT_PROPERTY_HEAP, &heap, sizeof(heap), error); if (FAILED(hr)) { goto Exit; } hr = WsAlloc( heap, sizeof(ExpectedShipDate), (void**)&expectedShipDate->chars, error); if (FAILED(hr)) { goto Exit; } hr = StringCbCopyW( expectedShipDate->chars, sizeof(ExpectedShipDate), ExpectedShipDate); if (FAILED(hr)) { goto Exit; } *orderID = 123; expectedShipDate->length = (ULONG)wcslen(ExpectedShipDate); Exit: return hr; }
HRESULT CALLBACK PurchaseOrderImpl( __in const WS_OPERATION_CONTEXT* context, __in int quantity, __in_opt __nullterminated WCHAR* productName, __out unsigned int* orderID, __out_opt __deref __nullterminated WCHAR** expectedShipDate, __in_opt const WS_ASYNC_CONTEXT* asyncContext, __in_opt WS_ERROR* error) { UNREFERENCED_PARAMETER(asyncContext); WS_HEAP* heap = NULL; HRESULT hr = S_OK; wprintf(L"%ld, %s\n", quantity, productName); fflush(stdout); hr = WsGetOperationContextProperty( context, WS_OPERATION_CONTEXT_PROPERTY_HEAP, &heap, sizeof(heap), error); if (FAILED(hr)) { goto Exit; } hr = WsAlloc( heap, sizeof(ExpectedShipDate), (void**)expectedShipDate, error); if (FAILED(hr)) { goto Exit; } hr = StringCbCopyW( *expectedShipDate, sizeof(ExpectedShipDate), ExpectedShipDate); if (FAILED(hr)) { goto Exit; } *orderID = 123; Exit: return hr; }
HRESULT CALLBACK FreeSessionCalculator( __in const WS_OPERATION_CONTEXT* context, __in const WS_ASYNC_CONTEXT* asyncContext) { UNREFERENCED_PARAMETER(asyncContext); SessionfulCalculator* calculator = NULL; WsGetOperationContextProperty( context, WS_OPERATION_CONTEXT_PROPERTY_CHANNEL_USER_STATE, &calculator, sizeof(SessionfulCalculator*), NULL); if (calculator != NULL) { wprintf(L"Deleting Calculator instance\n"); delete calculator; } SetEvent(closeServer); return S_OK; }
static HRESULT CALLBACK Clear( __in const WS_OPERATION_CONTEXT* context, __in const WS_ASYNC_CONTEXT* asyncContext, __in_opt WS_ERROR* error) { UNREFERENCED_PARAMETER(asyncContext); HRESULT hr = S_OK; SessionfulCalculator* calculator = NULL; hr = WsGetOperationContextProperty( context, WS_OPERATION_CONTEXT_PROPERTY_CHANNEL_USER_STATE, &calculator, sizeof(SessionfulCalculator*), error); if (FAILED(hr)) { goto Exit; } hr = calculator->Clear(); Exit: return hr; }
// In this sample, wsutil is used with the /string:WS_STRING command line option // to compile the schema files. When /string:WS_STRING is used, wsutil generates stubs // using WS_STRING (instead of WCHAR*) type for strings. HRESULT CALLBACK GetOrderStatusImpl( _In_ const WS_OPERATION_CONTEXT* context, _Inout_ unsigned int* orderID, _Inout_ WS_STRING* status, _In_ const WS_ASYNC_CONTEXT* asyncContext, _In_ WS_ERROR* error) { UNREFERENCED_PARAMETER(asyncContext); WS_HEAP* heap = NULL; HRESULT hr = S_OK; // Generate a fault if we don't recognize the order ID if (*orderID != 123) { // Fill out details about the fault _OrderNotFoundFaultType orderNotFound; orderNotFound.orderID = *orderID; static const WS_XML_STRING _faultDetailName = WS_XML_STRING_VALUE("OrderNotFound"); static const WS_XML_STRING _faultDetailNs = WS_XML_STRING_VALUE("http://example.com"); static const WS_XML_STRING _faultAction = WS_XML_STRING_VALUE("http://example.com/fault"); static const WS_ELEMENT_DESCRIPTION _faultElementDescription = { (WS_XML_STRING*)&_faultDetailName, (WS_XML_STRING*)&_faultDetailNs, WS_UINT32_TYPE, NULL }; static const WS_FAULT_DETAIL_DESCRIPTION orderNotFoundFaultTypeDescription = { (WS_XML_STRING*)&_faultAction, (WS_ELEMENT_DESCRIPTION*)&_faultElementDescription }; // Set fault detail information in the error object hr = WsSetFaultErrorDetail( error, &orderNotFoundFaultTypeDescription, WS_WRITE_REQUIRED_VALUE, &orderNotFound, sizeof(orderNotFound)); if (FAILED(hr)) { goto Exit; } // Add an error string to the error object. This string will // be included in the fault that is sent. static const WS_STRING errorMessage = WS_STRING_VALUE(L"Invalid order ID"); hr = WsAddErrorString(error, &errorMessage); if (FAILED(hr)) { goto Exit; } hr = E_FAIL; goto Exit; } *orderID = *orderID; hr = WsGetOperationContextProperty( context, WS_OPERATION_CONTEXT_PROPERTY_HEAP, &heap, sizeof(heap), error); if (FAILED(hr)) { goto Exit; } hr = WsAlloc( heap, sizeof(OrderStatusString), (void**)&status->chars, error); if (FAILED(hr)) { goto Exit; } hr = StringCbCopyW( status->chars, sizeof(OrderStatusString), OrderStatusString); if (FAILED(hr)) { goto Exit; } status->length = (ULONG)wcslen(OrderStatusString); 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; }
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 = NOERROR; WS_HEAP* heap = NULL; WS_MESSAGE* replyMessage = NULL; hr = WsGetOperationContextProperty( context, WS_OPERATION_CONTEXT_PROPERTY_HEAP, &heap, sizeof(heap), error); if (FAILED(hr)) { goto Exit; } WS_MESSAGE* requestMessage = NULL; hr = WsGetOperationContextProperty( context, WS_OPERATION_CONTEXT_PROPERTY_INPUT_MESSAGE, &requestMessage, sizeof(requestMessage), error); if (FAILED(hr)) { goto Exit; } hr = WsGetOperationContextProperty( context, WS_OPERATION_CONTEXT_PROPERTY_CHANNEL, &channel, sizeof(channel), error); if (FAILED(hr)) { goto Exit; } hr = WsCreateMessageForChannel( channel, NULL, 0, &replyMessage, error); if (FAILED(hr)) { goto Exit; } // Get action value WS_XML_STRING receivedAction; hr = WsGetHeader( requestMessage, WS_ACTION_HEADER, WS_XML_STRING_TYPE, WS_READ_REQUIRED_VALUE, NULL, &receivedAction, sizeof(receivedAction), error); if (FAILED(hr)) { goto Exit; } // Make sure action is what we expect if (WsXmlStringEquals( &receivedAction, PurchaseOrder_wsdl.messages.PurchaseOrder.action, error) != S_OK) { hr = WS_E_ENDPOINT_ACTION_NOT_SUPPORTED; goto Exit; } // Read purchase order _PurchaseOrderType purchaseOrder; hr = WsReadBody( requestMessage, &PurchaseOrder_wsdl.globalElements.PurchaseOrderType, WS_READ_REQUIRED_VALUE, heap, &purchaseOrder, sizeof(purchaseOrder), error); if (FAILED(hr)) { goto Exit; } // Read end of message hr = WsReadMessageEnd( channel, requestMessage, NULL, error); if (FAILED(hr)) { goto Exit; } // Print out purchase order contents wprintf(L"%ld, %s\n", purchaseOrder.quantity, purchaseOrder.productName); // Initialize order confirmation data _OrderConfirmationType orderConfirmation; orderConfirmation.expectedShipDate = L"1/1/2006"; orderConfirmation.orderID = 123; // Send a reply message hr = WsSendReplyMessage( channel, replyMessage, &PurchaseOrder_wsdl.messages.OrderConfirmation, WS_WRITE_REQUIRED_VALUE, &orderConfirmation, sizeof(orderConfirmation), requestMessage, NULL, error); if (FAILED(hr)) { goto Exit; } hr = WS_S_END; Exit: fflush(stdout); if (replyMessage != NULL) { WsFreeMessage( replyMessage); } return hr; }