2012-09-13 16 views
0

我通过使用类似于answer to my previous question的代码通过System插件获取系统信息。 API函数非常相似,只是它返回(或不是)宽字符串。测试系统插件返回的字符串时的意外logiclib行为

在作为域成员的计算机上使用该脚本时,我无法理解为什么logiclib测试总是​​通过测试的${else}分支。下面的截图显示了该$1不为空:

variable dump

在阅读更多的NetGetDCName reference我认为,这将是最好检查函数的返回值,而不是宽字符字符串的指针。我有点困惑,为什么我的${If} 0 <> $1总是失败?我检查了一个虚拟机,而不是域名的成员,在这种情况下,该域名为$1等于0。那么我认为${IfThen}测试释放内存也是错误的。

下面是示例代码:

!include "logiclib.nsh" 
outfile "hello2.exe" 

!define DEBUG `System::Call kernel32::OutputDebugString(ts)` 

section 

    Call GetDCName 
    pop $0 

    Messagebox MB_OK "DCName=$0" 

sectionEnd 

Function GetDCName 
    ;Push the domain controler name to the stack (or an empty string if no dc) 
    push $0 
    push $1 
    push $2 
    System::Call "netapi32::NetGetDCName(i0, i0, *w 0 r1) i.r2" 
    Dumpstate::debug 
    ${If} 0 <> $1 
     ${debug} "copy $1" 
     StrCpy $0 $1 
    ${else} 
     ${debug} "copy empty string" 
     StrCpy $0 "" 
    ${endif} 
    ${IfThen} $1 <> 0 ${|} System::Call "netapi32::NetApiBufferFree(ir1)" ${|} 
    Pop $2 
    Pop $1 
    Exch $0 
FunctionEnd 

编辑:感谢安德斯,这里是修正功能:

Function GetDCName 
    ;Push the domain controler name to the stack (or an empty string if no dc) 
    push $0 
    push $1 
    push $2 
    System::Call "netapi32::NetGetDCName(i0, i0, *i 0 r1) i.r2" ;do not convert r1 to wchar, keep the pointer to free it 
    ${If} $2 = 0 
     System::Call "*$1(&w${NSIS_MAX_STRLEN} .r0)"  ;get the wchar from the pointer 
     ${IfThen} $1 <> 0 ${|} System::Call "netapi32::NetApiBufferFree(ir1)" ${|} ;free the pointer 
    ${else} 
     StrCpy $0 "" 
    ${endif} 
    Pop $2 
    Pop $1 
    Exch $0 
FunctionEnd 
+0

字符串指针即使函数失败,也可能是非null,总是先检查返回值... – Anders

回答

0

<>运营商是数字,而不是字符串。但这不是你唯一的问题; *可以(通常)只能用于i,而不是t/m/wt/m/w类型转换为C风格的字符串或从C风格的字符串转换,但在你的情况下,你需要实际的内存地址,因为你必须将它传递给自由函数。

你需要传递*i0r1到NetGetDCName,那么如果$ 2为0,那么你可以提取与结构语法(*$1(&w${NSIS_MAX_STRLEN}.r5)*$1(w.r5))和串终于通$ 1触及到自由功能...

+0

天哪,我错过了关于字符串比较器的观点。非常感谢'* $ 1(&w $ {NSIS_MAX_STRLEN} .r5)'符号(我不会猜到)作为我使用崩溃的'* $ 1(w.r5)'符号。不知道为什么,也许是由于我的NSIS专门为长字符串构建的? – Seki

+0

是的,你真的应该使用&w语法,所以你不会溢出缓冲区。 w.r0语法可能只适用于你自己设置字符串的情况,我不记得...... – Anders

相关问题