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 | 把字符串中的环境变量扩展成实际值 |
|
|