2010-08-09 62 views
6

我正在使用Delphi 2010,我的程序想要获得系统的临时路径。我正在使用TPath.GetTempPath,一切工作正常......至少对我和我的同事来说。但在某些客户机器上,此方法返回(当然)不存在的裁剪路径。我发现问题似乎是对GetLongPathName()的底层调用的结果。Delphi TPath.GetTempPath结果被裁剪

完整的代码如下所示:

[...] 
var 
TmpDir : String; 
Len : Integer; 
begin 

[... Call to GetTempPath succeeds and we have a valid temp directory in short "~" notation in var TmpDir ...] 

Len := GetLongPathName(PChar(TmpDir), nil, 0);  // Len = 37 
    SetLength(TmpDir, Len - 1);       // We want to set the len of TmpDir to 37 - 1. 
    GetLongPathName(PChar(TmpDir), PChar(TmpDir), Len); // Only 32 (instead of 36) characters are copied - so we have a cropped path - But why?! 

end; 
[...] 

这只是发生在某些系统上,我不知道为什么。我发现了一个令人讨厌的解决方法,但我想知道这里发生了什么。

有人可以对此有所了解吗?

+0

您能否介绍一下正确的(预期的)和错误的(实际的)路径名的例子吗?可能是Unicode或编码问题? – 2010-08-10 06:26:59

+0

我们认为这也是第一位的,但路径名不包含任何可能导致Unicode转换问题的字符。 GetLongPathName的结果路径名仅缺失最后4个字符(“Temp \”的“emp \”) - 所有其他字符都是有效的。 – Patrick 2010-08-10 08:07:28

+0

听起来像http://qc.embarcadero.com/wc/qcmain.aspx?d=92006 – 2016-08-29 15:57:21

回答

4

有一个关于国土安全的页面此Windows API函数注:

“为 GetLongPathName()和类似 函数的返回缓冲区可能返回截断 路径,导致难以 - 查找错误。“

https://buildsecurityin.us-cert.gov/bsi-rules/home/g1/753-BSI.html

如果你的源代码,你可以,如果这篇文章中所述的问题在Delphi 2010的实现存在检查。

+0

你是对的,我也发现,我的“讨厌的解决方法”是最初将Len设置为MAX_PATH并检查GetLongPathName的结果(),但我想知道为什么Embarcadero使用另一种方法...但感谢你张贴这个,因为它验证了我的方法。 – Patrick 2010-08-09 15:01:47

+0

您应该向QC报告。 – 2010-08-09 15:38:44

+1

那么问题是什么?问题中的代码正确地调用了两次函数,不是吗?一旦找到所需的长度,然后第二次填充真实的缓冲区。您引用的代码首先分配缓冲区,以便第一次调用该函数可能会起作用,但如果失败,它将分配一个新的缓冲区并使用它。这真的是一个重要的区别吗?文章警告,假设第一次调用在给定MAX_PATH大小的缓冲区时总会成功。这种警告如何适用于这种情况? – 2010-08-09 15:42:00

3

,如果你尝试,会发生什么:

var 
    longpath : string; 

SetLength(longpath,MAX_PATH); 
SetLength(longpath, GetLongPathName(PChar(TmpDir),PChar(LongPath),MAX_PATH)); 

这个工作对我来说,你的版本截短的路径。

+0

这就是我在我的“解决方法”中所做的事情 - 如果问题在您的计算机上发生:如果TPath.GetTempPath()函数适合您,它会很有趣? – Patrick 2010-08-09 15:10:07

+1

此代码可能会给您提供比Max_Path更长的字符串,但只分配Max_Path字符。也就是'Length(longpath)> StrLen(PChar(longpath))''。您可能还会留下一个带有垃圾的字符串 - 当缓冲区太小时,文档没有说明函数存储在缓冲区中的内容。安全公告和文档都描述了避免该问题的方法。 – 2010-08-09 23:27:32

+0

好的,我们应该在这里提到,GetLongPathName的返回值很重要,应该检查。 – Patrick 2010-08-10 07:58:32