[源码] Sambar Server ISAPI Search extension.
来源:互联网 发布:java 观察者模式 实现 编辑:程序博客网 时间:2024/06/17 15:25
[源码] Sambar Server ISAPI Search extension.
来源(null)
下载源文件: i1830_001search.rar
search.c
/*
** SEARCH
**
** This is a simple ISAPI search DLL that takes a set of words
** to search for in the "query" parameter, and displays all files
** that match the keywords.
**
** Important! The search occurs from the location of the search.dll
** and below. The search.dll will only work properly if placed in
** the root of your documents directory.
**
** Confidential Property of Tod Sambar
** (c) Copyright Tod Sambar 1998
** All rights reserved.
**
**
** History:
** Chg# Date Description Resp
** ---- ------- ------------------------------------------------------- ----
** 20MAR98 Created sambar
*/
#include <windows.h>
#include <httpext.h>
#include <string.h>
#include <stdio.h>
#include <stdarg.h>
/*
** Globals
*/
#define PAGE_END "<P><B>Done.</B>/n</BODY></HTML>/n"
#define INVALID_FORMAT "<B>Invalid search syntax.</B><P><I>search?query=foo&logic=AND</I>"
#define NO_RESULTS "<P><B>No results matching search request.</B>"
#define SEARCH_PG_MAIN "/n/n<center>/n<table cellpadding=/"5/">/n <tr>/n <td>/n<b>Search:</b><br>/n<form METHOD=/"GET/" ACTION=/"search.dll/">/n<input NAME=/"query/" SIZE=/"30/" VALUE MAXLENGTH=/"40/"> /n<input TYPE=/"submit/" value=/"给我搜/"><br>/n<input TYPE=/"radio/" NAME=/"logic/" VALUE=/"or/" CHECKED> <b>OR</b> together terms<br>/n<input TYPE=/"radio/" NAME=/"logic/" VALUE=/"and/"> <b>AND</b> together terms/n</form>/n </td>/n </tr>/n</table>/n</center>/n"
/*
** Local Prototypes
*/
static DWORD search_error(EXTENSION_CONTROL_BLOCK *pECB, CHAR *errorstr);
static void search_find(EXTENSION_CONTROL_BLOCK *pECB,
CHAR *docdir, CHAR *urldir,
CHAR kwords[10][256], int numkwords, int any,
int *nump);
static short search_match(CHAR *filename, CHAR kwords[10][256],
int numkwords, int any);
static void escape_to_ascii(CHAR *buf, int buflen);
static short get_param(CHAR *params, CHAR *arg, CHAR *buf, int buflen);
static short get_next(CHAR *head, CHAR *buffer, CHAR **tailp);
/*
** GetExtensionVersion
**
** ISAPI/Win32 API method to ensure compatibility with the Server.
*/
BOOL WINAPI
GetExtensionVersion(HSE_VERSION_INFO *pVer)
{
pVer->dwExtensionVersion = MAKELONG(HSE_VERSION_MINOR, HSE_VERSION_MAJOR);
lstrcpyn(pVer->lpszExtensionDesc, "Sambar Server ISAPI Search extension.",
HSE_MAX_EXT_DLL_NAME_LEN);
return TRUE;
}
/*
** HttpExtensionProc
**
** Called in response to the client request.
**
** Format:
** search?query="<word1> <word2>... <wordN>"&logic="AND">
** or
** search?query="<word1> <word2>... <wordN>"&logic="OR">
*/
DWORD WINAPI
HttpExtensionProc(EXTENSION_CONTROL_BLOCK *pECB)
{
int any;
int num;
int numkwords;
int found;
DWORD buflen;
CHAR *head;
CHAR *params;
CHAR tmp[256];
CHAR kwords[10][256];
CHAR buffer[2048];
CHAR urldir[512];
/* Get the GET/POST data */
params = NULL;
if (!stricmp(pECB->lpszMethod, "GET"))
{
/* Set the parameters list to the QUERY_STRING data */
params = pECB->lpszQueryString;
}
else /* POST */
{
/* Note: cbTotalBytes = cbAvailable in the Sambar Server */
if(pECB->cbTotalBytes > 0)
params = pECB->lpbData;
}
// if ( params == NULL)
if (*params == '/0')
return (search_error(pECB, SEARCH_PG_MAIN));
// return (search_error(pECB, INVALID_FORMAT));
// return (search_error(pECB, SEARCH_PG_MAIN));
/* Get the "query" and "logic" parameters */
if (!get_param(params, "logic", tmp, 255))
return (search_error(pECB, INVALID_FORMAT));
if (stricmp(tmp, "and"))
any = 1;
else
any = 0;
if (!get_param(params, "query", tmp, 255))
return (search_error(pECB, INVALID_FORMAT));
/* Parse the query into a list. */
head = tmp;
numkwords = 0;
while ((numkwords < 10) && get_next(head, kwords[numkwords], &head))
{
_strupr(kwords[numkwords]);
numkwords++;
}
wsprintf(buffer,
"Content-Type: text/html/r/n"
"/r/n"
"<head><title>Sambar ISAPI Search</title></head>/n"
"<body><h1>Sambar ISAPI Search</h1>/n"
"<hr><P>Keywords: %s</P>/n", tmp);
buflen = lstrlen(buffer);
if (!pECB->ServerSupportFunction(pECB->ConnID, HSE_REQ_SEND_RESPONSE_HEADER,
"200 OK", &buflen, (LPDWORD)buffer))
{
pECB->dwHttpStatusCode = 500;
return HSE_STATUS_ERROR;
}
/*
** Search for the keywords.
*/
num = 0;
/*
** Get the document root to search from.
*/
GetModuleFileName(GetModuleHandle("search.dll"), buffer, 1024);
buflen = strlen(buffer) - strlen("//search.dll");
buffer[buflen] = '/0';
/*
** Get the URL path
*/
buflen = 512;
if (!pECB->GetServerVariable(pECB->ConnID, "URL", urldir, &buflen))
{
buflen = lstrlen(NO_RESULTS);
pECB->WriteClient(pECB->ConnID, NO_RESULTS, &buflen, 0);
pECB->dwHttpStatusCode = 200;
return HSE_STATUS_SUCCESS;
}
/* Strip off to the last "directory" symbol. */
found = 0;
buflen = strlen(urldir);
while ((!found) && (buflen > 0))
{
if ((urldir[buflen - 1] == '/') || (urldir[buflen - 1] == '/'))
found = 1;
buflen--;
}
urldir[buflen] = '/0';
search_find(pECB, buffer, urldir, kwords, numkwords, any, &num);
if (num == 0)
{
buflen = lstrlen(NO_RESULTS);
pECB->WriteClient(pECB->ConnID, NO_RESULTS, &buflen, 0);
}
buflen = lstrlen(PAGE_END);
pECB->WriteClient(pECB->ConnID, PAGE_END, &buflen, 0);
pECB->dwHttpStatusCode = 200;
return HSE_STATUS_SUCCESS;
}
/*
** search_find
**
** Recursively search from the directory in which the search.dll
** is located and below returning files that match the query
** criteria.
*/
static void
search_find(EXTENSION_CONTROL_BLOCK *pECB, CHAR *docdir, CHAR *urldir,
CHAR kwords[10][256], int numkwords, int any, int *nump)
{
DWORD buflen;
HANDLE hFile;
WIN32_FIND_DATA findData;
CHAR buffer[2048];
CHAR newurl[2048];
/*
** Loop through all the files from the root directory.
*/
sprintf(buffer, "%s//*.htm", docdir);
hFile = FindFirstFile(buffer, &findData);
while (hFile != INVALID_HANDLE_VALUE)
{
/* Search file handle... */
sprintf(buffer, "%s//%s", docdir, findData.cFileName);
if (search_match(buffer, kwords, numkwords, any))
{
*nump = *nump + 1;
sprintf(buffer, "<A HREF=/"%s/%s/">%s/%s</A><BR>/n",
urldir, findData.cFileName, urldir, findData.cFileName);
buflen = lstrlen(buffer);
pECB->WriteClient(pECB->ConnID, buffer, &buflen, 0);
}
if (!FindNextFile(hFile, &findData))
break;
}
FindClose(hFile);
sprintf(buffer, "%s//*.html", docdir);
hFile = FindFirstFile(buffer, &findData);
while (hFile != INVALID_HANDLE_VALUE)
{
/* Search file handle... */
sprintf(buffer, "%s//%s", docdir, findData.cFileName);
if (search_match(buffer, kwords, numkwords, any))
{
*nump = *nump + 1;
sprintf(buffer, "<A HREF=/"%s/%s/">%s/%s</A><BR>/n",
urldir, findData.cFileName, urldir, findData.cFileName);
buflen = lstrlen(buffer);
pECB->WriteClient(pECB->ConnID, buffer, &buflen, 0);
}
if (!FindNextFile(hFile, &findData))
break;
}
FindClose(hFile);
sprintf(buffer, "%s//*.txt", docdir);
hFile = FindFirstFile(buffer, &findData);
while (hFile != INVALID_HANDLE_VALUE)
{
/* Search file handle... */
sprintf(buffer, "%s//%s", docdir, findData.cFileName);
if (search_match(buffer, kwords, numkwords, any))
{
*nump = *nump + 1;
sprintf(buffer, "<A HREF=/"%s/%s/">%s/%s</A><BR>/n",
urldir, findData.cFileName, urldir, findData.cFileName);
buflen = lstrlen(buffer);
pECB->WriteClient(pECB->ConnID, buffer, &buflen, 0);
}
if (!FindNextFile(hFile, &findData))
break;
}
FindClose(hFile);
/*
** Recurse the directory(s)
*/
sprintf(buffer, "%s//*.*", docdir);
hFile = FindFirstFile(buffer, &findData);
while (hFile != INVALID_HANDLE_VALUE)
{
if ((findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
(strcmp(findData.cFileName, ".") != 0) &&
(strcmp(findData.cFileName, "..") != 0))
{
sprintf(buffer, "%s//%s", docdir, findData.cFileName);
sprintf(newurl, "%s/%s", urldir, findData.cFileName);
search_find(pECB, buffer, newurl, kwords, numkwords, any, nump);
}
if (!FindNextFile(hFile, &findData))
break;
}
FindClose(hFile);
return;
}
/*
** search_match
**
** Determine if the file matches the search criteria provided.
*/
static short
search_match(CHAR *filename, CHAR kwords[10][256], int numkwords, int any)
{
int i;
int matched;
FILE *hFile;
short match[10];
CHAR buffer[2048];
hFile = fopen(filename, "r");
if (hFile == NULL)
return (0);
matched = 0;
for (i = 0; i < numkwords; i++)
match[i] = 0;
while (fgets(buffer, 2048, hFile) != NULL)
{
_strupr(buffer);
/* Match found? */
for (i = 0; i < numkwords; i++)
{
if (strstr(buffer, kwords[i]) != NULL)
{
if (any)
{
fclose(hFile);
return (1);
}
if (!match[i])
{
match[i] = 1;
matched++;
}
}
}
/* All words matched... */
if (matched == numkwords)
{
fclose(hFile);
return (1);
}
}
fclose(hFile);
return 0;
}
/*
** search_error
**
** Report a failure of the search interface.
*/
static DWORD
search_error(EXTENSION_CONTROL_BLOCK *pECB, CHAR *errorstr)
{
DWORD buflen;
CHAR buffer[2048];
/* Prepare the response header */
wsprintf(buffer,
"Content-Type: text/html/r/n"
"/r/n"
"<head><title>Sambar ISAPI Search</title></head>/n"
"<body><h1>Sambar ISAPI Search Tool</h1>/n"
"<hr><P>%s</P>/n"
"</body></html>/n", errorstr);
buflen = lstrlen(buffer);
if (!pECB->ServerSupportFunction(pECB->ConnID, HSE_REQ_SEND_RESPONSE_HEADER,
"200 OK", &buflen, (LPDWORD)buffer))
{
pECB->dwHttpStatusCode = 500;
return HSE_STATUS_ERROR;
}
pECB->dwHttpStatusCode = 200;
return HSE_STATUS_SUCCESS;
}
/*
**
** Parameter Processing...
**
*/
static CHAR
hex_to_ascii(CHAR *cval)
{
CHAR c;
c = (cval[0] >= 'A' ? ((cval[0] & 0xDF) - 'A') + 10 : (cval[0] - '0'));
c *= 16;
c += (cval[1] >= 'A' ? ((cval[1] & 0xDF) - 'A') + 10 : (cval[1] - '0'));
return c;
}
static void
escape_to_ascii(CHAR *buf, int buflen)
{
int i, j;
for (i = 0, j = 0; j < buflen; ++i, ++j)
{
if ((buf[i] = buf[j]) == '%' )
{
buf[i] = hex_to_ascii(&buf[j+1]);
j+=2;
}
}
buf[i] = '/0';
}
/*
** GET_PARAM
**
*/
static short
get_param(CHAR *params, CHAR *arg, CHAR *buf, int buflen)
{
int i;
int len;
CHAR *head;
CHAR *tail;
/*
** Find the value passed in by the client for some particular
** parameter within the query string.
*/
head = strstr(params, arg);
if (!head)
return (0);
/* Increment past the equals sign... */
head += strlen(arg) + 1;
/* Now determine the length of the value string. */
tail = strchr(head, '&');
if (tail)
len = tail - head;
else
len = strlen(head);
/* Fail if we have zero lenght string. */
if ((len <= 0) || (len > buflen))
return (0);
strncpy(buf, head, len);
buf[len] = '/0';
/*
** Now replace "+" characters with " " characters and
** "%xx" (hexadecemal) to the ASCII representation.
*/
for (i = 0; i < len; i++)
{
if (buf[i] == '+')
buf[i] = ' ';
}
escape_to_ascii(buf, len);
return (1);
}
static short
get_next(CHAR *head, CHAR *buffer, CHAR **tailp)
{
int hlen;
int blen;
CHAR end;
hlen = 0;
end = ' ';
while (isspace(head[hlen]))
hlen++;
if (head[hlen] == '/0')
return (0);
if ((head[hlen] == '"') || (head[hlen] == '/''))
{
end = head[hlen];
hlen++;
}
blen = 0;
while ((head[hlen] != '/0') && (head[hlen] != end))
{
buffer[blen] = head[hlen];
hlen++;
blen++;
}
buffer[blen] = '/0';
*tailp = &head[hlen];
return (1);
}
search.def
LIBRARY search
DESCRIPTION 'Search ISAPI Extension DLL'
EXPORTS
GetExtensionVersion
HttpExtensionProc
search.dsp
# Microsoft Developer Studio Project File - Name="search" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
CFG=search - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "search.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "search.mak" CFG="search - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "search - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "search - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
MTL=midl.exe
RSC=rc.exe
!IF "$(CFG)" == "search - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SEARCH_EXPORTS" /YX /FD /c
# ADD CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SEARCH_EXPORTS" /YX /FD /c
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x804 /d "NDEBUG"
# ADD RSC /l 0x804 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"search.dll"
!ELSEIF "$(CFG)" == "search - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SEARCH_EXPORTS" /YX /FD /GZ /c
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SEARCH_EXPORTS" /YX /FD /GZ /c
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x804 /d "_DEBUG"
# ADD RSC /l 0x804 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"search.dll" /pdbtype:sept
!ENDIF
# Begin Target
# Name "search - Win32 Release"
# Name "search - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=./Search.c
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
# Begin Source File
SOURCE=./Search.def
# End Source File
# End Group
# End Target
# End Project
Link: http://www.asm32.net/article_disp.asp?ID=1830
- [源码] Sambar Server ISAPI Search extension.
- [源码] Sambar Server ISAPI Search extension
- 源码 Sambar ISAPI TEST
- 源码 Sambar ISAPI TEST
- 源码 Sambar ISAPI "hello.dll"
- 源码 Sambar ISAPI "hello.dll"
- Sambar ISAPI "hello4.dll"
- Sambar ISAPI "hello4.dll"
- IIS5 ISAPI Extension Back Door
- IIS5 ISAPI Extension Back Door
- What an ISAPI extension is?(转载)
- (转载)IIS5 ISAPI Extension Back Door
- iis6 + win2k3中调试isapi filter和extension的方法
- 在win2k3+iis6中调试isapi filter及isapi extension的方法
- ISAPI
- ISAPI
- R Extension package category and search
- VS2003 Front Page Server Extension
- C++字符串完全指引之二 —— 字符串封装类
- 成功誓言
- 杂谈:Web2.0环境下信息构建的第三期成果诞生!
- Java 理论与实践: 线程池与工作队列
- 黄昏感悟
- [源码] Sambar Server ISAPI Search extension.
- 用自删除dll实现应用程序的安装/卸载代码
- IBM ThinkPad笔记本BIOS设置手册
- 关于在程序开头下断点
- 可输入的下拉框(DropDownList)
- JSF优点(转载自中国IT实验室)
- 源码 Sambar ISAPI TEST
- 深入介绍Linux内核(五)
- 中文字体对照表