//***************************************************************************** // Copyright (C) 2007 Microsoft Corporation // All rights reserved. // // Definition file for WSMAN //***************************************************************************** #ifndef _WSMAN_H_ #define _WSMAN_H_ #include #if defined(WSMAN_API_VERSION_1_0) #else #error "Define WSMAN_API_VERSION_1_0 before including wsman.h" #endif #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_ecount(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_ecount(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_ecount_opt(optionsCount) WSMAN_OPTION *options; BOOL optionsMustUnderstand; } WSMAN_OPTION_SET; // // ----------------------------------------------------------------------------- // 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_ecount_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; 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; } WSMAN_OPERATION_INFO; // // ----------------------------------------------------------------------------- // 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, 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_ecount_part_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_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 150kb), // 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. }; 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_ecount_part_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, }; // // ----------------------------------------------------------------------------- // 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_ecount_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_ecount_opt(varsCount) WSMAN_ENVIRONMENT_VARIABLE *vars; } WSMAN_ENVIRONMENT_VARIABLE_SET; // // ----------------------------------------------------------------------- // Shell initialization parameters // ----------------------------------------------------------------------- // typedef struct _WSMAN_SHELL_STARTUP_INFO { WSMAN_STREAM_ID_SET *inputStreamSet; WSMAN_STREAM_ID_SET *outputStreamSet; DWORD idleTimeoutMs; PCWSTR workingDirectory; WSMAN_ENVIRONMENT_VARIABLE_SET *variableSet; } WSMAN_SHELL_STARTUP_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 = 1 }; 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; // // ----------------------------------------------------------------------- // 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. // ----------------------------------------------------------------------- // 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 ); // // ----------------------------------------------------------------------------- // 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 __nullterminated 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_ecount_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 __nullterminated 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 ); // // ----------------------------------------------------------------------------- // 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. // ----------------------------------------------------------------------------- // #define WSMAN_FLAG_RECEIVE_RESULT_NO_MORE_DATA 1 #define WSMAN_FLAG_RECEIVE_FLUSH 2 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. // ----------------------------------------------------------------------------- // DWORD WINAPI WSManPluginOperationComplete( __in WSMAN_PLUGIN_REQUEST *requestDetails, __in DWORD flags, __in DWORD errorCode, __in_opt PCWSTR extendedErrorInformation ); // // ----------------------------------------------------------------------------- //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 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. // ----------------------------------------------------------------------------- // 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 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 ); // // ----------------------------------------------------------------------------- // 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 // _WSMAN_H_