如何将 std::wstring 转换为 LSA_UNICODE_STRING
今天,我能够编写一个简单的 C++ 程序,该程序授予用户“作为服务登录”权限 。其中一部分涉及在 LPCWSTR
和 LSA_UNICODE_STRING
。执行此操作的代码如下:
LSA_UNICODE_STRING StringToLsaUnicodeString(LPCWSTR string) {
LSA_UNICODE_STRING lsaString;
DWORD dwLen = 0;
dwLen = wcslen(string);
lsaString.Buffer = (LPWSTR) string;
lsaString.Length = (USHORT)((dwLen) * sizeof(WCHAR));
lsaString.MaximumLength = (USHORT)((dwLen + 1) * sizeof(WCHAR));
return lsaString;
}
当我在此函数中出现一些小错误时,我调用 LsaLookupNames2()
失败,代码为 87(十六进制 0x57)“参数不正确。”我试图在使用 std::wstring 的 C++ 应用程序中进行此调用,但失败了。我当前的功能如下:
#if defined(_UNICODE)
LSA_UNICODE_STRING toLsaUnicodeString (std::wstring str) {
LSA_UNICODE_STRING lsaWStr;
DWORD len = 0;
LPWSTR cstr = (LPWSTR)str.c_str();
len = wcslen(cstr);
lsaWStr.Buffer = cstr;
lsaWStr.Length = (USHORT)((len) * sizeof(WCHAR));
lsaWStr.MaximumLength = (USHORT)((len + 1) * sizeof(WCHAR));
return lsaWStr;
}
#endif
我做错了什么?
Today I was able to write a simple C++ program that granted a user the "Log on as a service" privilege. Part of this involved converting between a LPCWSTR
and an LSA_UNICODE_STRING
. The code to do that is here:
LSA_UNICODE_STRING StringToLsaUnicodeString(LPCWSTR string) {
LSA_UNICODE_STRING lsaString;
DWORD dwLen = 0;
dwLen = wcslen(string);
lsaString.Buffer = (LPWSTR) string;
lsaString.Length = (USHORT)((dwLen) * sizeof(WCHAR));
lsaString.MaximumLength = (USHORT)((dwLen + 1) * sizeof(WCHAR));
return lsaString;
}
When I had some small errors in this function, my call to LsaLookupNames2()
failed with a code 87(hex 0x57) "The parameter is incorrect." I am trying to make this call in a C++ app that uses std::wstring
and it is failing. My current function there is as follows:
#if defined(_UNICODE)
LSA_UNICODE_STRING toLsaUnicodeString (std::wstring str) {
LSA_UNICODE_STRING lsaWStr;
DWORD len = 0;
LPWSTR cstr = (LPWSTR)str.c_str();
len = wcslen(cstr);
lsaWStr.Buffer = cstr;
lsaWStr.Length = (USHORT)((len) * sizeof(WCHAR));
lsaWStr.MaximumLength = (USHORT)((len + 1) * sizeof(WCHAR));
return lsaWStr;
}
#endif
What am I doing wrong?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您可能会遇到从
str.c_str()
返回的wchar_t*
的生命周期问题。str.c_str()
将返回一个指向底层字符串的指针,该字符串的生命周期由str
控制。由于str
是按值传递的,因此它将在toLsaUnicodeString
函数末尾被销毁,导致返回的LSA_UNICODE_STRING
指向内存已被解除分配。为了避免这种情况,您需要在toLsaUnicodeString
函数中创建底层字符串的副本,并将该副本与返回的LSA_UNICODE_STRING
相关联,如下所示:现在内存已在堆上分配,您有责任确保它已被释放。您可以使用如下所示的函数来处理此问题。
更好的是使用 RAII 来管理内存并保证当变量不再使用时将其释放。有关此方法的详细信息,请参阅 Mr_C64 的回答。
You're likely encountering a lifetime issue with the
wchar_t*
returned fromstr.c_str()
.str.c_str()
will return a pointer to an underlying string whose lifetime is governed bystr
. Sincestr
is passed by-value, it will be destroyed at the end of thetoLsaUnicodeString
function, resulting in the returnedLSA_UNICODE_STRING
pointing at memory that has been deallocated. In order to avoid this, you'll need to make a copy of the underlying string in thetoLsaUnicodeString
function, and associate the copy with the returnedLSA_UNICODE_STRING
, something like:Since the memory is now allocated on the heap, you are responsible for making sure it is deallocated. You can use a function like the following to take care of this.
Even better would be to use RAII to manage the memory and guarantee that it is released when the variable is no longer in use. See Mr_C64's answer for details on this approach.
我认为在 C++ 中执行此操作的正确方法是围绕原始 C 结构 LSA_UNICODE_STRING 编写一个 RAII 包装器 类。
此类的构造函数重载正确地初始化它,析构函数释放分配的资源(帮助编写异常安全代码),并且您可以提供一些operator=重载来执行正确的深层复制。
动态分配的WCHAR缓冲区不是使用显式的new[]和delete[],而是由std::vector的实例管理,这简化了代码(例如std::vector的析构函数将自动释放分配的内存)。
像这样的东西:
I think the correct way of doing this in C++ is to write a RAII wrapper class around the raw C structure LSA_UNICODE_STRING.
The constructor overloads of this class properly initialize it, the destructor releases allocated resources (helping writing exception-safe code), and you can provide some operator= overloads to do proper deep-copies.
Instead of using explicit new[] and delete[], the dynamically-allocated WCHAR buffer is managed by an instance of std::vector, which simplifies the code (e.g. std::vector's destructor will automatically release the allocated memory).
Something like this:
您可以使用 RtlInitUnicodeString 函数命令初始化一个 unicode 字符串。使用 UNICODE_STRING 调用 RtlFreeUnicodeString< /a>.
UNICODE_STRING 和 LSA_UNICODE_STRING 相同。
You can use the RtlInitUnicodeString function in order to initialize a unicode string. After using the UNICODE_STRING call RtlFreeUnicodeString.
The UNICODE_STRING and LSA_UNICODE_STRING are identical.