Chinaunix首页 | 论坛 | 博客
  • 博客访问: 578229
  • 博文数量: 752
  • 博客积分: 40000
  • 博客等级: 大将
  • 技术积分: 5005
  • 用 户 组: 普通用户
  • 注册时间: 2008-10-13 14:47
文章分类

全部博文(752)

文章存档

2011年(1)

2008年(751)

我的朋友

分类:

2008-10-13 16:51:13

字数很少~能不能算文章~ :P

vc写ISAPI不算复杂,因为有向导生成框架,不过估计现在ISAPI用的也不多了吧。.net、asp、jsp、php都不错~。不过vc写的ISAPI可以很灵活、效率高。

刚刚开始写ISAPI,一定要接触这几个宏


BEGIN_PARSE_MAP(CvStockExtension, CHttpServer)
?// TODO: 在此插入 ON_PARSE_COMMAND() 和
?// ON_PARSE_COMMAND_PARAMS() 以将命令挂钩。
?// 例如:

?

//下面两行是定义一个默认的请求处理动作,ITS_EMPTY说明没有参数。

?ON_PARSE_COMMAND(Default, CvStockExtension, ITS_EMPTY)
?DEFAULT_PARSE_COMMAND(Default, CvStockExtension)

//下面两行定义一个有7个参数的处理函数ITS表示字符型。第二行对应参数名或默认值。

?ON_PARSE_COMMAND(SaveBuy, CvStockExtension, ITS_PSTR ITS_PSTR ITS_PSTR ITS_PSTR ITS_PSTR ITS_PSTR ITS_PSTR)
?ON_PARSE_COMMAND_PARAMS("userid code market buy sum des='' totalCost='0'")

//下面的就不用多说了。

?ON_PARSE_COMMAND(SaveSell, CvStockExtension, ITS_PSTR ITS_PSTR ITS_PSTR ITS_PSTR ITS_PSTR ITS_PSTR ITS_PSTR)
?ON_PARSE_COMMAND_PARAMS("userid code market buy sum des='' totalCost='0'")


END_PARSE_MAP(CvStockExtension)

相样的请求函数定义如下,注意参数就可以了。

?void Default(CHttpServerContext* pCtxt);
?void SaveBuy(CHttpServerContext* pCtxt,LPTSTR userid,LPTSTR code,LPTSTR market,LPTSTR buy,LPTSTR sum,LPTSTR des,LPTSTR totalCost);
?void SaveSell(CHttpServerContext* pCtxt,LPTSTR userid,LPTSTR code,LPTSTR market,LPTSTR buy,LPTSTR sum,LPTSTR des,LPTSTR totalCost);

另外在IIS配置中有一个选项。“是否缓存ISAPI程序”。如果选择缓存的话,这时你在ISAPI程序中申请的全局内存块可以被所有的请求客户(比如IE)端看到,可以利用这个来处理需要为所为客户端共享的数据,比如:聊天程序的聊天记录~。速度比放到数据库里可以快很多,但要注意做好互斥。如果设置成不缓存,就是每个请求之间不可见的了~

另外还有一个就是ISAPI中取得cookie信息的方法如下:

@_@代码在公司,此处先省略若干字~~~明天补齐~~

最后一点(罗唆吧?),就在如果在ISAPI中用Mutex或CreateFileMapping的话,可以会不能成功找开,因为ISAPI运行帐号权限太低~,解决办法可以参考下面代码:


HANDLE CMemRecord::ObtainAccessableMutex( BOOL bInitialOwner, LPTSTR szName )
{
 SID_IDENTIFIER_AUTHORITY siaWorld = SECURITY_WORLD_SID_AUTHORITY;
 PSID psidEveryone = NULL;
 HANDLE hMutex = NULL  ;
 int nSidSize ;
 int nAclSize ;
 PACL paclNewDacl = NULL;
 SECURITY_DESCRIPTOR sd ;
 SECURITY_ATTRIBUTES sa ;

 __try{
  // Create the everyone sid
  if (!AllocateAndInitializeSid(&siaWorld, 1, SECURITY_WORLD_RID, 0,
   0, 0, 0, 0, 0, 0, &psidEveryone))
  {           
   psidEveryone = NULL ;
   __leave;
  }

  nSidSize = GetLengthSid(psidEveryone) ;
  nAclSize = nSidSize * 2 + sizeof(ACCESS_ALLOWED_ACE) + sizeof(ACCESS_DENIED_ACE) + sizeof(ACL) ;
  paclNewDacl = (PACL) LocalAlloc( LPTR, nAclSize ) ;
  if( !paclNewDacl )
   __leave ;
  if(!InitializeAcl( paclNewDacl, nAclSize, ACL_REVISION ))
   __leave ;
  if(!AddAccessDeniedAce( paclNewDacl, ACL_REVISION, WRITE_DAC | WRITE_OWNER, psidEveryone ))
   __leave ;
  // I am using GENERIC_ALL here so that this very code can be applied to
  // other objects.  Specific access should be applied when possible.
  if(!AddAccessAllowedAce( paclNewDacl, ACL_REVISION, GENERIC_ALL, psidEveryone ))
   __leave ;
  if(!InitializeSecurityDescriptor( &sd, SECURITY_DESCRIPTOR_REVISION ))
   __leave ;
  if(!SetSecurityDescriptorDacl( &sd, TRUE, paclNewDacl, FALSE ))
   __leave ;
  sa.nLength = sizeof( sa ) ;
  sa.bInheritHandle = FALSE ;
  sa.lpSecurityDescriptor = &sd ;

  hMutex = CreateMutex( &sa, bInitialOwner, szName ) ;
  if( !hMutex )       
   hMutex = OpenMutex( SYNCHRONIZE, FALSE, szName ) ;

 }__finally{
  if( !paclNewDacl )
   LocalFree( paclNewDacl ) ;
  if( !psidEveryone )
   FreeSid( psidEveryone ) ;

 }

 return hMutex ;
}

 

