惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

IT之家
IT之家
L
LangChain Blog
博客园 - 聂微东
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
GbyAI
GbyAI
博客园_首页
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
酷 壳 – CoolShell
酷 壳 – CoolShell
D
Docker
V
V2EX
月光博客
月光博客
Recent Commits to openclaw:main
Recent Commits to openclaw:main
S
SegmentFault 最新的问题
雷峰网
雷峰网
Stack Overflow Blog
Stack Overflow Blog
Cyberwarzone
Cyberwarzone
P
Privacy International News Feed
Spread Privacy
Spread Privacy
Project Zero
Project Zero
腾讯CDC
Engineering at Meta
Engineering at Meta
T
Tenable Blog
aimingoo的专栏
aimingoo的专栏
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Jina AI
Jina AI
大猫的无限游戏
大猫的无限游戏
量子位
Blog — PlanetScale
Blog — PlanetScale
D
DataBreaches.Net
T
Troy Hunt's Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
美团技术团队
N
News and Events Feed by Topic
T
Tor Project blog
H
Help Net Security
www.infosecurity-magazine.com
www.infosecurity-magazine.com
Last Week in AI
Last Week in AI
S
Security Affairs
小众软件
小众软件
Scott Helme
Scott Helme
云风的 BLOG
云风的 BLOG
Apple Machine Learning Research
Apple Machine Learning Research
Vercel News
Vercel News
人人都是产品经理
人人都是产品经理
PCI Perspectives
PCI Perspectives
TaoSecurity Blog
TaoSecurity Blog
博客园 - 叶小钗
V
Visual Studio Blog
The Cloudflare Blog
Recent Announcements
Recent Announcements

博客园 - vibration

ATL3.0组件注册bug的解决方法 奇怪的引用错误及解决方法 OLE2T在VS2003中转换中文失败的问题及解决方法 标题栏按钮的WTL实现 AppBar的WTL实现 招聘C++和C#开发工程师 关于C++模板的连接问题 - vibration - 博客园 用窗口消息解决COM接口的多线程访问问题 用全局接口表实现COM接口在不同线程中的传递 MyMSN支持自定义内容了 自画菜单的WM_MEASUREITEM只会发送一次 悼念皮皮 上了点照片 一个测试记忆力的小游戏 老板该如何向核心员工许诺 ActiveScript SkinX界面换肤框架更新 反射获取定制Attribute Skin技术实现框架(完)
ATL组件中文路径注册问题(转载)
vibration · 2005-09-07 · via 博客园 - vibration

ATL组件注册的一个很糟糕的BUG,以至于需要通过修改ATL源码来解决。记录在此,方便下次重装机器后使用。

  我曾用ATL写过一个COM组件(MBCS下编译),如果安装在中文路径下的话,注册就会失败.
  为什么会失败?
  打开ATL的源文件statreg.h,可以找到函数BOOL AddString(LPCOLESTR lpsz),他被
组件的UpdateRegistry所调用,他又调用了BOOL AddChar(const TCHAR* pch).问题就
出现在这两个函数中。请看:
  BOOL AddString(LPCOLESTR lpsz)
  {
   USES_CONVERSION;
   LPCTSTR lpszT = OLE2CT(lpsz);
   while (*lpszT)
   {
    AddChar(lpszT);
    lpszT++; // note! @1
   }
   return TRUE;
  }
  BOOL AddChar(const TCHAR* pch)
  {
   if (nPos == nSize) // realloc @3
   {
    nSize *= 2;
    p = (LPTSTR) CoTaskMemRealloc(p, nSize*sizeof(TCHAR));
   }
   p[nPos++] = *pch;
#ifndef _UNICODE
   if (IsDBCSLeadByte(*pch))
    p[nPos++] = *(pch + 1); file://note! @2
#endif
   return TRUE;
  }
 当我们不是使用UNICODE时,如果遇到一个汉字的话,标注@2行识别整个汉字,存入缓冲区.但是pch变量仍然指向
汉字的第一个字节,返回到@1行时,lpszT++后指向了该汉字的第二个字节!以后又把该汉字的第二字节当成一个独立的字
符再次处理一遍.所以就产生了乱码.(致使组件注册的信息有一部分是错误的)
 怎么解决?
 由上面的分析,很容易得到解决的办法:
  BOOL AddString(LPCOLESTR lpsz)
  {
   USES_CONVERSION;
   LPCTSTR lpszT = OLE2CT(lpsz);
   while (*lpszT)
   {
    AddChar(lpszT);
    lpszT++; 
   }
   return TRUE;
  }
/*******************************************************************
 * This function cause some error in hanzi.
 *  Modified by L.C. ,Nov 12th,2001
 *******************************************************************/
/********************************************************************
  BOOL AddChar(const TCHAR* pch)
 ********************************************************************/
  BOOL AddChar(const TCHAR* &pch) file://we'll modify the pch value
  {
   if (nPos == nSize) // realloc
   {
    nSize *= 2;
    p = (LPTSTR) CoTaskMemRealloc(p, nSize*sizeof(TCHAR));
   }
   p[nPos++] = *pch;
#ifndef _UNICODE
   if (IsDBCSLeadByte(*pch))
/*******************************************************************
    p[nPos++] = *(pch + 1); 
********************************************************************/
    p[nPos++] = *( ++ pch);
#endif
   return TRUE;
  }
 还有什么错误?
 请观察@3行,如果阅读一下这个类的源代码(180行开始),很明显会有缓冲区溢出的危险:
在非UNICODE情况下,nPos要加两次,而进入这段代码时有可能是nPos=nSize-1.如果是这样,恐怕程序的
会有一些无法预测的行为(虽然几率很小:在 rgs文件中出现大段中文的可能性不多)。修改实际上比较
容易,将if (nPos == nSize) 变为if (nPos == nSize-1)即可。(当然有很多别的方法)
 结论
 如果你的组件有可能出现在中文路径下的话(使用MBCS),建议你在编译时使用_ATL_STATIC_REGISTRY
编译,并且在编译前修改ATL中相关的代码(或自己写注册函数)。否则现有的ATL.DLL会坏了你的好事.
 修改现有的类库是很危险的事情。因为他们的调用关系太复杂了.不过,如果他里面有BUG,这也算是一个
好方法.