//*****************************************************************************
//  Copyright (C) 2007 Microsoft Corporation
//  All rights reserved.
//
//  Definition file for WSMAN
//*****************************************************************************

#ifndef _WSMAN_H_
#pragma option push -b -a8 -pc -A- -w-pun /*P_O_Push*/
#define _WSMAN_H_
#include <winapifamily.h>

#pragma region Desktop Family or WinMgmt Package
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_PKG_WINMGMT)


#include <specstrings.h>

#if defined(WSMAN_API_VERSION_1_0)
#elif defined(WSMAN_API_VERSION_1_1)
#else
#error "Define WSMAN_API_VERSION_1_0 or WSMAN_API_VERSION_1_1 before including wsman.h"
#endif

#define WSMAN_FLAG_REQUESTED_API_VERSION_1_0   0x0
#define WSMAN_FLAG_REQUESTED_API_VERSION_1_1   0x1


#ifdef __cplusplus
extern "C" {
#endif

//
// -----------------------------------------------------------------------------
//  WSMan - Public Client API v1.0
// -----------------------------------------------------------------------------
//

//
// -----------------------------------------------------------------------------
//  BEGIN COMMON: Shared between client and plug-in
// -----------------------------------------------------------------------------
//

//
// -----------------------------------------------------------------------------
//  Structure for a data object.  These structures are used as output and input
//  to operations.  Eg, output from a WSManReceiveShellOutput and input to a 
//      WSManSendShellInput.
// -----------------------------------------------------------------------------
//

//
// -----------------------------------------------------------------------------
// data as text
// -----------------------------------------------------------------------------
//
typedef struct _WSMAN_DATA_TEXT
{
    DWORD bufferLength;
    _In_reads_(bufferLength) PCWSTR buffer;
}WSMAN_DATA_TEXT;

//
// -----------------------------------------------------------------------------
// binary data used by API like for example WSManSendShellInput and 
//  WSManReceiveShellOutput for Shell API, the data can be stream text 
//  (ANSI/UNICODE), binary content or objects or partial or full XML
// -----------------------------------------------------------------------------
//
typedef struct _WSMAN_DATA_BINARY
{
    DWORD dataLength;
    _In_reads_(dataLength) BYTE *data; 
}WSMAN_DATA_BINARY;

//
// -----------------------------------------------------------------------------
// type of the data used by the WSMAN_DATA structure
// -----------------------------------------------------------------------------
//

enum WSManDataType
{
    WSMAN_DATA_NONE                = 0,
    WSMAN_DATA_TYPE_TEXT           = 1,
    WSMAN_DATA_TYPE_BINARY         = 2,
    WSMAN_DATA_TYPE_DWORD          = 4
};
typedef enum WSManDataType WSManDataType;

//
// -----------------------------------------------------------------------------
// Structure used to pass data as XML text, binary data or DWORD
// -----------------------------------------------------------------------------
//
typedef struct _WSMAN_DATA
{
    WSManDataType type; 
    union
    {
        WSMAN_DATA_TEXT text;
        WSMAN_DATA_BINARY binaryData;
        DWORD number;
    };
} WSMAN_DATA;

//
// -----------------------------------------------------------------------------
//  Error structure containing fault code (a Windows error code that maps to 
//  a SOAP fault) and extended error information.
//  The extended error information is the soap fault description from the protocol layer
//  including the machine where the fault was reported as well as plug-in
//  specific error text.
//
//  This error structure is used by callbacks to return detailed error information.
//
//  The error structure can contain also a transport error.
// -----------------------------------------------------------------------------
//

typedef struct _WSMAN_ERROR 
{
    DWORD code; 
    // extended error information
    _In_opt_ PCWSTR errorDetail; // extended error description from the fault; 
                                 // it can be NULL, for example in out of memory conditions
    _In_opt_ PCWSTR language;    // language for error description (RFC 3066 language code); it can be NULL
    _In_opt_ PCWSTR machineName; // machine id; it can be NULL
    _In_opt_ PCWSTR pluginName;  // Plug-in name for errors generated by plug-ins. Otherwise NULL.
} WSMAN_ERROR;

//
// -----------------------------------------------------------------------------
// Username and password on the remote machine
// -----------------------------------------------------------------------------
//
typedef struct _WSMAN_USERNAME_PASSWORD_CREDS
{
    _In_ PCWSTR username;
    _In_ PCWSTR password;
} WSMAN_USERNAME_PASSWORD_CREDS;

//
// -----------------------------------------------------------------------------
// flags used by the authenticationMechanism member of WSMAN_AUTHENTICATION_CREDENTIALS structure
// -----------------------------------------------------------------------------
//
enum WSManAuthenticationFlags
{
    WSMAN_FLAG_DEFAULT_AUTHENTICATION    = 0x0,     //Use the default authentication
    WSMAN_FLAG_NO_AUTHENTICATION         = 0x1,     //Use no authentication for a remote operation
    WSMAN_FLAG_AUTH_DIGEST               = 0x2,     //Use digest authentication for a remote operation
    WSMAN_FLAG_AUTH_NEGOTIATE            = 0x4,     //Use negotiate authentication for a remote operation (may use kerberos or ntlm)
    WSMAN_FLAG_AUTH_BASIC                = 0x8,     //Use basic authentication for a remote operation
    WSMAN_FLAG_AUTH_KERBEROS             = 0x10,    //Use kerberos authentication for a remote operation 
#if (WINVER >= 0x600)
    WSMAN_FLAG_AUTH_CREDSSP              = 0x80,    //Use CredSSP authentication for a remote operation
#endif
    WSMAN_FLAG_AUTH_CLIENT_CERTIFICATE   = 0x20     //Use client certificate authentication for a remote operation 
};

//
// -----------------------------------------------------------------------------
// Structure for passing the credentials and the authentication mechanism
// -----------------------------------------------------------------------------
//
typedef struct _WSMAN_AUTHENTICATION_CREDENTIALS
{
    DWORD authenticationMechanism; // can be 0 (the user did not specify an
                                   // authentication mechanism, WSMan client
                                   // will choose between Kerberos and Negotiate only);
                                   // if it is not 0, it must be one of the 
                                   // values from WSManAuthenticationFlags
                                   // enumeration
    union 
    {
        WSMAN_USERNAME_PASSWORD_CREDS userAccount;
        PCWSTR certificateThumbprint; 
    };
}WSMAN_AUTHENTICATION_CREDENTIALS;

//
// -----------------------------------------------------------------------
// Options
// -----------------------------------------------------------------------
//
typedef struct _WSMAN_OPTION 
{
    PCWSTR name;
    PCWSTR value;
    BOOL mustComply;
} WSMAN_OPTION;

typedef struct _WSMAN_OPTION_SET 
{
    DWORD optionsCount;
    _In_reads_opt_(optionsCount) WSMAN_OPTION *options;
    BOOL optionsMustUnderstand;
} WSMAN_OPTION_SET;

typedef struct _WSMAN_OPTION_SETEX 
{
    DWORD optionsCount;
    _In_reads_opt_(optionsCount) WSMAN_OPTION *options;
    BOOL optionsMustUnderstand;
    _In_reads_opt_(optionsCount) PCWSTR *optionTypes;
} WSMAN_OPTION_SETEX;

//
// -----------------------------------------------------------------------------
//  Structures containing information for addressing the endpoint.
// -----------------------------------------------------------------------------
//
typedef struct _WSMAN_KEY 
{
    PCWSTR key;
    PCWSTR value;
} WSMAN_KEY;

typedef struct _WSMAN_SELECTOR_SET 
{
    DWORD numberKeys; // Number of keys (selectors)
    _In_reads_opt_(numberKeys) WSMAN_KEY *keys;  // Array of key names and values
} WSMAN_SELECTOR_SET;

//
// -----------------------------------------------------------------------------
// Structure reserved for future use (Fragment Level WS-Transfer) 
// -----------------------------------------------------------------------------
//
typedef struct _WSMAN_FRAGMENT
{
    _In_ PCWSTR path;               // fragment path - WS-Transfer
    _In_opt_ PCWSTR dialect;        // dialect for Fragment path 

} WSMAN_FRAGMENT;

//
// -----------------------------------------------------------------------------
// Structure reserved for future use (Filter Enumeration/Eventing)
// -----------------------------------------------------------------------------
//
typedef struct _WSMAN_FILTER
{
    _In_ PCWSTR filter;              // filter enumeration/subscription - allows ad-hoc queries using quey languages like SQL
    _In_opt_ PCWSTR dialect;         // dialect for filter predicate

} WSMAN_FILTER;

#define WSMAN_OPERATION_INFOV1  0x00000000
#define WSMAN_OPERATION_INFOV2  0xaabbccdd

typedef struct _WSMAN_OPERATION_INFO
{
    _In_opt_ WSMAN_FRAGMENT fragment;              // optional element to support Fragment transfer or
    _In_opt_ WSMAN_FILTER filter;                  // optional Filter WS-Enumerate/WS-Eventing
    _In_opt_ WSMAN_SELECTOR_SET selectorSet;
    _In_opt_ WSMAN_OPTION_SET optionSet;  
    _In_opt_ void *reserved;
             DWORD version;
} WSMAN_OPERATION_INFO;

typedef struct _WSMAN_OPERATION_INFOEX
{
    _In_opt_ WSMAN_FRAGMENT fragment;              // optional element to support Fragment transfer or
    _In_opt_ WSMAN_FILTER filter;                  // optional Filter WS-Enumerate/WS-Eventing
    _In_opt_ WSMAN_SELECTOR_SET selectorSet;
    _In_opt_ WSMAN_OPTION_SETEX optionSet;
             DWORD version;
    _In_opt_ PCWSTR uiLocale;
    _In_opt_ PCWSTR dataLocale;
} WSMAN_OPERATION_INFOEX;
//
// -----------------------------------------------------------------------------
//  Client Initialization/Deinitialization functions
// -----------------------------------------------------------------------------
//

typedef struct WSMAN_API *WSMAN_API_HANDLE;

//
// -----------------------------------------------------------------------------
// This API is used to initialize the WinRM client;
// It can be used by different clients on the same process, ie svchost.exe.
// Returns a nonzero error code upon failure
// -----------------------------------------------------------------------------
// 
DWORD WINAPI WSManInitialize(
    DWORD flags,
    _Out_ WSMAN_API_HANDLE *apiHandle
    );

//
// -----------------------------------------------------------------------------
// This API deinitializes the Winrm client stack; all operations will 
//  finish before this API will return; this is a sync call;
//  it is highly recommended that all operations are explictly cancelled 
//  and all sessions are closed before calling this API
// Returns non zero error code upon failure
// -----------------------------------------------------------------------------
// 
DWORD WINAPI WSManDeinitialize(
    _Inout_opt_ WSMAN_API_HANDLE apiHandle,
    DWORD flags
    );

//
// -----------------------------------------------------------------------------
// This API returns a NULL terminated unicode string containing the message 
//  of an error number and an optional language identifier. The optional 
//  parameter languageCode specifies the UI language as RFC 3066 language code 
//  that should be used to localize the message (if not specified, the thread's 
//  UI language will be used). If the function cannot find a message for that 
//  language, it returns ERROR_RESOURCE_LANG_NOT_FOUND. The function copies 
//  the formatted message text to an output buffer. 
//
// Returns non zero error code upon failure. If the output buffer is not 
//  big enough or NULL, the function returns ERROR_INSUFFICIENT_BUFFER and 
//  the messageLengthUsed parameter contains the requested size of the buffer.
// -----------------------------------------------------------------------------
//
DWORD WINAPI WSManGetErrorMessage(
    _In_ WSMAN_API_HANDLE apiHandle,
    _Reserved_ DWORD flags,            // reserved for future use; must be 0
    _In_opt_ PCWSTR languageCode,    // the RFC 3066 language code; it can be NULL
    DWORD errorCode,        // error code for the requested error message
    DWORD messageLength,    // message length, including NULL terminator
    _Out_writes_to_opt_(messageLength, *messageLengthUsed) PWSTR message,
    _Out_ DWORD* messageLengthUsed  // effective message length, including NULL terminator
    );


//
// -----------------------------------------------------------------------------
// Unsigned long integer value that contains the proxy access type
// By default, wsman uses WSMAN_OPTION_PROXY_WINHTTP_PROXY_CONFIG -
//  the proxy settings configured for WinHTTP. The WinHTTP proxy settings 
//  can be set with Proxycfg.exe or by using netsh command.
// When WSMAN_OPTION_PROXY_IE_PROXY_CONFIG is specified, the current user's
//  Internet Explorer proxy settings for the current active network connection. 
//  This option requires the user profile to be loaded, so the option can 
//  be directly used when called within a process that is running under 
//  an interactive user account identity; if the client application is running 
//  under a user context different then the interactive user, the client 
//  application has to explicitly load the user profile prior to using this option.
// IMPORTANT: proxy configuration is supported for HTTPS only; for HTTP, the direct 
//      connection to the server is used
// -----------------------------------------------------------------------------
//
enum WSManProxyAccessType
{
    WSMAN_OPTION_PROXY_IE_PROXY_CONFIG          = 1,    // use the Internet Explorer proxy configuration for the current user
    WSMAN_OPTION_PROXY_WINHTTP_PROXY_CONFIG     = 2,    // default: proxy settings configured for WinHTTP, using the ProxyCfg.exe utility       
    WSMAN_OPTION_PROXY_AUTO_DETECT              = 4,    // Force autodetection of proxy
    WSMAN_OPTION_PROXY_NO_PROXY_SERVER          = 8,    // do not use a proxy server - resolves all host names locally   
};

//
// -----------------------------------------------------------------------------
// Structure used to set the proxy information per session
// -----------------------------------------------------------------------------
// 

typedef struct _WSMAN_PROXY_INFO
{  
    DWORD accessType;
    _In_opt_ WSMAN_AUTHENTICATION_CREDENTIALS authenticationCredentials; // credentials and authentication scheme used for proxy
} WSMAN_PROXY_INFO;

//
// -----------------------------------------------------------------------------
//  Client Session
// -----------------------------------------------------------------------------
//
typedef struct WSMAN_SESSION *WSMAN_SESSION_HANDLE;

//
// -----------------------------------------------------------------------------
// Creates a session which can be used to perform subsequent operations
// Returns a non zero error code upon failure
// -----------------------------------------------------------------------------
//
DWORD WINAPI WSManCreateSession(
    _In_ WSMAN_API_HANDLE apiHandle,
    _In_opt_ PCWSTR connection,                         // if NULL, then connection will default to localhost
    DWORD flags,
    _In_opt_ WSMAN_AUTHENTICATION_CREDENTIALS *serverAuthenticationCredentials,
    _In_opt_ WSMAN_PROXY_INFO *proxyInfo,
    _Out_ WSMAN_SESSION_HANDLE *session
    );

//
// -----------------------------------------------------------------------------
// Frees memory of session and closes all related operations before returning; this is sync call
// it is recommended that all pending operations are either completed or cancelled before calling this API
// Returns a non zero error code upon failure
// -----------------------------------------------------------------------------
//
DWORD WINAPI WSManCloseSession(
    _Inout_opt_ WSMAN_SESSION_HANDLE session,
    DWORD flags
    );

//
// default operation timeout for network operations - 1 min = 60000ms
//
#define WSMAN_DEFAULT_TIMEOUT_MS 60000

//
// -----------------------------------------------------------------------------
// Extended options set for the session
// -----------------------------------------------------------------------------
//
enum WSManSessionOption 
{
    //
    //Timeouts
    //

    WSMAN_OPTION_DEFAULT_OPERATION_TIMEOUTMS = 1,// DWORD - default timeout in ms that applies to all operations on the client side

    WSMAN_OPTION_MAX_RETRY_TIME             = 11, // DWORD (read only) - maximum time for Robust connection retries
    WSMAN_OPTION_TIMEOUTMS_CREATE_SHELL      = 12,// DWORD - timeout in ms for WSManCreateShell operations
    WSMAN_OPTION_TIMEOUTMS_RUN_SHELL_COMMAND =13,// DWORD - timeout in ms for WSManRunShellCommand operations
    WSMAN_OPTION_TIMEOUTMS_RECEIVE_SHELL_OUTPUT =14,// DWORD - timeout in ms for WSManReceiveShellOutput operations
    WSMAN_OPTION_TIMEOUTMS_SEND_SHELL_INPUT  = 15,// DWORD - timeout in ms for WSManSendShellInput operations
    WSMAN_OPTION_TIMEOUTMS_SIGNAL_SHELL      = 16,// DWORD - timeout in ms for WSManSignalShell and WSManCloseCommand operations
    WSMAN_OPTION_TIMEOUTMS_CLOSE_SHELL       = 17,// DWORD - timeout in ms for WSManCloseShell operations

    //
    // connection options
    //

    WSMAN_OPTION_SKIP_CA_CHECK              = 18,// DWORD  - 1 to not validate the CA on the server certificate; 0 - default
    WSMAN_OPTION_SKIP_CN_CHECK              = 19,// DWORD  - 1 to not validate the CN on the server certificate; 0 - default
    WSMAN_OPTION_UNENCRYPTED_MESSAGES       = 20,// DWORD  - 1 to not encrypt the messages; 0 - default
    WSMAN_OPTION_UTF16                      = 21,// DWORD  - 1 Send all network packets for remote operatons in UTF16; 0 - default is UTF8
    WSMAN_OPTION_ENABLE_SPN_SERVER_PORT     = 22,// DWORD  - 1 When using negotiate, include port number in the connection SPN; 0 - default
                                                 // Used when not talking to the main OS on a machine but, for instance, a BMC 
    WSMAN_OPTION_MACHINE_ID                 = 23,// DWORD  - 1 Identify this machine to the server by including the MachineID header; 0 - default
    
    //
    // other options
    //
    WSMAN_OPTION_LOCALE                     = 25,// string - RFC 3066 language code
    WSMAN_OPTION_UI_LANGUAGE                = 26,// string - RFC 3066 language code
    WSMAN_OPTION_MAX_ENVELOPE_SIZE_KB       = 28,// DWORD - max SOAP envelope size (kb) - default 150kb from winrm config 
                                                // (see 'winrm help config' for more details); the client SOAP packet size cannot surpass 
                                                //  this value; this value will be also sent to the server in the SOAP request as a 
                                                //  MaxEnvelopeSize header; the server will use min(MaxEnvelopeSizeKb from server configuration, 
                                                //  MaxEnvelopeSize value from SOAP).
    WSMAN_OPTION_SHELL_MAX_DATA_SIZE_PER_MESSAGE_KB = 29,// DWORD (read only) - max data size (kb) provided by the client, guaranteed by 
                                                     //  the winrm client implementation to fit into one SOAP packet; this is an 
                                                     // approximate value calculated based on the WSMAN_OPTION_MAX_ENVELOPE_SIZE_KB (default 500kb), 
                                                     // the maximum possible size of the SOAP headers and the overhead of the base64 
                                                     // encoding which is specific to WSManSendShellInput API; this option can be used 
                                                     // with WSManGetSessionOptionAsDword API; it cannot be used with WSManSetSessionOption API.
    WSMAN_OPTION_REDIRECT_LOCATION          = 30,// string - read-only, cannot set
    WSMAN_OPTION_SKIP_REVOCATION_CHECK  = 31,// DWORD  - 1 to not validate the revocation status on the server certificate; 0 - default
    WSMAN_OPTION_ALLOW_NEGOTIATE_IMPLICIT_CREDENTIALS  = 32,// DWORD  - 1 to allow default credentials for Negotiate (this is for SSL only); 0 - default
    WSMAN_OPTION_USE_SSL                    = 33,    // DWORD - When using just a machine name in the connection string use an SSL connection. 0 means HTTP, 1 means HTTPS.  Default is 0.
    WSMAN_OPTION_USE_INTEARACTIVE_TOKEN  = 34        // DWORD - When creating connection on local machine, use interactive token feature. 1 - default
};
typedef enum WSManSessionOption WSManSessionOption;

//
// -----------------------------------------------------------------------------
// WSManSetSessionOption API - set session options
//  Returns a non zero error code upon failure
// -----------------------------------------------------------------------------
// 
DWORD WINAPI WSManSetSessionOption(
    _In_ WSMAN_SESSION_HANDLE session,
    WSManSessionOption option,
    _In_ WSMAN_DATA *data
    );

//
// -----------------------------------------------------------------------------
// WSManGetSessionOptionAsDword API - get a session option
//  Returns a non zero error code upon failure
// -----------------------------------------------------------------------------
// 
DWORD WINAPI WSManGetSessionOptionAsDword(
    _In_ WSMAN_SESSION_HANDLE session,
    WSManSessionOption option,
    _Inout_ DWORD *value
    );

//
// -----------------------------------------------------------------------------
// WSManGetSessionOptionAsString API - get a session option
//  Returns a non zero error code upon failure
// -----------------------------------------------------------------------------
// 
_Success_(return == NO_ERROR)
DWORD WINAPI WSManGetSessionOptionAsString(
    _In_ WSMAN_SESSION_HANDLE session,
    WSManSessionOption option,
    DWORD stringLength,    
    _Out_writes_to_opt_(stringLength, *stringLengthUsed) PWSTR string,
    _Out_ DWORD* stringLengthUsed  
    );

//
// -----------------------------------------------------------------------------
// Handle returned by WS-Transfer and WS-Enumerate operations
// -----------------------------------------------------------------------------
//
typedef struct WSMAN_OPERATION *WSMAN_OPERATION_HANDLE;

//
// -----------------------------------------------------------------------------
// flags used by WSMAN_SHELL_COMPLETION_FUNCTION callback function
// -----------------------------------------------------------------------------
//
enum WSManCallbackFlags 
{
    //
    // Flag that marks the end of any single step of multistep operation
    // 
    WSMAN_FLAG_CALLBACK_END_OF_OPERATION     = 0x1,

    //
    // WSMAN_SHELL_COMPLETION_FUNCTION API specific flags
    //  end of a particular stream; it is used for optimization purposes if the shell 
    //  knows that no more output will occur for this stream; in some conditions this 
    //  cannot be determined. 
    //
    WSMAN_FLAG_CALLBACK_END_OF_STREAM        = 0x8,

    // Flag that if present on CreateShell callback indicates that it supports disconnect
    WSMAN_FLAG_CALLBACK_SHELL_SUPPORTS_DISCONNECT = 0x20,

    // Flag that indicates that the shell got disconnected due to netowrk failure
    WSMAN_FLAG_CALLBACK_SHELL_AUTODISCONNECTED     = 0x40,

    // Flag indicates that the client shell detected a network failure
    WSMAN_FLAG_CALLBACK_NETWORK_FAILURE_DETECTED = 0x100,

    // Flag indicates that client shell is retrying to establish network connection with the server
    WSMAN_FLAG_CALLBACK_RETRYING_AFTER_NETWORK_FAILURE = 0x200,

    // Flag indicates that client shell successfully reconnected with the server after attempting to reconnect to the server
    WSMAN_FLAG_CALLBACK_RECONNECTED_AFTER_NETWORK_FAILURE = 0x400,    

    // Flag indicates that the client shell attempts to reconnect to the server failed and hence it is AutoDisconnecting
    WSMAN_FLAG_CALLBACK_SHELL_AUTODISCONNECTING      = 0x800,

    // Flag indicates that the client shell got into broken state in the middle of retry notification sequence due to some internal error at wsman layer
    WSMAN_FLAG_CALLBACK_RETRY_ABORTED_DUE_TO_INTERNAL_ERROR = 0x1000,

    // Flag that indicates for a receive operation that a delay stream request has been processed
    WSMAN_FLAG_CALLBACK_RECEIVE_DELAY_STREAM_REQUEST_PROCESSED = 0X2000
};

//
// -----------------------------------------------------------------------------
// Closes an asynchronous operation; if the callback associated with the operation 
//  is pending and have not completed when WSManCloseOperation is called, then 
//  the function marks the operation for deletion and returns; If the callback was not called,
//  the operation is cancelled and the operation callback is called with 
//  WSMAN_ERROR_OPERATION_ABORTED error; the operation handle is freed in all cases 
//  after the callback returns.
// -----------------------------------------------------------------------------
//
DWORD WINAPI WSManCloseOperation(
    _Inout_opt_ WSMAN_OPERATION_HANDLE operationHandle,
    DWORD flags
    );

//
//------------------------------------------------------------------------
// Shell Client API 
//  The API set includes the ability to create a shell, execute one or 
//  more commands, possibly pipe input stream to the command, collect the 
//  output stream from the command, terminate the command and finally 
//  close the shell. The client must retrieve the output initiating 
//  a WSManReceiveShellOutput once; the underlying implementation will 
//  handle pulling the data from the command, until the command is done. 
//  For each received stream, the completion function will be called with
//  the status of the command.
//
//  WSManCloseCommand or WSManCloseShell can be called any time to close the 
//    commmand or a shell operation. The callback will be called with 
//    WSMAN_FLAG_CALLBACK_END_OF_OPERATION flag to mark the end of the operation.
//    See WSManCloseCommand/WSManCloseShell API description for more info.
// -----------------------------------------------------------------------
//

//
// -----------------------------------------------------------------------
// Shell handle returned by WSManCreateShell API
// -----------------------------------------------------------------------
//
typedef struct WSMAN_SHELL *WSMAN_SHELL_HANDLE;

//
// -----------------------------------------------------------------------
// Command handle returned by WSManRunShellCommand API
// -----------------------------------------------------------------------
//
typedef struct WSMAN_COMMAND *WSMAN_COMMAND_HANDLE;

//
// -----------------------------------------------------------------------
// predefined stream ids 
// -----------------------------------------------------------------------
//
#define WSMAN_STREAM_ID_STDIN L"stdin"
#define WSMAN_STREAM_ID_STDOUT L"stdout"
#define WSMAN_STREAM_ID_STDERR L"stderr"

//
// -----------------------------------------------------------------------
// stream selector - array of stream ids; ie L"stdin" or L"stdout" or L"stderr"
// -----------------------------------------------------------------------
//
typedef struct _WSMAN_STREAM_ID_SET
{
    DWORD streamIDsCount;
    _In_reads_opt_(streamIDsCount) PCWSTR *streamIDs;

} WSMAN_STREAM_ID_SET;

//
// -----------------------------------------------------------------------
// Environment variable 
// -----------------------------------------------------------------------
//
typedef struct _WSMAN_ENVIRONMENT_VARIABLE
{
    PCWSTR name;
    PCWSTR value;

} WSMAN_ENVIRONMENT_VARIABLE;

//
// -----------------------------------------------------------------------
// environment variable set - array of environment variables
// -----------------------------------------------------------------------
//
typedef struct _WSMAN_ENVIRONMENT_VARIABLE_SET
{
    DWORD varsCount;
    _In_reads_opt_(varsCount) WSMAN_ENVIRONMENT_VARIABLE *vars;

} WSMAN_ENVIRONMENT_VARIABLE_SET;

//
// -----------------------------------------------------------------------
// Shell initialization parameters 
// -----------------------------------------------------------------------
//
typedef struct _WSMAN_SHELL_STARTUP_INFO_V10
{
    WSMAN_STREAM_ID_SET *inputStreamSet;
    WSMAN_STREAM_ID_SET *outputStreamSet;
    DWORD idleTimeoutMs;
    PCWSTR workingDirectory;
    WSMAN_ENVIRONMENT_VARIABLE_SET *variableSet;

} WSMAN_SHELL_STARTUP_INFO_V10;

typedef struct _WSMAN_SHELL_STARTUP_INFO_V11 : _WSMAN_SHELL_STARTUP_INFO_V10
{
    PCWSTR name;
} WSMAN_SHELL_STARTUP_INFO_V11;


#if defined(WSMAN_API_VERSION_1_0)
typedef WSMAN_SHELL_STARTUP_INFO_V10 WSMAN_SHELL_STARTUP_INFO;
#elif defined(WSMAN_API_VERSION_1_1)
typedef WSMAN_SHELL_STARTUP_INFO_V11 WSMAN_SHELL_STARTUP_INFO;
#endif

typedef struct _WSMAN_SHELL_DISCONNECT_INFO
{
    DWORD idleTimeoutMs;
} WSMAN_SHELL_DISCONNECT_INFO;

//
// -----------------------------------------------------------------------
// Pre-defined URIs
// -----------------------------------------------------------------------
// 
#define WSMAN_SHELL_NS L"http://schemas.microsoft.com/wbem/wsman/1/windows/shell"
#define WSMAN_SHELL_NS_LEN (sizeof(WSMAN_SHELL_NS)/sizeof(WCHAR)-1)

// 
// -----------------------------------------------------------------------
// URI to create a Windows command shell; used with WSManCreateShell API
// -----------------------------------------------------------------------
// 
#define WSMAN_CMDSHELL_URI WSMAN_SHELL_NS L"/cmd"


//
// -----------------------------------------------------------------------
// Windows shell options
// -----------------------------------------------------------------------
// 
enum WSManShellFlag
{
    //Turn off compression for Send/Receive operations.  By default compression is
    //turned on, but if communicating with a down-level box it may be necessary to
    //do this.  Other reasons for turning it off is due to the extra memory consumption
    //and CPU utilization that is used as a result of compression.
    WSMAN_FLAG_NO_COMPRESSION = 0x1,
    WSMAN_FLAG_DELETE_SERVER_SESSION = 0x2,
    //Enable the service to drop operation output when running disconnected
    WSMAN_FLAG_SERVER_BUFFERING_MODE_DROP = 0x4,
    //Enable the service to block operation progress when output buffers are full
    WSMAN_FLAG_SERVER_BUFFERING_MODE_BLOCK = 0x8,
    //Enable receive call to not immediately retrieve results. Only applicable for Receive calls on commands
    WSMAN_FLAG_RECEIVE_DELAY_OUTPUT_STREAM = 0X10
};
typedef enum WSManShellFlag WSManShellFlag;

//
// -----------------------------------------------------------------------
// Windows command shell specific options
// -----------------------------------------------------------------------
// 

//
// -----------------------------------------------------------------------
// Code page option name to be used with WSManCreateShell 
//  API to remotely set the code page
// -----------------------------------------------------------------------
//
#define WSMAN_CMDSHELL_OPTION_CODEPAGE L"WINRS_CODEPAGE"

//
// -----------------------------------------------------------------------
// Option name used with WSManCreateShell API to not load the 
//  user profile on the remote server 
// -----------------------------------------------------------------------
//
#define WSMAN_SHELL_OPTION_NOPROFILE L"WINRS_NOPROFILE"

//
// -----------------------------------------------------------------------
// Option name used with WSManRunShellCommand API to 
//  indicate that the client side mode of standard input is Console;  
//  default  implies Pipe. 
// -----------------------------------------------------------------------
//
#define WSMAN_CMDSHELL_OPTION_CONSOLEMODE_STDIN L"WINRS_CONSOLEMODE_STDIN"

//
// -----------------------------------------------------------------------
// to be used with WSManRunShellCommand API to not use cmd.exe /c prefix when launching the command
// -----------------------------------------------------------------------
//
#define WSMAN_CMDSHELL_OPTION_SKIP_CMD_SHELL L"WINRS_SKIP_CMD_SHELL"

//
// -----------------------------------------------------------------------
// pre-defined command states
// -----------------------------------------------------------------------
//
#define WSMAN_COMMAND_STATE_DONE WSMAN_SHELL_NS L"/CommandState/Done"
#define WSMAN_COMMAND_STATE_PENDING WSMAN_SHELL_NS L"/CommandState/Pending"
#define WSMAN_COMMAND_STATE_RUNNING WSMAN_SHELL_NS L"/CommandState/Running"

//
// -----------------------------------------------------------------------
// Data structure returned after a Receive operation; each WSMAN_RECEIVE_DATA_RESULT
//  has a stream element with data that can be text (ANSI/UNICODE), binary content,
//  objects, or partial or full XML. In addition, the command state is reported 
//  to the client and exitCode if the command is done.
//
// This structure is allocated and owned by the winrm stack and it is valid
//  in the completion function only
// -----------------------------------------------------------------------
//
typedef struct _WSMAN_RECEIVE_DATA_RESULT
{
    PCWSTR streamId;          // string - any output stream name from the list passed to
                              // the server when creating the shell
    WSMAN_DATA streamData;    // always data as binary; can be stream text (ANSI/UNICODE), binary content or objects or partial or full XML

    // command state string values (shell specific) - the state of the command for which status is being reported
    PCWSTR commandState;      // if WSMAN_COMMAND_STATE_DONE then the command should be closed at this moment
    DWORD exitCode;

} WSMAN_RECEIVE_DATA_RESULT;

#if defined(WSMAN_API_VERSION_1_1)

typedef struct _WSMAN_CONNECT_DATA
{
    WSMAN_DATA data;
} WSMAN_CONNECT_DATA;

typedef struct _WSMAN_CREATE_SHELL_DATA
{
    WSMAN_DATA data;
} WSMAN_CREATE_SHELL_DATA;

typedef union _WSMAN_RESPONSE_DATA
{
    WSMAN_RECEIVE_DATA_RESULT receiveData;
    WSMAN_CONNECT_DATA connectData;
    WSMAN_CREATE_SHELL_DATA createData;
} WSMAN_RESPONSE_DATA;

#endif
//
// -----------------------------------------------------------------------
// Completion function used by all Shell functions 
// Returns error->code != 0 upon error; use error->errorDetail structure 
//  for extended error informations; the callback is called for each 
//  shell operation; after a WSManReceiveShellOutput operation is initiated, 
//  the callback is called for each output stream element or if error; 
//  the underlying implementation handles the polling of stream data
//  from the command or shell. If WSMAN_COMMAND_STATE_DONE state is received, no more 
//  streams will be received from the command, so the command can be closed 
//  using WSManCloseCommand(command).
// 
// If error->code != 0, the result is guaranteed to be NULL
//
// The error and result objects are allocated and owned by the winrm 
//  client stack; they are valid during the callback only; the user 
//  has to synchronously copy the data in the callback
// 
// This callback function will use the current access token, whether it is 
//  a process or impersonation token. 
// -----------------------------------------------------------------------
//

#if defined(WSMAN_API_VERSION_1_1)

typedef void (CALLBACK *WSMAN_SHELL_COMPLETION_FUNCTION)(
    _In_opt_ PVOID operationContext,                     //user defined context
    DWORD flags,                                         // one or more flags from WSManCallbackFlags
    _In_ WSMAN_ERROR *error,                             // error allocated and owned by the winrm stack; valid in the callback only;
    _In_ WSMAN_SHELL_HANDLE shell,                       // shell handle associated with the user context; must be closed using WSManCloseShell 
    _In_opt_ WSMAN_COMMAND_HANDLE command,               // command handle associated with the user context; must be closed using WSManCloseCommand  
    _In_opt_ WSMAN_OPERATION_HANDLE operationHandle,     // valid only for Send/Receive/Signal operations; must be closed using WSManCloseOperation  
    _In_opt_ WSMAN_RESPONSE_DATA *data                   // output data from command/shell; allocated internally and owned by the winrm stack
                                                         // valid only within this function. Currently used to send back receive stream data and 
                                                         // open Xml content in rsp:ConnectResponse
    );   
#else

typedef void (CALLBACK *WSMAN_SHELL_COMPLETION_FUNCTION)(
    _In_opt_ PVOID operationContext,                     //user defined context
    DWORD flags,                                         // one or more flags from WSManCallbackFlags
    _In_ WSMAN_ERROR *error,                             // error allocated and owned by the winrm stack; valid in the callback only;
    _In_ WSMAN_SHELL_HANDLE shell,                       // shell handle associated with the user context; must be closed using WSManCloseShell 
    _In_opt_ WSMAN_COMMAND_HANDLE command,               // command handle associated with the user context; must be closed using WSManCloseCommand  
    _In_opt_ WSMAN_OPERATION_HANDLE operationHandle,     // valid only for Send/Receive/Signal operations; must be closed using WSManCloseOperation  
    _In_opt_ WSMAN_RECEIVE_DATA_RESULT *data             // output data from command/shell; allocated internally and owned by the winrm stack
                                                         // valid only within this function
    );                                   

#endif
//
// -----------------------------------------------------------------------------
// Asynchronous structure to be passed to all Shell operations; 
//  it contains an optional user context and the callback function
// -----------------------------------------------------------------------------
//
typedef struct _WSMAN_SHELL_ASYNC
{
    _In_opt_ PVOID operationContext;                         
    _In_ WSMAN_SHELL_COMPLETION_FUNCTION completionFunction;
} WSMAN_SHELL_ASYNC;

//
// -----------------------------------------------------------------------------
// WSManCreateShell API - wxf:Create
// -----------------------------------------------------------------------------
//
void WINAPI WSManCreateShell(

    _Inout_ WSMAN_SESSION_HANDLE session,
    DWORD flags,  
    _In_ PCWSTR resourceUri,           // shell resource URI
    _In_opt_ WSMAN_SHELL_STARTUP_INFO *startupInfo,
    _In_opt_ WSMAN_OPTION_SET *options,
    _In_opt_ WSMAN_DATA *createXml,                     // open content for create shell
    _In_ WSMAN_SHELL_ASYNC *async,
    _Out_ WSMAN_SHELL_HANDLE *shell // should be closed using WSManCloseShell
);

//
// -----------------------------------------------------------------------------
//  WSManRunShellCommand API - rsp:Command
// -----------------------------------------------------------------------------
// 

//
// -----------------------------------------------------------------------
// array of command arguments
// -----------------------------------------------------------------------
//
typedef struct _WSMAN_COMMAND_ARG_SET
{
    DWORD argsCount;
    _In_reads_opt_(argsCount) PCWSTR *args;

} WSMAN_COMMAND_ARG_SET;

void WINAPI WSManRunShellCommand(

    _Inout_ WSMAN_SHELL_HANDLE shell,
    DWORD flags,  
    _In_ PCWSTR commandLine,
    _In_opt_ WSMAN_COMMAND_ARG_SET *args,
    _In_opt_ WSMAN_OPTION_SET *options,
    _In_ WSMAN_SHELL_ASYNC *async,
    _Out_ WSMAN_COMMAND_HANDLE *command // should be closed using WSManCloseCommand
);

//
// -----------------------------------------------------------------------------
//  WSManSignalShell API - rsp:Signal
// -----------------------------------------------------------------------------
//

//
// -----------------------------------------------------------------------
// control codes for the command
// -----------------------------------------------------------------------
// 
#define WSMAN_SIGNAL_SHELL_CODE_TERMINATE WSMAN_SHELL_NS L"/signal/terminate"
#define WSMAN_SIGNAL_SHELL_CODE_CTRL_C WSMAN_SHELL_NS L"/signal/ctrl_c"
#define WSMAN_SIGNAL_SHELL_CODE_CTRL_BREAK WSMAN_SHELL_NS L"/signal/ctrl_break"

void WINAPI WSManSignalShell(

    _In_ WSMAN_SHELL_HANDLE shell,
    _In_opt_ WSMAN_COMMAND_HANDLE command,         // if NULL, the Signal will be sent to the shell
    DWORD flags,
    _In_ PCWSTR code,             // signal code
    _In_ WSMAN_SHELL_ASYNC *async,
    _Out_ WSMAN_OPERATION_HANDLE *signalOperation  // should be closed using WSManCloseOperation
);

//
// -----------------------------------------------------------------------------
//  WSManReceiveShellOutput API - rsp:Receive
// -----------------------------------------------------------------------------
//

void WINAPI WSManReceiveShellOutput(

    _Inout_ WSMAN_SHELL_HANDLE shell,
    _In_opt_ WSMAN_COMMAND_HANDLE command,
    DWORD flags,
    _In_opt_ WSMAN_STREAM_ID_SET *desiredStreamSet,  // request output from a particular stream or list of streams
    _In_ WSMAN_SHELL_ASYNC *async,
    _Out_ WSMAN_OPERATION_HANDLE *receiveOperation // should be closed using WSManCloseOperation
);

//
// -----------------------------------------------------------------------------
//  WSManSendShellInput API - rsp:Send
// -----------------------------------------------------------------------------
//
void WINAPI WSManSendShellInput(

    _In_ WSMAN_SHELL_HANDLE shell,
    _In_opt_ WSMAN_COMMAND_HANDLE command,
    DWORD flags,
    _In_ PCWSTR streamId,               // input stream name 
    _In_ WSMAN_DATA *streamData,        // data as binary - that can contain text (ANSI/UNICODE), 
                                        // binary content or objects or partial or full XML
    BOOL endOfStream,
    _In_ WSMAN_SHELL_ASYNC *async,
    _Out_ WSMAN_OPERATION_HANDLE *sendOperation // should be closed using WSManCloseOperation
);

//
// -----------------------------------------------------------------------------
// WSManCloseCommand API 
// -----------------------------------------------------------------------------
//

//
// -----------------------------------------------------------------------------
// Closes a command (signals the termination of a command); the WSManCloseCommand callback 
//  is called with WSMAN_FLAG_CALLBACK_END_OF_OPERATION flag as result of this operation
// -----------------------------------------------------------------------------
//
void WINAPI WSManCloseCommand(
    _Inout_opt_ WSMAN_COMMAND_HANDLE commandHandle,
    DWORD flags,
    _In_ WSMAN_SHELL_ASYNC *async
    );

//
// -----------------------------------------------------------------------------
// WSManCloseShell API 
// -----------------------------------------------------------------------------
//

//
// -----------------------------------------------------------------------------
// Closes a shell; the WSManCloseShell callback is called with 
//  WSMAN_FLAG_CALLBACK_END_OF_OPERATION flag as result of this operation
// -----------------------------------------------------------------------------
//
void WINAPI WSManCloseShell(
    _Inout_opt_ WSMAN_SHELL_HANDLE shellHandle,
    DWORD flags,
    _In_ WSMAN_SHELL_ASYNC *async
    );

//New APIs defined for disconnect/reconnect
#if defined(WSMAN_API_VERSION_1_1)

//
// -----------------------------------------------------------------------------
// WSManCreateShellEx API - wxf:Create with specific shell Id.
// -----------------------------------------------------------------------------
//
void WINAPI WSManCreateShellEx(
    _Inout_ WSMAN_SESSION_HANDLE session,
    DWORD flags,  
    _In_ PCWSTR resourceUri,           // shell resource URI
    _In_ PCWSTR shellId,
    _In_opt_ WSMAN_SHELL_STARTUP_INFO *startupInfo,
    _In_opt_ WSMAN_OPTION_SET *options,
    _In_opt_ WSMAN_DATA *createXml,                     // open content for create shell
    _In_ WSMAN_SHELL_ASYNC *async,
    _Out_ WSMAN_SHELL_HANDLE *shell // should be closed using WSManCloseShell
);

//
// -----------------------------------------------------------------------------
// WSManRunShellCommandEx API - rsp:Command with specific command Id.
// -----------------------------------------------------------------------------
//
void WINAPI WSManRunShellCommandEx(

    _Inout_ WSMAN_SHELL_HANDLE shell,
    DWORD flags,  
    _In_ PCWSTR commandId,
    _In_ PCWSTR commandLine,
    _In_opt_ WSMAN_COMMAND_ARG_SET *args,
    _In_opt_ WSMAN_OPTION_SET *options,
    _In_ WSMAN_SHELL_ASYNC *async,
    _Out_ WSMAN_COMMAND_HANDLE *command // should be closed using WSManCloseCommand
);

//
// -----------------------------------------------------------------------------
// WSManDisconnectShell API - rsp:Disconnect
// -----------------------------------------------------------------------------
//
void WINAPI WSManDisconnectShell(
    _Inout_ WSMAN_SHELL_HANDLE shell,
    DWORD flags,  
    _In_ WSMAN_SHELL_DISCONNECT_INFO* disconnectInfo,
    _In_ WSMAN_SHELL_ASYNC *async                                    
    );

//
// -----------------------------------------------------------------------------
// WSManReconnectShell API - rsp:Disconnect
// -----------------------------------------------------------------------------
//
void WINAPI WSManReconnectShell(
    _Inout_ WSMAN_SHELL_HANDLE shell,
    DWORD flags,  
    _In_ WSMAN_SHELL_ASYNC *async                                    
    );

//
// -----------------------------------------------------------------------------
// WSManReconnectShell API - rsp:Disconnect
// This is a temporary API for first week's delivery. This will be replaced
// by an API that does not take a callback. Instead the callback supplied to
// WSManRunShellCommand is used to report the completion of this operation
// -----------------------------------------------------------------------------
//
void WINAPI WSManReconnectShellCommand(
    _Inout_ WSMAN_COMMAND_HANDLE commandHandle,
    DWORD flags,  
    _In_ WSMAN_SHELL_ASYNC *async                                    
    );

//
// -----------------------------------------------------------------------------
// WSManConnectShell API - rsp:Connect
// -----------------------------------------------------------------------------
//
void WINAPI WSManConnectShell(
    _Inout_ WSMAN_SESSION_HANDLE session,
    DWORD flags,  
    _In_ PCWSTR resourceUri,
    _In_ PCWSTR shellID,           // shell Identifier
    _In_opt_ WSMAN_OPTION_SET *options,
    _In_opt_ WSMAN_DATA *connectXml,                     // open content for connect shell
    _In_ WSMAN_SHELL_ASYNC *async,
    _Out_ WSMAN_SHELL_HANDLE *shell // should be closed using WSManCloseShell
);

//
// -----------------------------------------------------------------------------
// WSManConnectShellCommand API - rsp:Connect
// -----------------------------------------------------------------------------
//
void WINAPI WSManConnectShellCommand(
    _Inout_ WSMAN_SHELL_HANDLE shell,
    DWORD flags,  
    _In_ PCWSTR commandID,  //command Identifier
    _In_opt_ WSMAN_OPTION_SET *options,
    _In_opt_ WSMAN_DATA *connectXml,                // open content for connect command
    _In_ WSMAN_SHELL_ASYNC *async,
    _Out_ WSMAN_COMMAND_HANDLE *command // should be closed using WSManCloseCommand
);

#endif

//
// -----------------------------------------------------------------------------
// Plug-in APIs.  These APIs are used by plug-ins for reporting results
// -----------------------------------------------------------------------------
//

//
// ------------------------------------------------------------------------
// Sender information
// ------------------------------------------------------------------------
//

typedef struct _WSMAN_CERTIFICATE_DETAILS
{
    PCWSTR subject;         // Certificate subject in distinguished form
                            // Ex: "CN=xyz.com, OU=xyz management, O=Microsoft, L=Redmond, S=Washington, C=US"
    PCWSTR issuerName;      // Certificate issuer in distinguished form
                            // Ex: "CN=Microsoft Secure Server Authority, DC=redmond, DC=corp, DC=microsoft, DC=com" 
    PCWSTR issuerThumbprint;// Thumbprint of Certificate issuer
    PCWSTR subjectName;     // Certificate Subject Alternative Name (SAN) if available or subject Common Name (CN)
                            // Ex: "xyz.com" 
} WSMAN_CERTIFICATE_DETAILS;

typedef struct _WSMAN_SENDER_DETAILS
{
    PCWSTR senderName;                  // Username of the sender 
    PCWSTR authenticationMechanism;      // 
    WSMAN_CERTIFICATE_DETAILS *certificateDetails; // valid only if the authentication is client certificates
    HANDLE clientToken;
    PCWSTR httpURL;
} WSMAN_SENDER_DETAILS;

//
// -----------------------------------------------------------------------------
// A pointer to a WSMAN_PLUGIN_REQUEST structure is passed to all operation
// entry points within the plug-in.  All result notification APIs use this
// pointer to match the result with the request.  All information in the 
// structure will stay valid until the plug-in calls WSManPluginOperationComplete
// on the operation.  A plug-in has two ways of handling cancellation of an 
// operation.  The plug-in can check the shutdownNotification boolean value
// if it iterates through a set of results, or if the plug-in is more 
// asynchronous in nature then the shutdownNotificationHandle can be used
// when queuing up asynchronous notification threads.
// -----------------------------------------------------------------------------
//
typedef struct _WSMAN_PLUGIN_REQUEST
{
    WSMAN_SENDER_DETAILS *senderDetails;
    PCWSTR locale;
    PCWSTR resourceUri;
    WSMAN_OPERATION_INFO *operationInfo;
    volatile BOOL shutdownNotification;
    HANDLE shutdownNotificationHandle;
    PCWSTR dataLocale;
} WSMAN_PLUGIN_REQUEST;
//
// -----------------------------------------------------------------------------
// This API is called by a plug-in that supports Shell commands.  When 
// Create Shell and Create Command plug-in entry points are called the plug-in
// need to return a context to that shell or command before data can be channelled
// into the plug-in, or before data can be returned to the called.  WS-Man calls
// the WSMAN_PLUGIN_RELEASE_SHELL_CONTEXT entry point during shell shutdown when
// it is safe to delete the plug-in shell context, and WS-Man calls the
// WSMAN_PLUGIN_RELEASE_COMMAND_CONTEXT entry point when it is safe to delete
// the plug-in command context.  Any context reported through
// WSManPluginReportContext may not be deleted until the corresponding release
// function has been called. Failure to follow the contract will result in
// errors being generated.
// -----------------------------------------------------------------------------
//
DWORD WINAPI WSManPluginReportContext(
    _In_ WSMAN_PLUGIN_REQUEST *requestDetails,
    _In_ DWORD flags,
    _In_ PVOID context
    );

typedef VOID (WINAPI *WSMAN_PLUGIN_RELEASE_SHELL_CONTEXT)(
    _In_ PVOID shellContext
    );

typedef VOID (WINAPI *WSMAN_PLUGIN_RELEASE_COMMAND_CONTEXT)(
    _In_ PVOID shellContext,
    _In_ PVOID commandContext
    );

//
// -----------------------------------------------------------------------------
// This API is used by most a shell plug-in to report data for the Receive 
// operation.  This is the only operation that returns results that has a 
// different API due to the extra shell data that is needed.  This API
// is called for every result in the stream.  Once all data is received
// the WSManPluginOperationComplete API must be called.
// stream and streamResult are one pair of information that if one parameter
// is specified the other is needed otherwise ERROR_INVALID_PARAMETER is
// returned.  commandState and exitCode are also a pair, and exitCode is
// ignored in all cases but when commandState is WSMAN_COMMAND_STATE_DONE
// is specified.  Both pairs of parameters are independent to each other
// so the API can be used to register the stream data, command state or 
// both.
// flags:
//      WSMAN_FLAG_RECEIVE_RESULT_NO_MORE_DATA 
//          No more data on this stream.  Only valid when a stream is specified.
//      WSMAN_FLAG_RECEIVE_FLUSH
//          Send the data as soon as possible.  Normally data is held onto in 
//          order to maximise the size of the response packet.  This should
//          only be used if a request/response style of data is needed between
//          the send and receive data streams.
//      WSMAN_FLAG_RECEIVE_RESULT_DATA_BOUNDARY
//          Data reported is at a boundary. Plugins usually serialize and fragment
//          output data objects and push them along the receive byte stream. 
//          If the current data chunk being reported is an end fragment of the 
//          data object current processed, plugins would set this flag.
// -----------------------------------------------------------------------------
//
#define WSMAN_FLAG_RECEIVE_RESULT_NO_MORE_DATA 1
#define WSMAN_FLAG_RECEIVE_FLUSH               2
#define WSMAN_FLAG_RECEIVE_RESULT_DATA_BOUNDARY 4

DWORD WINAPI WSManPluginReceiveResult(
    _In_ WSMAN_PLUGIN_REQUEST *requestDetails,
    _In_ DWORD flags,
    _In_opt_ PCWSTR stream,
    _In_opt_ WSMAN_DATA *streamResult,
    _In_opt_ PCWSTR commandState,
    _In_ DWORD exitCode
    );

//
// -----------------------------------------------------------------------------
// This API is used by all plug-ins to report the completion of an operation.
// For operations like Get, Put, Create and Invoke this API is likely to be 
// called after the result has been called.  For Delete operations where no 
// result is needed other than status, this API is all that is needed.
// For more complex operations like Enumerations, Subscriptions and shell 
// Receive operations this API is is used to report the completion of the 
// data stream.  The Create Shell and Create Command operations must also
// call this when the shell and command operations a completed fully.
// extendedInformation is used by plugin 
// - to either report additional faiure information in case of an error 
//   (errorCode != No_ERROR) or 
// - to supply open Xml content in certain wsman responses like rsp:ConnectResponse
// -----------------------------------------------------------------------------
//
DWORD WINAPI WSManPluginOperationComplete(
    _In_ WSMAN_PLUGIN_REQUEST *requestDetails,
    _In_ DWORD flags,
    _In_ DWORD errorCode,
    _In_opt_ PCWSTR extendedInformation
    );

//
// -----------------------------------------------------------------------------
//This API is used to get operational information for items such as timeouts 
//and data restrictions associated with the operation.  It is not recommended 
//that a plug-in handles these kinds of parameters for anything other than 
//informational use. 
//
//Locale parameters return WSMAN_DATA_TEXT, which is owned internally, 
//so you don't need to delete the text buffers.
// -----------------------------------------------------------------------------
//

#define WSMAN_PLUGIN_PARAMS_MAX_ENVELOPE_SIZE 1
#define WSMAN_PLUGIN_PARAMS_TIMEOUT 2
#define WSMAN_PLUGIN_PARAMS_REMAINING_RESULT_SIZE 3
#define WSMAN_PLUGIN_PARAMS_LARGEST_RESULT_SIZE 4
#define WSMAN_PLUGIN_PARAMS_GET_REQUESTED_LOCALE 5 /* Returns WSMAN_DATA_TEXT */
#define WSMAN_PLUGIN_PARAMS_GET_REQUESTED_DATA_LOCALE 6 /* Returns WSMAN_DATA_TEXT */


DWORD WINAPI WSManPluginGetOperationParameters ( 
    _In_ WSMAN_PLUGIN_REQUEST *requestDetails,
    _In_ DWORD flags,
    _Out_ WSMAN_DATA *data
    );




//
// -----------------------------------------------------------------------------
// This API is used to get plugin configuration information from within the plugin.
// The plugin can ask for specific data by specifying a different flag for each as follows:
// WSMAN_PLUGIN_PARAMS_SHAREDHOST                           1    Specifies if the plugin is configured to run as a shared host or separate host.
// WSMAN_PLUGIN_PARAMS_RUNAS_USER                           2    Specifies the RunAs User configured for the plugin. If no RunAs user is configured, this will return an empty string.
// WSMAN_PLUGIN_PARAMS_AUTORESTART                         3    Specifies if the plugin is configured to be autorestarted.
// WSMAN_PLUGIN_PARAMS_HOSTIDLETIMEOUTSECONDS    4    Specifies the idle timeout in seconds configured for the host process.
// -----------------------------------------------------------------------------
//
#define WSMAN_PLUGIN_PARAMS_SHAREDHOST 1
#define WSMAN_PLUGIN_PARAMS_RUNAS_USER 2
#define WSMAN_PLUGIN_PARAMS_AUTORESTART 3
#define WSMAN_PLUGIN_PARAMS_HOSTIDLETIMEOUTSECONDS 4
#define WSMAN_PLUGIN_PARAMS_NAME 5

DWORD WINAPI WSManPluginGetConfiguration (
  _In_   PVOID pluginContext,
  _In_   DWORD flags,
  _Out_  WSMAN_DATA *data
);



//
// -----------------------------------------------------------------------------
// This API is used by plugins to report completion
// flags are reserved
// pluginContext MUST be the same context that plugin provided to the WSManPluginStartup method
// -----------------------------------------------------------------------------
//
DWORD WINAPI WSManPluginReportCompletion(
  _In_      PVOID pluginContext,
  _In_      DWORD flags
);


//
// -----------------------------------------------------------------------------
// This API is used release memory that is held for the purpose of populating
// the WSMAN_PLUGIN_REQUEST that is passed into operation plug-in entry points.
// This API can be called any time between a plug-in entry point is called and
// the entry point calling WSManPluginOperationComplete.  This API does not need
// to be called.  Not calling it will result in all memory being freed up when 
// WSManPluginOperationComplete is called.  Calling this method can result in
// significant amounts of memory to be freed up.  After calling this API
// the plug-in must not access any member variables from within the 
// WSMAN_PLUGIN_REQUEST structure.
// A good use of this API is in the following situation:
// A plug-in implements the Shell infrastructure.  The WSMAN_PLUGIN_SHELL 
// entry point is called and that method calls WSManPluginReportContext.
// No other information from the shell WSMAN_PLUGIN_REQUEST is needed from this 
// point on and because WSManPluginOperationComplete is not called for 
// potentially a long time in the future, calling WSManPluginFreeRequestDetails
// can potentially free a lot of resources.  The command and receive entry 
// points are also good categories as they are called once, but the plugin may
// not call the operation complete method for some time.  
// -----------------------------------------------------------------------------
//
DWORD WINAPI WSManPluginFreeRequestDetails(_In_ WSMAN_PLUGIN_REQUEST *requestDetails);

//
// -----------------------------------------------------------------------------
// Plug-in DLL Entry points.  A plug-in needs to have their catalog registered
// with the WSMan service and it contains the names of the plug-in DLL entry 
// points.  The entry points themselves need to conform to these prototype
// definitions
// -----------------------------------------------------------------------------
//

//
// -----------------------------------------------------------------------------
// Each plug-in needs to support the Startup callback.  A plug-in may be 
// initialized more than once within the same process, but only once per 
// applicationIdentification.
// -----------------------------------------------------------------------------
//
#define WSMAN_PLUGIN_STARTUP_REQUEST_RECEIVED              0x0
#define WSMAN_PLUGIN_STARTUP_AUTORESTARTED_REBOOT    0x1
#define WSMAN_PLUGIN_STARTUP_AUTORESTARTED_CRASH      0x2

typedef DWORD (WINAPI *WSMAN_PLUGIN_STARTUP)(
    _In_ DWORD flags,
    _In_ PCWSTR applicationIdentification,
    _In_opt_ PCWSTR extraInfo,
    _Out_ PVOID *pluginContext
    );

//
// -----------------------------------------------------------------------------
// Each plug-in needs to support the Shutdown callback.  Each successful call 
// to Startup will result in a call to Shutdown before the DLL is unloaded.
// It is important to make sure the plug-in tracks the number of times the 
// Startup entry point is called so the plug-in is not shutdown prematurely.
// -----------------------------------------------------------------------------
//
#define WSMAN_PLUGIN_SHUTDOWN_SYSTEM  1
#define WSMAN_PLUGIN_SHUTDOWN_SERVICE 2
#define WSMAN_PLUGIN_SHUTDOWN_IISHOST 3
#define WSMAN_PLUGIN_SHUTDOWN_IDLETIMEOUT_ELAPSED 4

typedef DWORD (WINAPI *WSMAN_PLUGIN_SHUTDOWN)(
    _In_opt_ PVOID pluginContext,
    _In_ DWORD flags,
    _In_ DWORD reason
    );

//
// -----------------------------------------------------------------------------
// A plug-in that supports the Shell operations needs to implement this callback
// to allow commands to be created and to allow data to be streamed into either
// a shell or command.  The plug-in must call WSManPluginReportContext to 
// report the shell context.  Once the shell is completed or when it is closed
// via the operationClosed boolean value or operationClosedHandle in the 
// requestDetails the plug-in needs to call WSManPluginOperationComplete.
// The shell is active until this time.
// -----------------------------------------------------------------------------
//
typedef VOID (WINAPI *WSMAN_PLUGIN_SHELL)(
    _In_ PVOID pluginContext,   //Relates to context returned from WSMAN_PLUGIN_STARTUP
    _In_ WSMAN_PLUGIN_REQUEST *requestDetails,
    _In_ DWORD flags,
    _In_opt_ WSMAN_SHELL_STARTUP_INFO *startupInfo,
    _In_opt_ WSMAN_DATA *inboundShellInformation
    );

//
// -----------------------------------------------------------------------------
// A plug-in that supports the Shell operations and needs to create commands
// that are associated with the shell needs to implement this callback.
// The plug-in must call WSManPluginReportContext to 
// report the command context.  Once the command is completed or when it is closed
// via the operationClosed boolean value or operationClosedHandle in the 
// requestDetails the plug-in needs to call WSManPluginOperationComplete.
// The command is active until this time.
// -----------------------------------------------------------------------------
//
typedef VOID (WINAPI *WSMAN_PLUGIN_COMMAND)(
    _In_ WSMAN_PLUGIN_REQUEST *requestDetails,
    _In_ DWORD flags,
    _In_ PVOID shellContext,
    _In_ PCWSTR commandLine,
    _In_opt_ WSMAN_COMMAND_ARG_SET *arguments
    );

//
// -----------------------------------------------------------------------------
// A plug-in receives an inbound data stream to either the shell or command
// via this callback.  Each piece of data causes the callback to be called once.
// For each piece of data the plug-in calls WSManPluginOperationComplete to 
// acknowledge receipt and to allow the next piece of data to be delivered.
// -----------------------------------------------------------------------------
//
#define WSMAN_FLAG_SEND_NO_MORE_DATA 1

typedef VOID (WINAPI *WSMAN_PLUGIN_SEND)(
    _In_ WSMAN_PLUGIN_REQUEST *requestDetails,
    _In_ DWORD flags,
    _In_ PVOID shellContext,
    _In_opt_ PVOID commandContext,
    _In_ PCWSTR stream,
    _In_ WSMAN_DATA *inboundData
    );

//
// -----------------------------------------------------------------------------
// A plug-in sends an outbound data stream from either the shell or command
// via this callback.  This API is called when an inbound request from a client
// is received.  This callback may be called against the shell and/or command
// based on the client request.  Each piece of data that needs to be sent back
// to the client is done so through the WSManPluginReceiveResult API.  Once 
// all data has been send, when the stream is terminated via some internal means,
// or if the receive call is cancelled through the operationClosed boolean 
// value or operationClosedHandle, the plug-in needs to call 
// WSManPluginOperationComplete.  The operation is marked as active until this 
// time.
// -----------------------------------------------------------------------------
//
typedef VOID (WINAPI *WSMAN_PLUGIN_RECEIVE)(
    _In_ WSMAN_PLUGIN_REQUEST *requestDetails,
    _In_ DWORD flags,
    _In_ PVOID shellContext,
    _In_opt_ PVOID commandContext,
    _In_opt_ WSMAN_STREAM_ID_SET *streamSet
    ); 

//
// -----------------------------------------------------------------------------
// A plug-in receives an inbound signal to either the shell or command
// via this callback.  Each signal causes the callback to be called once.
// For each call the plug-in calls WSManPluginOperationComplete to 
// acknowledge receipt and to allow the next signal to be received.
// A signal can cause the shell or command to be terminated, so the result
// of this callback may be many completion calls for the Signal, Receive, Command
// and Shell operations.
// -----------------------------------------------------------------------------
//
typedef VOID (WINAPI *WSMAN_PLUGIN_SIGNAL)(
    _In_ WSMAN_PLUGIN_REQUEST *requestDetails,
    _In_ DWORD flags,
    _In_ PVOID shellContext,
    _In_opt_ PVOID commandContext,
    _In_ PCWSTR code
    );

typedef VOID (WINAPI* WSMAN_PLUGIN_CONNECT)(
    _In_ WSMAN_PLUGIN_REQUEST *requestDetails,
    _In_ DWORD flags,
    _In_ PVOID shellContext,
    _In_opt_ PVOID commandContext,
    _In_opt_ WSMAN_DATA *inboundConnectInformation
     );


//
// -----------------------------------------------------------------------------
// Authorization Plug-in Structures
// -----------------------------------------------------------------------------
//

//
// -----------------------------------------------------------------------------
// WSMAN_AUTHZ_QUOTA
// Any of the maxAllowed entries can be set to MAX_DWORD to mark quota as 
// unlimited.  If maxAllowedOperationsPerTimeslot is MAX_DWORD the timeslotSize
// is ignored.
// -----------------------------------------------------------------------------
//
typedef struct _WSMAN_AUTHZ_QUOTA
{
    DWORD maxAllowedConcurrentShells;
    DWORD maxAllowedConcurrentOperations;
    DWORD timeslotSize;
    DWORD maxAllowedOperationsPerTimeslot; 
} WSMAN_AUTHZ_QUOTA;

//
// -----------------------------------------------------------------------------
// Authorization Plug-in entry points
// -----------------------------------------------------------------------------
//

//
// -----------------------------------------------------------------------------
// WSMAN_PLUGIN_AUTHORIZE_USER
// Plug-in needs to have a DLL export of WSManPluginAuthzUser to handle this
// request.  When a user issues a request and has not made a request in
// some configurable time this entry point is called to determin if the 
// user is allowed to carry out any request at all.  The plug-in must call
// WSManPluginAuthzUserComplete to report either the user is not authorized
// with ERROR_ACCESS_DENIED or for successful authorization NO_ERROR.
// ERROR_WSMAN_REDIRECT_REQUIRED should be reported if a HTTP redirect is
// required for this user, in which case the new HTTP URI should be recorded
// in the extendedErrorInformation.  All other errors are report a failure
// to the client but no specific information is reported.
// -----------------------------------------------------------------------------
//
typedef VOID (WINAPI * WSMAN_PLUGIN_AUTHORIZE_USER)(
    _In_ PVOID pluginContext,
    _In_ WSMAN_SENDER_DETAILS *senderDetails,
    _In_ DWORD flags
    );

//
// -----------------------------------------------------------------------------
// WSMAN_PLUGIN_AUTHORIZE_USER
// Plug-in needs to have a DLL export of WSManPluginAuthzOperation to handle this
// request.  The plug-in must call WSManPluginAuthzUserComplete to report either 
// the user is not authorized with ERROR_ACCESS_DENIED or for successful 
// authorization NO_ERROR.  All other errors are reported as a failure
// to the client as a SOAP fault with information given in the 
// extendedErrorInformation parameter.
// -----------------------------------------------------------------------------
//
typedef VOID (WINAPI * WSMAN_PLUGIN_AUTHORIZE_OPERATION)(
    _In_ PVOID pluginContext,
    _In_ WSMAN_SENDER_DETAILS *senderDetails,
    _In_ DWORD flags,
    _In_ DWORD operation,
    _In_ PCWSTR action,
    _In_ PCWSTR resourceUri
    );

typedef VOID (WINAPI * WSMAN_PLUGIN_AUTHORIZE_QUERY_QUOTA)(
    _In_ PVOID pluginContext,
    _In_ WSMAN_SENDER_DETAILS *senderDetails,
    _In_ DWORD flags
    );

typedef VOID (WINAPI * WSMAN_PLUGIN_AUTHORIZE_RELEASE_CONTEXT)(
    _In_ PVOID userAuthorizationContext
    );

//
// -----------------------------------------------------------------------------
// Authorization Plug-in Callback methods
// -----------------------------------------------------------------------------
//
DWORD WINAPI WSManPluginAuthzUserComplete ( 
    _In_ WSMAN_SENDER_DETAILS *senderDetails,
    _In_ DWORD flags,
    _In_opt_ PVOID userAuthorizationContext,
    _In_opt_ HANDLE impersonationToken,
    _In_ BOOL userIsAdministrator,
    _In_ DWORD errorCode,
    _In_opt_ PCWSTR extendedErrorInformation
    );

DWORD WINAPI WSManPluginAuthzOperationComplete ( 
    _In_ WSMAN_SENDER_DETAILS *senderDetails,
    _In_ DWORD flags,
    _In_opt_ PVOID userAuthorizationContext,
    _In_ DWORD errorCode,
    _In_opt_ PCWSTR extendedErrorInformation
    );

DWORD WINAPI WSManPluginAuthzQueryQuotaComplete ( 
    _In_ WSMAN_SENDER_DETAILS *senderDetails,
    _In_ DWORD flags,
    _In_opt_ WSMAN_AUTHZ_QUOTA *quota,
    _In_ DWORD errorCode,
    _In_opt_ PCWSTR extendedErrorInformation
    );



#ifdef __cplusplus
} // end of extern C 
#endif   // __cplusplus


#endif /* WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP | WINAPI_PARTITION_PKG_WINMGMT) */
#pragma endregion

#pragma option pop /*P_O_Pop*/
#endif // _WSMAN_H_

