Modified to add 'Align 4' on the HTTP_FILTER_VERSION, and remove the constant #SF_NOTIFY_READ_RAW_DATA, as it is no longer used.
ots_iisapi_filter_ascii.pb
Code: Select all
; ------------------------------------------------------------
; Program name: ots_iisapi_filter_ascii.pb
; Written by: Rich Algeni, Jr.
; Date written: 09/11/2015
;
; Purpose: 64 bit Internet Information Server Ascii Filter API Dll
; ------------------------------------------------------------
EnableExplicit
XIncludeFile "D:\development\Source Code Repository For Rich Algeni\PureBasic\iis_api\httpFilt_ascii.pbi"
; ************************************************************************************
; initialization procedure
; ************************************************************************************
ProcedureDLL.i AttachProcess(instance.i)
Protected logText.s = "ots_iisapi_filter AttachProcess() Ascii version completed successfully"
OutputDebugString_(logText)
ProcedureReturn #True
EndProcedure
; ************************************************************************************
; DetachProcess
; ************************************************************************************
ProcedureDLL.i DetachProcess(instance.i)
EndProcedure
; ************************************************************************************
; AttachThread
; ************************************************************************************
ProcedureDLL.i AttachThread(instance.i)
EndProcedure
; ************************************************************************************
; DetachThread
; ************************************************************************************
ProcedureDLL.i DetachThread(instance.i)
EndProcedure
; ************************************************************************************
; GetFilterVersion is called when the dll is loaded
; ************************************************************************************
ProcedureDLL.i GetFilterVersion(*pVer.HTTP_FILTER_VERSION)
Protected logText.s = "ots_iisapi_filter GetFilterVersion()"
Protected descriptionSize.l
Protected notificationMask.l
Protected description.s = "ISAPI Ascii Filter written in PureBasic"
Protected descripSize.l = Len(description)
notificationMask = #SF_NOTIFY_SECURE_PORT |
#SF_NOTIFY_NONSECURE_PORT |
#SF_NOTIFY_PREPROC_HEADERS |
#SF_NOTIFY_AUTHENTICATION |
#SF_NOTIFY_URL_MAP |
#SF_NOTIFY_ACCESS_DENIED |
#SF_NOTIFY_SEND_RESPONSE |
#SF_NOTIFY_SEND_RAW_DATA |
#SF_NOTIFY_LOG |
#SF_NOTIFY_END_OF_REQUEST |
#SF_NOTIFY_END_OF_NET_SESSION |
#SF_NOTIFY_AUTH_COMPLETE
descriptionSize = StringByteLength(description, #PB_Ascii)
; make the length of the description the same number of characters as #SF_MAX_FILTER_DESC_LEN
PokeL(@*pVer\dwFilterVersion, #HTTP_FILTER_REVISION)
PokeS(@*pVer\lpszFilterDesc, description, descriptionSize, #PB_Ascii)
PokeL(@*pVer\dwFlags, notificationMask)
logText + ", ISAPI Server Version: 0x" + RSet(Hex(*pVer\dwServerFilterVersion, #PB_Long), 8, "0")
logText + ", ISAPI Client Version: 0x" + RSet(Hex(*pVer\dwFilterVersion, #PB_Long), 8, "0")
logText + ", notifications requested: 0x" + RSet(Hex(notificationMask, #PB_Long), 8, "0")
OutputDebugString_(logText)
; return true, returning false will cause the dll to be unloaded
ProcedureReturn #True
EndProcedure
; ************************************************************************************
; This is the main function that is called for each client request pECB contains all needed data
; ************************************************************************************
ProcedureDLL.i HttpFilterProc(*pfc.HTTP_FILTER_CONTEXT, notificationType.l, *pvNotification)
Protected logText.s = "ots_iisapi_filter HttpFilterProc() > notificationType = " + Str(notificationType)
OutputDebugString_(logText)
; return get next notification
ProcedureReturn #SF_STATUS_REQ_NEXT_NOTIFICATION
EndProcedure
; ************************************************************************************
; TerminateFilter is called before unloading the dll.
; ************************************************************************************
ProcedureDLL.i TerminateFilter(dwFlags.l)
Protected logText.s = "ots_iisapi_filter TerminateFilter() > process terminating"
OutputDebugString_(logText)
; return true
ProcedureReturn #True
EndProcedure
; IDE Options = PureBasic 5.46 LTS (Windows - x64)
; ExecutableFormat = Shared dll
; CursorPosition = 73
; FirstLine = 62
; Folding = --
; EnableThread
; UseIcon = ..\OTS\ots.ico
; Executable = ots_iisapi_filter.dll
; DisableDebugger
; HideErrorLog
; CurrentDirectory = \
; CompileSourceDirectory
; Compiler = PureBasic 5.46 LTS (Windows - x64)
; EnableCompileCount = 5
; EnableBuildCount = 5
; EnableExeConstant
Code: Select all
; *************************************************************
; * Module Name: httpFilt_ascii.pbi
; *
; * Abstract : This module contains the Microsoft HTTP Ascii Filter header for PureBasic
; *************************************************************
; *************************************************************
; *************************************************************/
; * Manifest Constants
; *************************************************************/
#HSE_VERSION_MAJOR = 10; // major version of this spec
#HSE_VERSION_MINOR = 0; // minor version of this spec
#HTTP_FILTER_REVISION = #HSE_VERSION_MINOR | ( #HSE_VERSION_MAJOR << 16 )
#SF_MAX_USERNAME = 256 + 1
#SF_MAX_PASSWORD = 256 + 1
#SF_MAX_AUTH_TYPE = 32 + 1
#SF_MAX_FILTER_DESC_LEN = 256 + 1
; // These values can be used with the pfnSFCallback function supplied in the filter context Structure
; // Sends a complete HTTP server response header including the status, server version, message time and MIME version.
; // Server extensions should append other information at the end, such as Content-type, Content-length etc followed by an extra '\r\n'.
; // pData - Zero terminated string pointing to optional status string (i.e., "401 Access Denied") or NULL for the default response of "200 OK".
; // ul1 - Zero terminated string pointing to optional data to be appended and set with the header. If NULL, the header will be terminated with an empty line.
#SF_REQ_SEND_RESPONSE_HEADER = 0
; // If the server denies the HTTP request, add the specified headers to the server error response.
; // This allows an authentication filter to advertise its services w/o filtering every request. Generally the headers will be
; // WWW-Authenticate headers with custom authentication schemes but no restriction is placed on what headers may be specified.
; // pData - Zero terminated string pointing to one or more header lines with terminating '\r\n'.
#SF_REQ_ADD_HEADERS_ON_DENIAL = #SF_REQ_SEND_RESPONSE_HEADER + 1
; // Only used by raw data filters that return SF_STATUS_READ_NEXT
; // ul1 - size in bytes for the next read
#SF_REQ_SET_NEXT_READ_SIZE = #SF_REQ_SEND_RESPONSE_HEADER + 2
; // Used to indicate this request is a proxy request
; // ul1 - The proxy flags to set
; // 0x00000001 - This is a HTTP proxy request
#SF_REQ_SET_PROXY_INFO = #SF_REQ_SEND_RESPONSE_HEADER + 3
; // Returns the connection ID contained in the ConnID field of an ISAPI Application's Extension Control Block.
; // This value can be used as a key to cooridinate shared data between Filters and Applications.
; // pData - Pointer to DWORD that receives the connection ID.
#SF_REQ_GET_CONNID = #SF_REQ_SEND_RESPONSE_HEADER + 4
; // Used to set a SSPI security context + impersonation token derived from a client certificate.
; // pData - certificate info ( PHTTP_FILTER_CERTIFICATE_INFO )
; // ul1 - CtxtHandle*
; // ul2 - impersonation handle
#SF_REQ_SET_CERTIFICATE_INFO = #SF_REQ_SEND_RESPONSE_HEADER + 5
; // Used to get an IIS property as defined in SF_PROPERTY_IIS
; // ul1 - Property ID
#SF_REQ_GET_PROPERTY = #SF_REQ_SEND_RESPONSE_HEADER + 6
; // Used to normalize an URL
; // pData - URL to normalize
#SF_REQ_NORMALIZE_URL = #SF_REQ_SEND_RESPONSE_HEADER + 7
; // Disable Notifications
; // ul1 - notifications to disable
#SF_REQ_DISABLE_NOTIFICATIONS = #SF_REQ_SEND_RESPONSE_HEADER + 8
; //////////////////////////////////////////////////////////////////////////////////////////////////////////////
#SF_PROPERTY_SSL_CTXT = 0
#SF_PROPERTY_INSTANCE_NUM_ID = #SF_PROPERTY_SSL_CTXT + 1
; //////////////////////////////////////////////////////////////////////////////////////////////////////////////
; // These values are returned by the filter entry point when a new request is received indicating their interest in this particular request.
; // The filter has handled the HTTP request. The server should disconnect the session.
#SF_STATUS_REQ_FINISHED = $8000000
; // Same as SF_STATUS_FINISHED except the server should keep the TCP session open if the option was negotiated.
#SF_STATUS_REQ_FINISHED_KEEP_CONN = #SF_STATUS_REQ_FINISHED + 1
; // The next filter in the notification chain should be called.
#SF_STATUS_REQ_NEXT_NOTIFICATION = #SF_STATUS_REQ_FINISHED + 2
; // This filter handled the notification. No other handles should be called for this particular notification type.
#SF_STATUS_REQ_HANDLED_NOTIFICATION = #SF_STATUS_REQ_FINISHED + 3
; // An error occurred. The server should use GetLastError() and indicate the error to the client.
#SF_STATUS_REQ_ERROR = #SF_STATUS_REQ_FINISHED + 4
; // The filter is an opaque stream filter and we're negotiating the session parameters. Only valid for raw read notification.
#SF_STATUS_REQ_READ_NEXT = #SF_STATUS_REQ_FINISHED + 5
; //////////////////////////////////////////////////////////////////////////////////////////////////////////////
; // Bitfield indicating the requested resource has been denied by the server due to a logon failure, an ACL on a resource, an ISAPI Filter or an
; // ISAPI Application/CGI Application.
; // SF_DENIED_BY_CONFIG can appear with SF_DENIED_LOGON if the server configuration did not allow the user to logon.
#SF_DENIED_LOGON = $00000001
#SF_DENIED_RESOURCE = $00000002
#SF_DENIED_FILTER = $00000004
#SF_DENIED_APPLICATION = $00000008
#SF_DENIED_BY_CONFIG = $00010000
Prototype GetServerVariable(*pfc, *lpszVariableName, *lpvBuffer, *lpdwSize)
Prototype AddResponseHeaders(*pfc, *lpszHeaders, dwReserved.l)
Prototype WriteClient(*pfc, *lpvBuffer, *lpdwBytes, dwReserved.l)
Prototype AllocMem(*pfc, cbSize.l, dwReserved.l)
Prototype ServerSupportFunction(*pfc, sfReq.i, *pData, *ul1, *ul2)
; // see https://msdn.microsoft.com/en-us/library/aa383751(VS.85).aspx for variable types
; // bool = .l
; // int = .i
; // pointer = .i
; // byte = .c
; // dword = .l
; // dword32 = .l
; // dwordlong = .i
; // dword64 = .i
; // float = .f
; // pvNotification points to this structure for all request notification types
Structure HTTP_FILTER_CONTEXT Align #PB_Structure_AlignC
cbSize.l; // Size of this structure.
Revision.l; // Version info of this spec.
*ServerContext; // Reserved for server use.
ulReserved.l; // Reserved For server use.
fIsSecurePort.l; // A value of TRUE indicates that this event is over a secure port. A value of FALSE indicates that the event is not over a secure port.
*pFilterContext; // Points to any context information that the filter wants to associate with this request.
GetServerVariable.GetServerVariable; // Function call.
AddResponseHeaders.AddResponseHeaders; // Function call.
WriteClient.WriteClient; // Function call.
AllocMem.AllocMem; // Function call.
ServerSupportFunction.ServerSupportFunction; // Function call.
EndStructure
; // This Structure is the notification info For the Read And send raw Data notification types
Structure HTTP_FILTER_RAW_DATA Align #PB_Structure_AlignC
*pvInData; // Points to the data buffer.
cbInData.l; // Number of valid data bytes.
cbInBuffer.l; // Total size of buffer.
dwReserved.l; // Reserved for future use.
EndStructure
; // Retrieves the specified header value. Header names should include the trailing ':'. The special values
; // 'method', 'url' and 'version' can be used to retrieve the individual portions of the request line.
Prototype GetHeader(*pfc.HTTP_FILTER_CONTEXT, *lpszName, *lpvBuffer, *lpdwSize)
; // Replaces this header value to the specified value. To delete a header, specified a value of '\0'.
Prototype SetHeader(*pfc.HTTP_FILTER_CONTEXT, *lpszName, *lpszValue)
; // Adds the specified header and value.
Prototype AddHeader(*pfc.HTTP_FILTER_CONTEXT, *lpszName, *lpszValue)
; // This structure is the notification info for when the server is about to process the client headers.
Structure HTTP_FILTER_PREPROC_HEADERS Align #PB_Structure_AlignC
GetHeader.GetHeader; // Get header function call.
SetHeader.SetHeader; // Set header function call.
AddHeader.AddHeader; // Add header function call.
HttpStatus.l; // Status for SEND_RESPONSE.
dwReserved.l; // Reserved for future use.
EndStructure
; // Authentication information for this request.
Structure HTTP_FILTER_AUTHENT Align #PB_Structure_AlignC
pszUser.a; // String for username and password, empty strings for the anonymous user.
cbUserBuff.l; // The size of the buffer pointed to by pszUser. This is guaranteed to be at least SF_MAX_USERNAME.
pszPassword.a; // String containing the password for this request.
cbPasswordBuff.l; // The size of the buffer pointed to by pszPassword. This is guaranteed to be at least SF_MAX_PASSWORD.
EndStructure
; // Indicates the server is going to use the specific physical mapping for the specified URL. Filters can modify the physical path in place.
Structure HTTP_FILTER_URL_MAP Align #PB_Structure_AlignC
pszURL.a; // String for the URL that is being mapped to a physical path.
pszPhysicalPath.a; // String for the buffer where the physical path is stored.
cbPathBuff.l; // The size of the buffer pointed to by pszPhysicalPath.
EndStructure
; // Indicates the server is going to use the specific physical mapping for the specified URL. Filters can modify the physical path in place.
; // Additional members beyond those from HTTP_FILTER_URL_MAP are informational.
Structure HTTP_FILTER_URL_MAP_EX Align #PB_Structure_AlignC
pszURL.a; // String for the URL that is being mapped to a physical path.
pszPhysicalPath.a; // String for the buffer where the physical path is stored.
cbPathBuff.l; // The size of the buffer pointed to by pszPhysicalPath.
dwFlags.l
cchMatchingPath.l
cchMatchingURL.l
pszScriptMapEntry.a
EndStructure
Structure HTTP_FILTER_ACCESS_DENIED Align #PB_Structure_AlignC
pszURL.a; // String for the URL that is being mapped to a physical path.
pszPhysicalPath.a; // String for the buffer where the physical path is stored.
dwReason.l; // Bitfield of SF_DENIED flags due to a logon failure, an ACL on a resource, an ISAPI Filter or an ISAPI Application/CGI Application.
EndStructure
; // The log information about to be written to the server log file. The string pointers can be replaced but the memory must remain valid until
; // the next notification
Structure HTTP_FILTER_LOG Align #PB_Structure_AlignC
pszClientHostName.a; // String for the client's host name.
pszClientUserName.a; // String for the client's user name.
pszServerName.a; // String for the server name.
pszOperation.a; // String for the HTTP operation type.
pszTarget.a; // String for the target of the HTTP command.
pszParameters.a; // String for the parameters passed to the HTTP command.
dwHttpStatus.l; // The HTTP return status.
dwWin32Status.l; // The Win32 error code.
dwBytesSent.l; // The number of bytes sent from the server to the client.
dwBytesRecvd.l; // The number of bytes received by the server from the client.
msTimeForProcessing.l; // The time in milliseconds required to process the client request.
EndStructure
; // Called once the client request has been authenticated.
Prototype GetUserToken(*pfc.HTTP_FILTER_CONTEXT, phToken.i)
Structure HTTP_FILTER_AUTH_COMPLETE_INFO Align #PB_Structure_AlignC
GetHeader.GetHeader; // Get header function call.
SetHeader.SetHeader; // Set header function call.
AddHeader.AddHeader; // Add header function call.
GetUserToken.GetUserToken; // Get user token function call.
HttpStatus.l; // Status for SEND_RESPONSE.
fResetAuth.l; // Boolean reserved for future use.
dwReserved.l; // Reserved for future use.
EndStructure
; // Notification Flags
; //
; // SF_NOTIFY_SECURE_PORT
; // SF_NOTIFY_NONSECURE_PORT
; //
; // Indicates whether the application wants to be notified for transactions that are happenning on the server port(s) that support data encryption
; // (such as PCT and SSL), on only the non-secure port(s) or both.
; //
; // SF_NOTIFY_READ_RAW_DATA
; //
; // Applications are notified after the server reads a block of memory from the client but before the server does any processing on the
; // block. The data block may contain HTTP headers and entity data.
#SF_NOTIFY_SECURE_PORT = $00000001
#SF_NOTIFY_NONSECURE_PORT = $00000002
#SF_NOTIFY_PREPROC_HEADERS = $00004000
#SF_NOTIFY_AUTHENTICATION = $00002000
#SF_NOTIFY_URL_MAP = $00001000
#SF_NOTIFY_ACCESS_DENIED = $00000800
#SF_NOTIFY_SEND_RESPONSE = $00000040
#SF_NOTIFY_SEND_RAW_DATA = $00000400
#SF_NOTIFY_LOG = $00000200
#SF_NOTIFY_END_OF_REQUEST = $00000080
#SF_NOTIFY_END_OF_NET_SESSION = $00000100
#SF_NOTIFY_AUTH_COMPLETE = $04000000
; // Filter ordering flags
; //
; // Filters will tend to be notified by their specified ordering. For ties, notification order is determined by load order.
; //
; // SF_NOTIFY_ORDER_HIGH - Authentication or data transformation filters
; // SF_NOTIFY_ORDER_MEDIUM
; // SF_NOTIFY_ORDER_LOW - Logging filters that want the results of any other filters might specify this order.
#SF_NOTIFY_ORDER_HIGH = $00080000
#SF_NOTIFY_ORDER_MEDIUM = $00040000
#SF_NOTIFY_ORDER_LOW = $00020000
#SF_NOTIFY_ORDER_DEFAULT = #SF_NOTIFY_ORDER_LOW
#SF_NOTIFY_ORDER_MASK = #SF_NOTIFY_ORDER_HIGH | #SF_NOTIFY_ORDER_MEDIUM | #SF_NOTIFY_ORDER_LOW
; // Structure passed To GetFilterVersion
Structure HTTP_FILTER_VERSION Align #PB_Structure_AlignC
dwServerFilterVersion.l; // The ISAPI version in use by the server.
dwFilterVersion.l; // The version number of ISAPI used by the ISAPI filter. The version used by your filter can be set by using the HTTP_FILTER_REVISION definition from the httpfilt.h header file.
lpszFilterDesc.a[#SF_MAX_FILTER_DESC_LEN]; // String for short description of the ISAPI filter. Length = #SF_MAX_FILTER_DESC_LEN
dwFlags.l; // Contains flags that indicate for which notification event types the filter should be notified, and what the filter's priority is. The following table lists the valid bitmasks.
EndStructure
CompilerIf #PB_Compiler_Thread = 0
CompilerError "ISAPI Filters must be compiled with threadsafe enabled!"
CompilerEndIf
CompilerIf #PB_Compiler_Unicode = 1
CompilerWarning "Must be compiled without Unicode!!!"
CompilerEndIf
ots_iisapi_filter_unicode.pb
Code: Select all
; ------------------------------------------------------------
; Program name: ots_iisapi_filter_unicode.pb
; Written by: Rich Algeni, Jr.
; Date written: 09/11/2015
;
; Purpose: 64 bit Internet Information Server Unicode Filter API Dll
; ------------------------------------------------------------
EnableExplicit
XIncludeFile "D:\development\Source Code Repository For Rich Algeni\PureBasic\iis_api\httpFilt_unicode.pbi"
; ************************************************************************************
; initialization procedure
; ************************************************************************************
ProcedureDLL.i AttachProcess(instance.i)
Protected logText.s = "ots_iisapi_filter AttachProcess() Unicode version completed successfully"
OutputDebugString_(logText)
ProcedureReturn #True
EndProcedure
; ************************************************************************************
; DetachProcess
; ************************************************************************************
ProcedureDLL.i DetachProcess(instance.i)
EndProcedure
; ************************************************************************************
; AttachThread
; ************************************************************************************
ProcedureDLL.i AttachThread(instance.i)
EndProcedure
; ************************************************************************************
; DetachThread
; ************************************************************************************
ProcedureDLL.i DetachThread(instance.i)
EndProcedure
; ************************************************************************************
; GetFilterVersion is called when the dll is loaded
; ************************************************************************************
ProcedureDLL.i GetFilterVersion(*pVer.HTTP_FILTER_VERSION)
Protected logText.s = "ots_iisapi_filter GetFilterVersion()"
Protected descriptionSize.l
Protected notificationMask.l
Protected description.s = "ISAPI Unicode Filter written in PureBasic"
Protected descripSize.l = Len(description)
notificationMask = #SF_NOTIFY_SECURE_PORT |
#SF_NOTIFY_NONSECURE_PORT |
#SF_NOTIFY_PREPROC_HEADERS |
#SF_NOTIFY_AUTHENTICATION |
#SF_NOTIFY_URL_MAP |
#SF_NOTIFY_ACCESS_DENIED |
#SF_NOTIFY_SEND_RESPONSE |
#SF_NOTIFY_SEND_RAW_DATA |
#SF_NOTIFY_LOG |
#SF_NOTIFY_END_OF_REQUEST |
#SF_NOTIFY_END_OF_NET_SESSION |
#SF_NOTIFY_AUTH_COMPLETE
descriptionSize = StringByteLength(description, #PB_UTF8)
; make the length of the description the same number of characters as #SF_MAX_FILTER_DESC_LEN
PokeL(@*pVer\dwFilterVersion, #HTTP_FILTER_REVISION)
PokeS(@*pVer\lpszFilterDesc, description, descriptionSize, #PB_UTF8)
PokeL(@*pVer\dwFlags, notificationMask)
logText + ", ISAPI Server Version: 0x" + RSet(Hex(*pVer\dwServerFilterVersion, #PB_Long), 8, "0")
logText + ", ISAPI Client Version: 0x" + RSet(Hex(*pVer\dwFilterVersion, #PB_Long), 8, "0")
logText + ", notifications requested: 0x" + RSet(Hex(notificationMask, #PB_Long), 8, "0")
OutputDebugString_(logText)
; return true, returning false will cause the dll to be unloaded
ProcedureReturn #True
EndProcedure
; ************************************************************************************
; This is the main function that is called for each client request pECB contains all needed data
; ************************************************************************************
ProcedureDLL.i HttpFilterProc(*pfc.HTTP_FILTER_CONTEXT, notificationType.l, *pvNotification)
Protected logText.s = "ots_iisapi_filter HttpFilterProc() > notificationType = " + Str(notificationType)
OutputDebugString_(logText)
; return get next notification
ProcedureReturn #SF_STATUS_REQ_NEXT_NOTIFICATION
EndProcedure
; ************************************************************************************
; TerminateFilter is called before unloading the dll.
; ************************************************************************************
ProcedureDLL.i TerminateFilter(dwFlags.l)
Protected logText.s = "ots_iisapi_filter TerminateFilter() > process terminating"
OutputDebugString_(logText)
; return true
ProcedureReturn #True
EndProcedure
; IDE Options = PureBasic 5.72 (Windows - x64)
; ExecutableFormat = Shared dll
; CursorPosition = 96
; FirstLine = 62
; Folding = --
; EnableThread
; UseIcon = ..\OTS\ots.ico
; Executable = ots_iisapi_filter.dll
; DisableDebugger
; HideErrorLog
; CurrentDirectory = \
; CompileSourceDirectory
; EnableCompileCount = 5
; EnableBuildCount = 5
; EnableExeConstant
Code: Select all
; *************************************************************
; * Module Name: httpFilt_unicode.pbi
; *
; * Abstract : This module contains the Microsoft HTTP Unicode Filter header for PureBasic
; *************************************************************
; *************************************************************
; *************************************************************/
; * Manifest Constants
; *************************************************************/
#HSE_VERSION_MAJOR = 10; // major version of this spec
#HSE_VERSION_MINOR = 0; // minor version of this spec
#HTTP_FILTER_REVISION = #HSE_VERSION_MINOR | ( #HSE_VERSION_MAJOR << 16 )
#SF_MAX_USERNAME = 256 + 1
#SF_MAX_PASSWORD = 256 + 1
#SF_MAX_AUTH_TYPE = 32 + 1
#SF_MAX_FILTER_DESC_LEN = 256 + 1
; // These values can be used with the pfnSFCallback function supplied in the filter context Structure
; // Sends a complete HTTP server response header including the status, server version, message time and MIME version.
; // Server extensions should append other information at the end, such as Content-type, Content-length etc followed by an extra '\r\n'.
; // pData - Zero terminated string pointing to optional status string (i.e., "401 Access Denied") or NULL for the default response of "200 OK".
; // ul1 - Zero terminated string pointing to optional data to be appended and set with the header. If NULL, the header will be terminated with an empty line.
#SF_REQ_SEND_RESPONSE_HEADER = 0
; // If the server denies the HTTP request, add the specified headers to the server error response.
; // This allows an authentication filter to advertise its services w/o filtering every request. Generally the headers will be
; // WWW-Authenticate headers with custom authentication schemes but no restriction is placed on what headers may be specified.
; // pData - Zero terminated string pointing to one or more header lines with terminating '\r\n'.
#SF_REQ_ADD_HEADERS_ON_DENIAL = #SF_REQ_SEND_RESPONSE_HEADER + 1
; // Only used by raw data filters that return SF_STATUS_READ_NEXT
; // ul1 - size in bytes for the next read
#SF_REQ_SET_NEXT_READ_SIZE = #SF_REQ_SEND_RESPONSE_HEADER + 2
; // Used to indicate this request is a proxy request
; // ul1 - The proxy flags to set
; // 0x00000001 - This is a HTTP proxy request
#SF_REQ_SET_PROXY_INFO = #SF_REQ_SEND_RESPONSE_HEADER + 3
; // Returns the connection ID contained in the ConnID field of an ISAPI Application's Extension Control Block.
; // This value can be used as a key to cooridinate shared data between Filters and Applications.
; // pData - Pointer to DWORD that receives the connection ID.
#SF_REQ_GET_CONNID = #SF_REQ_SEND_RESPONSE_HEADER + 4
; // Used to set a SSPI security context + impersonation token derived from a client certificate.
; // pData - certificate info ( PHTTP_FILTER_CERTIFICATE_INFO )
; // ul1 - CtxtHandle*
; // ul2 - impersonation handle
#SF_REQ_SET_CERTIFICATE_INFO = #SF_REQ_SEND_RESPONSE_HEADER + 5
; // Used to get an IIS property as defined in SF_PROPERTY_IIS
; // ul1 - Property ID
#SF_REQ_GET_PROPERTY = #SF_REQ_SEND_RESPONSE_HEADER + 6
; // Used to normalize an URL
; // pData - URL to normalize
#SF_REQ_NORMALIZE_URL = #SF_REQ_SEND_RESPONSE_HEADER + 7
; // Disable Notifications
; // ul1 - notifications to disable
#SF_REQ_DISABLE_NOTIFICATIONS = #SF_REQ_SEND_RESPONSE_HEADER + 8
; //////////////////////////////////////////////////////////////////////////////////////////////////////////////
#SF_PROPERTY_SSL_CTXT = 0
#SF_PROPERTY_INSTANCE_NUM_ID = #SF_PROPERTY_SSL_CTXT + 1
; //////////////////////////////////////////////////////////////////////////////////////////////////////////////
; // These values are returned by the filter entry point when a new request is received indicating their interest in this particular request.
; // The filter has handled the HTTP request. The server should disconnect the session.
#SF_STATUS_REQ_FINISHED = $8000000
; // Same as SF_STATUS_FINISHED except the server should keep the TCP session open if the option was negotiated.
#SF_STATUS_REQ_FINISHED_KEEP_CONN = #SF_STATUS_REQ_FINISHED + 1
; // The next filter in the notification chain should be called.
#SF_STATUS_REQ_NEXT_NOTIFICATION = #SF_STATUS_REQ_FINISHED + 2
; // This filter handled the notification. No other handles should be called for this particular notification type.
#SF_STATUS_REQ_HANDLED_NOTIFICATION = #SF_STATUS_REQ_FINISHED + 3
; // An error occurred. The server should use GetLastError() and indicate the error to the client.
#SF_STATUS_REQ_ERROR = #SF_STATUS_REQ_FINISHED + 4
; // The filter is an opaque stream filter and we're negotiating the session parameters. Only valid for raw read notification.
#SF_STATUS_REQ_READ_NEXT = #SF_STATUS_REQ_FINISHED + 5
; //////////////////////////////////////////////////////////////////////////////////////////////////////////////
; // Bitfield indicating the requested resource has been denied by the server due to a logon failure, an ACL on a resource, an ISAPI Filter or an
; // ISAPI Application/CGI Application.
; // SF_DENIED_BY_CONFIG can appear with SF_DENIED_LOGON if the server configuration did not allow the user to logon.
#SF_DENIED_LOGON = $00000001
#SF_DENIED_RESOURCE = $00000002
#SF_DENIED_FILTER = $00000004
#SF_DENIED_APPLICATION = $00000008
#SF_DENIED_BY_CONFIG = $00010000
Prototype GetServerVariable(*pfc, *lpszVariableName, *lpvBuffer, *lpdwSize)
Prototype AddResponseHeaders(*pfc, *lpszHeaders, dwReserved.l)
Prototype WriteClient(*pfc, *lpvBuffer, *lpdwBytes, dwReserved.l)
Prototype AllocMem(*pfc, cbSize.l, dwReserved.l)
Prototype ServerSupportFunction(*pfc, sfReq.i, *pData, *ul1, *ul2)
; // see https://msdn.microsoft.com/en-us/library/aa383751(VS.85).aspx for variable types
; // bool = .l
; // int = .i
; // pointer = .i
; // byte = .c
; // dword = .l
; // dword32 = .l
; // dwordlong = .i
; // dword64 = .i
; // float = .f
; // pvNotification points to this structure for all request notification types
Structure HTTP_FILTER_CONTEXT Align #PB_Structure_AlignC
cbSize.l; // Size of this structure.
Revision.l; // Version info of this spec.
*ServerContext; // Reserved for server use.
ulReserved.l; // Reserved For server use.
fIsSecurePort.l; // A value of TRUE indicates that this event is over a secure port. A value of FALSE indicates that the event is not over a secure port.
*pFilterContext; // Points to any context information that the filter wants to associate with this request.
GetServerVariable.GetServerVariable; // Function call.
AddResponseHeaders.AddResponseHeaders; // Function call.
WriteClient.WriteClient; // Function call.
AllocMem.AllocMem; // Function call.
ServerSupportFunction.ServerSupportFunction; // Function call.
EndStructure
; // This Structure is the notification info For the Read And send raw Data notification types
Structure HTTP_FILTER_RAW_DATA Align #PB_Structure_AlignC
*pvInData; // Points to the data buffer.
cbInData.l; // Number of valid data bytes.
cbInBuffer.l; // Total size of buffer.
dwReserved.l; // Reserved for future use.
EndStructure
; // Retrieves the specified header value. Header names should include the trailing ':'. The special values
; // 'method', 'url' and 'version' can be used to retrieve the individual portions of the request line.
Prototype GetHeader(*pfc.HTTP_FILTER_CONTEXT, *lpszName, *lpvBuffer, *lpdwSize)
; // Replaces this header value to the specified value. To delete a header, specified a value of '\0'.
Prototype SetHeader(*pfc.HTTP_FILTER_CONTEXT, *lpszName, *lpszValue)
; // Adds the specified header and value.
Prototype AddHeader(*pfc.HTTP_FILTER_CONTEXT, *lpszName, *lpszValue)
; // This structure is the notification info for when the server is about to process the client headers.
Structure HTTP_FILTER_PREPROC_HEADERS Align #PB_Structure_AlignC
GetHeader.GetHeader; // Get header function call.
SetHeader.SetHeader; // Set header function call.
AddHeader.AddHeader; // Add header function call.
HttpStatus.l; // Status for SEND_RESPONSE.
dwReserved.l; // Reserved for future use.
EndStructure
; // Authentication information for this request.
Structure HTTP_FILTER_AUTHENT Align #PB_Structure_AlignC
pszUser.a; // String for username and password, empty strings for the anonymous user.
cbUserBuff.l; // The size of the buffer pointed to by pszUser. This is guaranteed to be at least SF_MAX_USERNAME.
pszPassword.a; // String containing the password for this request.
cbPasswordBuff.l; // The size of the buffer pointed to by pszPassword. This is guaranteed to be at least SF_MAX_PASSWORD.
EndStructure
; // Indicates the server is going to use the specific physical mapping for the specified URL. Filters can modify the physical path in place.
Structure HTTP_FILTER_URL_MAP Align #PB_Structure_AlignC
pszURL.a; // String for the URL that is being mapped to a physical path.
pszPhysicalPath.a; // String for the buffer where the physical path is stored.
cbPathBuff.l; // The size of the buffer pointed to by pszPhysicalPath.
EndStructure
; // Indicates the server is going to use the specific physical mapping for the specified URL. Filters can modify the physical path in place.
; // Additional members beyond those from HTTP_FILTER_URL_MAP are informational.
Structure HTTP_FILTER_URL_MAP_EX Align #PB_Structure_AlignC
pszURL.a; // String for the URL that is being mapped to a physical path.
pszPhysicalPath.a; // String for the buffer where the physical path is stored.
cbPathBuff.l; // The size of the buffer pointed to by pszPhysicalPath.
dwFlags.l
cchMatchingPath.l
cchMatchingURL.l
pszScriptMapEntry.a
EndStructure
Structure HTTP_FILTER_ACCESS_DENIED Align #PB_Structure_AlignC
pszURL.a; // String for the URL that is being mapped to a physical path.
pszPhysicalPath.a; // String for the buffer where the physical path is stored.
dwReason.l; // Bitfield of SF_DENIED flags due to a logon failure, an ACL on a resource, an ISAPI Filter or an ISAPI Application/CGI Application.
EndStructure
; // The log information about to be written to the server log file. The string pointers can be replaced but the memory must remain valid until
; // the next notification
Structure HTTP_FILTER_LOG Align #PB_Structure_AlignC
pszClientHostName.a; // String for the client's host name.
pszClientUserName.a; // String for the client's user name.
pszServerName.a; // String for the server name.
pszOperation.a; // String for the HTTP operation type.
pszTarget.a; // String for the target of the HTTP command.
pszParameters.a; // String for the parameters passed to the HTTP command.
dwHttpStatus.l; // The HTTP return status.
dwWin32Status.l; // The Win32 error code.
dwBytesSent.l; // The number of bytes sent from the server to the client.
dwBytesRecvd.l; // The number of bytes received by the server from the client.
msTimeForProcessing.l; // The time in milliseconds required to process the client request.
EndStructure
; // Called once the client request has been authenticated.
Prototype GetUserToken(*pfc.HTTP_FILTER_CONTEXT, phToken.i)
Structure HTTP_FILTER_AUTH_COMPLETE_INFO Align #PB_Structure_AlignC
GetHeader.GetHeader; // Get header function call.
SetHeader.SetHeader; // Set header function call.
AddHeader.AddHeader; // Add header function call.
GetUserToken.GetUserToken; // Get user token function call.
HttpStatus.l; // Status for SEND_RESPONSE.
fResetAuth.l; // Boolean reserved for future use.
dwReserved.l; // Reserved for future use.
EndStructure
; // Notification Flags
; //
; // SF_NOTIFY_SECURE_PORT
; // SF_NOTIFY_NONSECURE_PORT
; //
; // Indicates whether the application wants to be notified for transactions that are happenning on the server port(s) that support data encryption
; // (such as PCT and SSL), on only the non-secure port(s) or both.
; //
; // SF_NOTIFY_READ_RAW_DATA
; //
; // Applications are notified after the server reads a block of memory from the client but before the server does any processing on the
; // block. The data block may contain HTTP headers and entity data.
#SF_NOTIFY_SECURE_PORT = $00000001
#SF_NOTIFY_NONSECURE_PORT = $00000002
#SF_NOTIFY_PREPROC_HEADERS = $00004000
#SF_NOTIFY_AUTHENTICATION = $00002000
#SF_NOTIFY_URL_MAP = $00001000
#SF_NOTIFY_ACCESS_DENIED = $00000800
#SF_NOTIFY_SEND_RESPONSE = $00000040
#SF_NOTIFY_SEND_RAW_DATA = $00000400
#SF_NOTIFY_LOG = $00000200
#SF_NOTIFY_END_OF_REQUEST = $00000080
#SF_NOTIFY_END_OF_NET_SESSION = $00000100
#SF_NOTIFY_AUTH_COMPLETE = $04000000
; // Filter ordering flags
; //
; // Filters will tend to be notified by their specified ordering. For ties, notification order is determined by load order.
; //
; // SF_NOTIFY_ORDER_HIGH - Authentication or data transformation filters
; // SF_NOTIFY_ORDER_MEDIUM
; // SF_NOTIFY_ORDER_LOW - Logging filters that want the results of any other filters might specify this order.
#SF_NOTIFY_ORDER_HIGH = $00080000
#SF_NOTIFY_ORDER_MEDIUM = $00040000
#SF_NOTIFY_ORDER_LOW = $00020000
#SF_NOTIFY_ORDER_DEFAULT = #SF_NOTIFY_ORDER_LOW
#SF_NOTIFY_ORDER_MASK = #SF_NOTIFY_ORDER_HIGH | #SF_NOTIFY_ORDER_MEDIUM | #SF_NOTIFY_ORDER_LOW
; // Structure passed To GetFilterVersion
Structure HTTP_FILTER_VERSION Align #PB_Structure_AlignC
dwServerFilterVersion.l; // The ISAPI version in use by the server.
dwFilterVersion.l; // The version number of ISAPI used by the ISAPI filter. The version used by your filter can be set by using the HTTP_FILTER_REVISION definition from the httpfilt.h header file.
lpszFilterDesc.a[#SF_MAX_FILTER_DESC_LEN]; // String for short description of the ISAPI filter. Length = #SF_MAX_FILTER_DESC_LEN
dwFlags.l; // Contains flags that indicate for which notification event types the filter should be notified, and what the filter's priority is. The following table lists the valid bitmasks.
EndStructure
CompilerIf #PB_Compiler_Thread = 0
CompilerError "ISAPI Filters must be compiled with threadsafe enabled!"
CompilerEndIf
CompilerIf #PB_Compiler_Unicode = 0
CompilerWarning "Must be compiled in Unicode!!!"
CompilerEndIf
The BEST news: This now works! It takes a bit to go through all of the notifications I loaded, so that will be the next item I work on. Cutting it down to do just what I need.
I am using the OS call OutputDebugString_() to send data to Sysinternals debugview process. Remember to click on 'Capture Global Win32.'
Rich