PathAppend几个注意点

时间:2022-09-13 20:28:40

msdn对pathappend介绍的开头就有一句话说误用该接口会导致缓冲越界,建议使用更安全的PathCchAppend 或者PathCchAppendEx接口。今天就说说几个注意点:
(1)头文件包含,一般windows编程包含windows.h就可以,但是用PathAppend就必须要添加shlwapi.h,shlwapi是啥意思,打开.h文件,第一行就是Interface for the Windows light-weight utility APIs 。windows 轻量级功能接口。网上还有一个说明Shell Light-Weight Application Programming Interface,貌似更准确。大概意思也就有数。
(2)接口的两个参数Inout LPTSTR pszPath, In LPCTSTR pszMore
对长度的限制都是MAX_PATH,那附加之后,就会超过这个范围。先说单个参数。输入参数本身如果用strcpy/_tcscpy进行,那本身就已经存在越界的风险。如果这两个子串都在栈空间上,被覆盖是很容易的事。
(3)当我用debug版本测试PathAppend时,发现如果path+more超过MAX_PATH,path就会变成空串。此时PathAppend的返回值是FALSE,所以说,有返回值的接口判断返回值是避免异常最有效的手段。但是需要注意的是此时如果通过GetLastError()获取原因时,返回值是0,同时errno也是0,当然MSDN没说可以用GLE获取,但是这也是一个值得注意的地方。如何获取失败原因?不知道。所以一定要考虑到路径拼接之后的长度,包括可能会自动添加的\加上结尾的null,一共会不会超过MAX_PATH的长度,这个很关键。
(4)第(3)点中说到超过长度,还有一个后果是pszPath会直接变成空串,当然不是把path全部置0,而是第一个字节置0。其实这也是很可能会导致严重问题的设计,还是那句话,要判断返回值 ,不判断那是你的问题,接口不告诉你那是接口的问题。
(5)后来发现(3)(4)说的有问题,如果more参数是空串,那么path是不会置为空串的,而是把path截断为MAX_PATH-1的长度。同事more是空串在路径拼接的时候,也不会自动加斜杠。如果你无法指望用char path[MAX_PATH] = "c:\\test"; PathAppend(path, "");来把c:\test变成c:\test\。