Reputation: 1987
I got this Delphi code from SO that seemed pretty straightforward. I added some types that were missing and substituted some string handling functions that were missing, and got this.
unit WinCred;
interface
uses
Windows, SysUtils;
type
CREDENTIAL_ATTRIBUTE = packed record
Keyword: LPTSTR;
Flags: DWORD;
ValueSize: DWORD;
Value: LPBYTE;
end;
PCREDENTIAL_ATTRIBUTE = ^CREDENTIAL_ATTRIBUTE;
CREDENTIALW = packed record
Flags: DWORD;
Type_: DWORD;
TargetName: LPTSTR;
Comment: LPTSTR;
LastWritten: FILETIME;
CredentialBlobSize: DWORD;
CredentialBlob: LPBYTE;
Persist: DWORD;
AttributeCount: DWORD;
Attributes: PCREDENTIAL_ATTRIBUTE;
TargetAlias: LPTSTR;
UserName: LPTSTR;
end;
PCREDENTIALW = ^CREDENTIALW;
function CredWriteW(Credential: PCREDENTIALW; Flags: DWORD): Boolean; stdcall; external 'Advapi32.dll';
function CredWriteGenericCredentials(const Target, Username, Password: UnicodeString): Boolean;
implementation
function CredWriteGenericCredentials(const Target, Username, Password: UnicodeString): Boolean;
var
Credentials: CREDENTIALW;
begin
ZeroMemory(@Credentials, SizeOf(Credentials));
Credentials.TargetName := PWideChar(Target); //cannot be longer than CRED_MAX_GENERIC_TARGET_NAME_LENGTH (32767) characters. Recommended format "Company_Target"
Credentials.Type_ := CRED_TYPE_GENERIC;
Credentials.UserName := PWideChar(Username);
Credentials.Persist := CRED_PERSIST_LOCAL_MACHINE;
Credentials.CredentialBlob := PByte(Password);
Credentials.CredentialBlobSize := 2*(Length(Password)); //By convention no trailing null. Cannot be longer than CRED_MAX_CREDENTIAL_BLOB_SIZE (512) bytes
Result := CredWriteW(@Credentials, 0);
end;
end.
However, when I test this function
[Test]
[TestCase('user', 'pass')]
procedure TestInsertCred(Username, password: string);
...
procedure TWinCredTests.TestInsertCred(Username, password: string);
begin
Assert.IsTrue(CredWriteGenericCredentials('WinCred_Test', Username, password));
end;
The password shows up in the username.
This is baffling me. Shouldn't the .Username
field take the username? And the password is written to the "credentialBlob"? I've checked all my function signatures to make sure I haven't mistakenly switched things around.
Upvotes: 2
Views: 972
Reputation: 37221
Assuming you're using DUnitX, the first parameter to the TestCase attribute is the test case name, followed by parameters. So you're defining a test case named 'user', passing it 'pass' as UserName and nothing as Password. Try this instead:
[TestCase('TestInsertCred', 'user,pass')]
Upvotes: 4