0

I'm trying to use code from http://msdn.microsoft.com/en-us/library/windows/desktop/aa380536(v=VS.85).aspx

The line for AcquireCredentialsHandle says that the second argument is not compatible with PSECURITY_STRING. Anyone know what I can do here?

Michael Steele
  • 15,512
  • 2
  • 23
  • 24
Bluebaron
  • 2,289
  • 2
  • 27
  • 37
  • You can pass a compatible variable or cast it ... however we can't tell you what you're doing wrong unless you show us your code. – AJG85 Dec 12 '11 at 15:54

1 Answers1

1

Like with most Win32 API functions with string parameters, AcquireCredentialsHandle() maps to either AcquireCredentialsHandleA() or AcquireCredentialsHandleW() depending on whether UNICODE is defined, so it expects char* or wchar_t* pointers, respectively. A SECURITY_STRING, on the other hand, is a structure that is modeled after the UNICODE_STRING structure - both of which contain UTF-16 encoded Unicode data only.

To pass a SECURITY_STRING value to AcquireCredentialsHandleA(), you need to convert the contents of the SECURITY_STRING::Buffer member to Ansi first:

PSECURITY_STRING str;
...
int len = WideCharToMultiByte(0, 0, (LPWSTR)str->Buffer, str->Length, NULL, 0, NULL, NULL);
std::string tmp(len);
WideCharToMultiByte(0, 0, (LPWSTR)str->Buffer, str->Length, &tmp[0], len, NULL, NULL);
AcquireCredentialsHandle(..., tmp.c_str(), ...); 

To pass a SECURITY_STRING value to AcquireCredentialsHandleW(), you need to pass the SECURITY_STRING::Buffer member as-is:

PSECURITY_STRING str;
...
AcquireCredentialsHandle(..., (LPWSTR)str->Buffer, ...); 

Either way, you do not pass a pointer to the SECURITY_STRING itself.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • Just a comment on `SECURITY_STRING`'s. The `Buffer` member is declared to be a `USHORT` in `SECURITY_STRING`'s documentation, a `PWSTR` in `UNICODE_STRING`'s documentation, and an `unsigned short *` in the sspi.h (when in 64-bit mode). It may be that in 64-bit mode the `Buffer` parameter is not to be treated as a pointer, but the start of the character stream. – Michael Steele Sep 26 '13 at 17:47
  • `SECURITY_STRING`'s documentation contains another possible error. The `Length` and `MaximumLength` members are said to be the size in bytes, but the true source headers include MIDL information indicating that both represent the size in wide characters. – Michael Steele Sep 26 '13 at 17:51
  • 1
    `SECURITY_STRING::Buffer` is a pointer to a UTF-16 character array. The `SECURITY_STRING` documentation is wrong, it should have said `USHORT*` instead. As far as UTF-16 is concerned, `USHORT*`, `unsigned short*`, and `LPWSTR` are all the same and can be freely type-casted between them, as they are all 16-bit. As for `Length` and `MaximumLength`, they really are expressed in bytes, not characters. The MIDL `size_is()` and `length_is()` attributes are expressed in array elements. Since `Buffer` is a UTF-16 character array, the MIDL declarations are dividing `Length` and `MaximumLength` by 2. – Remy Lebeau Sep 26 '13 at 22:48
  • Thanks, that clarifies things. – Michael Steele Sep 27 '13 at 16:00