Here is my barebones program, only enough code to do the minimum needed to run:
Code: Select all
EnableExplicit
#PROGRAM_NAME = "ots_isapi_filter.dll"
#PROGRAM_VERSION = "1.0.01a." + #PB_Editor_BuildCount
#HSE_VERSION_MAJOR = 7; // 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 are returned by the filter entry point when a new request is received indicating their interest in this particular request
#SF_STATUS_REQ_FINISHED = $8000000
#SF_STATUS_REQ_NEXT_NOTIFICATION = #SF_STATUS_REQ_FINISHED + 2
Prototype GetServerVariable(hConnID.i, lpszVariableName.i, lpvBuffer.i, lpdwSize.l)
Prototype AddResponseHeaders(hConnID.i, lpszHeaders.i, dwReserved.l)
Prototype WriteClient(hConnID.i, lpvBuffer.i, lpdwBytes.i, dwReserved.l)
Prototype AllocMem(hConnID.i, cbSize.l, dwReserved.l)
Prototype ServerSupportFunction(hConnID.i, sfReq.i, pData.i, ul1.i, ul2.i)
; // pvNotification points to this structure for all request notification types
Structure HTTP_FILTER_CONTEXT
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 when the server is about to process the client headers
Prototype GetHeader(*pfc.HTTP_FILTER_CONTEXT, lpszName.s, lpvBuffer.i, lpdwSize.l)
; // Replaces this header value to the specified value. To delete a header, specified a value of '\0'.
Prototype SetHeader(*pfc.HTTP_FILTER_CONTEXT, lpszName.s, lpszValue.s)
; // Adds the specified header and value
Prototype AddHeader(*pfc.HTTP_FILTER_CONTEXT, lpszName.s, lpszValue.s)
Structure HTTP_FILTER_PREPROC_HEADERS
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
#SF_NOTIFY_SECURE_PORT = $00000001
#SF_NOTIFY_NONSECURE_PORT = $00000002
#SF_NOTIFY_SEND_RESPONSE = $00000040
#SF_NOTIFY_PREPROC_HEADERS = $00004000
#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
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
; ************************************************************************************
; initialization procedure
; ************************************************************************************
ProcedureDLL.i AttachProcess(instance.i)
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.l GetFilterVersion(*pVer.HTTP_FILTER_VERSION)
Protected logText.s
Protected notifyVersion.l
Protected description.s = "ISAPI Filter written in PureBasic"
Protected descriptionSize.i = StringByteLength(description, #PB_UTF8)
Protected netSource.s = #PROGRAM_NAME + ", version " + #PROGRAM_VERSION + ", GetFilterVersion() > "
Protected notifyFlags.l = #SF_NOTIFY_SEND_RESPONSE | #SF_NOTIFY_ORDER_DEFAULT | #SF_NOTIFY_PREPROC_HEADERS
notifyVersion = #HTTP_FILTER_REVISION
If notifyVersion > *pVer\dwServerFilterVersion
notifyVersion = *pVer\dwServerFilterVersion
EndIf
*pVer\dwFilterVersion = notifyVersion
PokeS(@*pVer\lpszFilterDesc, description, descriptionSize, #PB_UTF8)
*pVer\dwFlags = notifyFlags
logText = netSource + "ISAPI Version: 0x" + RSet(Hex(*pVer\dwServerFilterVersion, #PB_Long), 8, "0")
logText + ", program version: 0x" + RSet(Hex(notifyVersion), 8, "0")
logText + ", notifications requested: 0x" + RSet(Hex(notifyFlags, #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.l HttpFilterProc(*pfc.HTTP_FILTER_CONTEXT, notificationType.l, *pvNotification)
OutputDebugString_(#PROGRAM_NAME + ", version " + #PROGRAM_VERSION + ", HttpFilterProc() called by " + Str(notificationType))
ProcedureReturn #SF_STATUS_REQ_NEXT_NOTIFICATION
EndProcedure
; ************************************************************************************
; TerminateFilter is called before unloading the dll.
; ************************************************************************************
ProcedureDLL.l TerminateFilter(dwFlags)
OutputDebugString_(#PROGRAM_NAME + ", version " + #PROGRAM_VERSION + ", TerminateFilter() called")
ProcedureReturn #True
EndProcedure
; IDE Options = PureBasic 5.70 LTS (Windows - x64)
; ExecutableFormat = Shared dll
; CursorPosition = 115
; FirstLine = 105
; EnableThread
; Executable = ots_iisapi_filter.dll
; DisableDebugger
; HideErrorLog
; DisableCompileCount = 2
; EnableBuildCount = 8
; EnableExeConstant
Code: Select all
[14268] ots_isapi_filter.dll, version 1.0.01a.7, GetFilterVersion() > ISAPI Version: 0x000A0000, program version: 0x00070000, notifications requested: 0x00020043