HANDLE CMemRecord::ObtainAccessableFileMapping( DWORD nSize, LPTSTR szName )
{
 SID_IDENTIFIER_AUTHORITY siaWorld = SECURITY_WORLD_SID_AUTHORITY;
 PSID psidEveryone = NULL;
 HANDLE hMapFile = NULL  ;
 int nSidSize ;
 int nAclSize ;
 PACL paclNewDacl = NULL;
 SECURITY_DESCRIPTOR sd ;
 SECURITY_ATTRIBUTES sa ;

 __try{
  // Create the everyone sid
  if (!AllocateAndInitializeSid(&siaWorld, 1, SECURITY_WORLD_RID, 0,
   0, 0, 0, 0, 0, 0, &psidEveryone))
  {           
   psidEveryone = NULL ;
   __leave;
  }

  nSidSize = GetLengthSid(psidEveryone) ;
  nAclSize = nSidSize * 2 + sizeof(ACCESS_ALLOWED_ACE) + sizeof(ACCESS_DENIED_ACE) + sizeof(ACL) ;
  paclNewDacl = (PACL) LocalAlloc( LPTR, nAclSize ) ;
  if( !paclNewDacl )
   __leave ;
  if(!InitializeAcl( paclNewDacl, nAclSize, ACL_REVISION ))
   __leave ;
//  if(!AddAccessDeniedAce( paclNewDacl, ACL_REVISION, WRITE_DAC | WRITE_OWNER, psidEveryone ))
//   __leave ;
  // I am using GENERIC_ALL here so that this very code can be applied to
  // other objects.  Specific access should be applied when possible.
  if(!AddAccessAllowedAce( paclNewDacl, ACL_REVISION, GENERIC_ALL, psidEveryone ))
   __leave ;
  if(!InitializeSecurityDescriptor( &sd, SECURITY_DESCRIPTOR_REVISION ))
   __leave ;
  if(!SetSecurityDescriptorDacl( &sd, TRUE, paclNewDacl, FALSE ))
   __leave ;
  sa.nLength = sizeof( sa ) ;
  sa.bInheritHandle = FALSE ;
  sa.lpSecurityDescriptor = &sd ;
  /*
  hMutex = CreateMutex( &sa, bInitialOwner, szName ) ;
  if( !hMutex )       
  hMutex = OpenMutex( SYNCHRONIZE, FALSE, szName ) ;
  */
  hMapFile = CreateFileMapping(INVALID_HANDLE_VALUE,    // current file handle
   &sa,                              // default security
   PAGE_READWRITE,                    // read/write permission
   0,                                 // max. object size
   nSize,                                 // size of hFile
   szName);            // name of mapping object

  if (hMapFile == NULL)
  {
   hMapFile=OpenFileMapping(SYNCHRONIZE,FALSE,szName);

   if(hMapFile==NULL)
   {
    DWORD dError = GetLastError();
    TRACE("Could not create file mapping object.\r\n");
   }
  }


 }__finally{
  if( !paclNewDacl )
   LocalFree( paclNewDacl ) ;
  if( !psidEveryone )
   FreeSid( psidEveryone ) ;

 }

 return hMapFile ;
}

好了~88~


--------------------next---------------------


调试ISAP和发布ISAPI时应该注意的构造请求格式的问题


Web 浏览器的不一致性
当创建服务器扩展 DLL 和创建包含调用扩展的链接或窗体的 Web 页时,必须牢记:尽管您控制着服务器端发生的操作,但却不能控制用户的 Web 浏览器。例如,请看下面的 HTML 窗体:



该窗体生成语法取决于个别浏览器的请求。Microsoft Internet Explorer 将发送如下命令行:

而 Netscape Navigator 将发送:

如果是通过 GET 方法将窗体发送到服务器,则 Microsoft Internet Explorer 将在窗体的操作中追加问号。如果窗体的方法是 POST,它将不在操作中追加问号;但是,在扩展 DLL 名称的后面必须有一个问号,以指示该 DLL 是要运行的脚本,而不是要下载的项。Netscape Navigator 及其后续版本则总是发送在操作的结尾包含一个且只包含一个问号的命令行,不论用来发送窗体的方法和 ACTION 的语法是什么。这些浏览器的其他版本和其他公司编写的浏览器的行为可能不同。
使用 MfcISAPICommand 参数
为了向您提供一种简单的方法来应付此浏览器不一致的问题,同时仍保留利用命令处理程序的能力,MFC 实现了 MfcISAPICommand 参数。如果“MfcISAPICommand”是第一个可用的参数,它的值将是由 CHttpServer 对象用来处理请求的命令处理程序。如果第一个可用的参数不是“MfcISAPICommand”,那么 CHttpServer 对象将在命令行上查找扩展名称后面的第一项以确定要调用的函数,这与它在 MFC 4.1 参数处理中的操作一样。
注意 除非“MfcISAPICommand”参数位于窗体数据的开头,否则将被当作普通参数处理。
下面的 HTML 窗体显示建议的“MfcISAPICommand”参数用法,该参数使 Internet 服务器扩展能够正确地处理由 Microsoft 或 Netscape 浏览器生成的请求:

Enter your full name:







--------------------next---------------------

阅读(412) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~