天天看点

CBSCore 中的字符串 SCZ

CBSCore 中的字符串 SCZ

CBSCore 中的字符串 SCZ 类似于 WCHAR*,但是,有一点不同,就是在WCHAR* 前 -1 位,保存了字符串的长度。

引用的地址还是 WCHAR* 的起始位置。

不知道是怎么实现的。

由于不知道如何表示 -1 位的长度,因此也就没有办法实现 SCZ 结构。

好在可以用系统提供的函数进行初始化,但是,只能用PSCZ 表示,即指向 SCZ 的地址。

但是,再复杂也可以不管,让系统自己去做,我们只要把SCZ 对象的地址保存下来就可以了,因此,把PSCZ 定义成WCHAR*。

直接就按照内容,把它定义成:

typedefWCHAR *PSCZ;

CBSCore 中的许多字符串都是使用了这种格式。

如果直接用 WCHAR* 代替 SCZ,函数运行也能运行,且结果也正确,但是,在退出时会出现 0xc0000374 堆破坏的错误。这是因为在结束函数前要释放变量,释放 SCZ 变量,不权要释放 SCZ 变量指针指向的 WCHAR* 字符串,还要释放 SCZ 变量的前一位,即字符串的长度。

如果是用 WCHAR* 代替 SCZ 的话,SCZ 变量的前一位由于没有初始化,那么释放这一位,就必然出错了。

为了方便转换,CBSCore 提供了十多个函数(64 位系统与 32 位系统提供的函数数量不同)。

用法:

声明变量:

PSCZ *v10 = newPSCZ();

初始化成指定长度的空字符串:

SczAlloc(v10,16);

用 WCHAR* 字符串进行初始化,也可以说是转换:

SczAllocFromSz(v10, L"C:\\Windows");

把PSCZ 转换成 WCHAR* 格式

WCHAR *scz = *v10;

应用示例:

LPCWSTRlpSrc = L"%SystemRoot%\\winsxs\\x86_microsoft-windows-servicingstack_31bf3856ad364e35_6.3.9600.18384_none_9dfef83fe2e442e4";

PSCZ *lpDst = newPSCZ();

SczAllocFromSz(lpDst, lpSrc);

FileExpandPath(*lpDst, lpDst);

SczEnsureBackslashTerminated(lpDst);

PSCZ *lpStackDirectory = newPSCZ() ;

FindServicingStackDirectory(lpStackDirectory);

LoadCbsCoreOnline();

提供的一些函数:

函数名 功能
SczAlloc 初始化指定长度
SczAllocConcat2Sz 连接两个 WCHAR* 字符串到 SCZ
SczAllocConcatSz 连接一个 WCHAR* 字符串到 SCZ
SczAllocConcatSzFast 连接一个 WCHAR* 字符串到 SCZ
SczAllocFormatted 调用SczAllocFormattedArgs
SczAllocFormattedArgs 类似 print 中的格式化参数
SczAllocFromAnsiSz

连接一个Ansi 字符串到 SCZ

先MultiByteToWideChar

SczAllocFromStringTable
SczAllocFromSz 转换WCHAR* 到 PSCZ 格式
SczAllocFromSzAndEnsureBackslash 转换 WCHAR* 到 PSCZ 格式,保证结尾有 \
SczAllocPrefixSz 转换 WCHAR* 到 PSCZ 格式,用指定的前缀
SczAllocConcatUnicodeString 连接一个Unicode 字符串到 SCZ
SczEnsureBackslashTerminated 转换 WCHAR* 到 PSCZ 格式,保证结尾有 \
SczGrowIfNeeded 增加字符串的长度
SczPublicAllocFromSz 转换有接口的字符串pMalloc
SczPublicFree 释放有接口的字符串 pMalloc
SczSize 计算 SCZ 字符串的长度,实现就是读 -1 处的值
FileExpandPath 把字符串中的环境变量扩展成实际值

继续阅读