Я пытаюсь открыть диалоговое окно аутентификации Windows и получить учетные данные, введенные пользователем, в Java.
Идея состоит в том, чтобы вызвать функции CredUIPromptForWindowsCredentialsW и CredUnPackAuthenticationBufferW.
В C ++ это прекрасно работает:
#include <string>
#include <Windows.h>
#include <wincred.h>
int main()
{
CREDUI_INFOW credui = {};
credui.pszMessageText = L"Hello1";
credui.pszCaptionText = L"Hello2";
credui.hwndParent = nullptr;
credui.hbmBanner = nullptr;
credui.cbSize = sizeof(credui);
ULONG authPackage = 0;
LPVOID outCredBuffer = nullptr;
ULONG outCredSize = 0;
BOOL save = false;
int result = CredUIPromptForWindowsCredentialsW(
&credui,
0,
&authPackage,
NULL,
0,
&outCredBuffer,
&outCredSize,
&save,
0x1);
DWORD dwFlags = 0x1;
std::wstring pszUserName = L" ";
std::wstring pszDomain = L" ";
std::wstring pszPassword = L" ";
DWORD domainSize = 100;
DWORD* pDomainSize = &domainSize;
DWORD userNameSize = 100;
DWORD* pUserNameSize = &userNameSize;
DWORD passwordSize = 100;
DWORD* pPasswordSize = &passwordSize;
BOOL boolResult = CredUnPackAuthenticationBufferW(
dwFlags,
outCredBuffer,
outCredSize,
&pszUserName.at(0),
pUserNameSize,
&pszDomain.at(0),
pDomainSize,
&pszPassword.at(0),
pPasswordSize);
if (result == ERROR_SUCCESS) {
printf("getlasterror(): %d\n", GetLastError());
}
return 0;
}
В Java с JNA я могу вызвать диалоговое окно аутентификации Windows, но не могу получить учетные данные пользователя:
package testcredui;
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.Structure;
import com.sun.jna.WString;
import com.sun.jna.platform.win32.WinDef.HBITMAP;
import com.sun.jna.platform.win32.WinDef.HWND;
import com.sun.jna.platform.win32.WinDef.ULONG;
import com.sun.jna.platform.win32.WinDef.ULONGByReference;
import com.sun.jna.platform.win32.WTypes.LPWSTR;
import com.sun.jna.platform.win32.WinDef;
import com.sun.jna.ptr.IntByReference;
import com.sun.jna.ptr.PointerByReference;
import com.sun.jna.platform.win32.WinDef.DWORD;
import com.sun.jna.platform.win32.WinDef.DWORDByReference;
import java.util.Arrays;
import java.util.List;
public class TestCredui {
public interface CInterface extends Library
{
CInterface INSTANCE = (CInterface) Native.load("Credui", CInterface.class);
/*
* CredUIPromptForWindowsCredentialsW
* DWORD WINAPI CredUIPromptForWindowsCredentials(
* PCREDUI_INFO pUiInfo,
* DWORD dwAuthError,
* ULONG *pulAuthPackage,
* LPCVOID pvInAuthBuffer,
* ULONG ulInAuthBufferSize,
* LPVOID *ppvOutAuthBuffer,
* ULONG *pulOutAuthBufferSize,
* BOOL *pfSave,
* DWORD dwFlags
* )
*/
int CredUIPromptForWindowsCredentialsW(
CREDUI_INFO pUiInfo,
int dwAuthError,
ULONGByReference pulAuthPackage,
Pointer pvInAuthBuffer,
ULONG ulInAuthBufferSize,
PointerByReference ppvOutAuthBuffer,
ULONGByReference pulOutAuthBufferSize,
IntByReference pfSave,
int dwFlags
);
/*
CREDUIAPI BOOL CredUnPackAuthenticationBufferW(
DWORD dwFlags,
PVOID pAuthBuffer,
DWORD cbAuthBuffer,
LPWSTR pszUserName,
DWORD *pcchMaxUserName,
LPWSTR pszDomainName,
DWORD *pcchMaxDomainName,
LPWSTR pszPassword,
DWORD *pcchMaxPassword
);
*/
boolean CredUnPackAuthenticationBufferW(
DWORD dwFlags,
Pointer pAuthBuffer,
DWORD cbAuthBuffer,
LPWSTR pszUserName,
DWORDByReference pcchlMaxUserName,
LPWSTR pszDomainName,
DWORDByReference pcchMaxDomainName,
LPWSTR pszPassword,
DWORDByReference pcchMaxPassword
);
/*
* CREDUI_INFO
*
* typedef struct _CREDUI_INFO {
* DWORD cbSize;
* HWND hwndParent;
* PCTSTR pszMessageText;
* PCTSTR pszCaptionText;
* HBITMAP hbmBanner;
* } CREDUI_INFO, *PCREDUI_INFO;
*/
public static class CREDUI_INFO extends Structure {
public int cbSize;
public HWND hwndParent;
public WString pszMessageText;
public WString pszCaptionText;
public HBITMAP hbmBanner;
/**
* getFieldOrder
* @return
*/
@Override
protected List getFieldOrder() {
return Arrays.asList(new String[]{
"cbSize",
"hwndParent",
"pszMessageText",
"pszCaptionText",
"hbmBanner",
});
}
}
}
public static void main(String[] args)
{
CInterface.CREDUI_INFO info = new CInterface.CREDUI_INFO();
info.pszCaptionText = new WString("captionText");
info.pszMessageText = new WString("MessageText");
info.cbSize = info.size();
WinDef.ULONGByReference authPackage = new WinDef.ULONGByReference();
authPackage.setValue(new ULONG(0));
PointerByReference outCredBuffer = new PointerByReference();
WinDef.ULONGByReference outCredSize = new WinDef.ULONGByReference();
IntByReference save = new IntByReference(0);
WinDef.ULONG ulInAuthBufferSize = new WinDef.ULONG(0);
CInterface.INSTANCE.CredUIPromptForWindowsCredentialsW(
info,
0,
authPackage,
null,
ulInAuthBufferSize,
outCredBuffer,
outCredSize,
save,
0x1
);
WinDef.DWORD dwordValue = new DWORD(100);
LPWSTR username = new LPWSTR(" ");
WinDef.DWORDByReference usernameSize = new WinDef.DWORDByReference();
usernameSize.setValue(dwordValue);
LPWSTR domain = new LPWSTR(" ");
WinDef.DWORDByReference domainSize = new WinDef.DWORDByReference();
domainSize.setValue(dwordValue);
LPWSTR password = new LPWSTR(" ");
WinDef.DWORDByReference passwordSize = new WinDef.DWORDByReference();
passwordSize.setValue(dwordValue);
WinDef.DWORD flags = new WinDef.DWORD(0x1);
WinDef.DWORD bufferSize = new WinDef.DWORD(250);
boolean r = CInterface.INSTANCE.CredUnPackAuthenticationBufferW(
flags,
outCredBuffer.getPointer(),
bufferSize,
username,
usernameSize,
domain,
domainSize,
password,
passwordSize
);
System.out.println(username.getValue());
if (r == false) {
System.out.println(Native.getLastError());
}
}
}
Функция GetLastError возвращает 50 -> ERROR_NOT_SUPPORTED -> «Буфер аутентификации не поддерживается.»
Это общие учетные данные в виде обычного текста, которые поддерживаются всеми версиями Windows.
Не знаю почему.
Спасибо за вашу драгоценную помощь.