locked
CredWrite and CRED_PERSIST_LOCAL_MACHINE RRS feed

  • Question

  • Hi all,

    I hope I've found the right place.  I'm using CredRead and CredWrite to save a username and password for my application.  This has been working great, until I recently discovered that the CRED_PERSIST_LOCAL_MACHINE flag I'm using isn't supported by certain flavors Vista and XP (http://msdn.microsoft.com/en-us/library/aa374788%28VS.85%29.aspx). :(

    I've been looking for an alternative API I can use, but haven't had any luck so far.  CredUIPromptForCredentials almost works, except that there are times I need to be able to write credentials without prompting the user first.  As far as I can tell, there's no way to do this with CredUIPromptForCredentials.  Are there any other options available?

    Cheers,
    Colin
    Wednesday, August 26, 2009 10:08 PM

All replies

  • Hi Colin: 

    Your using the CredUIConfirmCredentials() Function, to retrieve the credentials,
    note: The CredUIConfirmCredentials() Function is also able to persist the credentials
    [just pass the CREDUI_FLAGS_EXPECT_CONFIRMATION flag to the "prompt" function].

    I hope this information was good and helpful...

    For further reading:
    http://msdn.microsoft.com/en-us/library/aa374788(VS.85).aspx
    http://msdn.microsoft.com/en-us/library/aa375173(VS.85).aspx

    Have a nice day...

    Best regards,
    Fisnik  


    Coder24.com
    • Proposed as answer by Fisnik Hasani Friday, November 13, 2009 7:30 PM
    Wednesday, October 28, 2009 1:28 PM
  • Hi Colin:

    How is the situation on your side?
    Is this thread solved or NOT?

    Please tell me!

    Have a nice day...

    Best regards,
    Fisnik
    Coder24.com
    Friday, November 13, 2009 7:30 PM
  • Hi again:

    How is the situation on your side?
    Is this thread solved?

    Please tell me!

    Have a nice day...

    Best regards,
    Fisnik
    Coder24.com
    Sunday, December 27, 2009 10:27 AM
  • Hi again:

    Is this thread solved or NOT?
    Please tell me!

    Have a nice day...

    Best regards,
    Fisnik

    Coder24.com
    Saturday, January 2, 2010 2:24 PM
  • He's not using CredPromptForCredentials/CredUIConfirmCredentials.

    He wants to use CredWrite to store credentials without prompting for them.
    Thursday, February 25, 2010 11:14 PM
  • Hi all,

    I hope I've found the right place.  I'm using CredRead and CredWrite to save a username and password for my application.  This has been working great, until I recently discovered that the CRED_PERSIST_LOCAL_MACHINE flag I'm using isn't supported by certain flavors Vista and XP (http://msdn.microsoft.com/en-us/library/aa374788%28VS.85%29.aspx). :(

    I've been looking for an alternative API I can use, but haven't had any luck so far.  CredUIPromptForCredentials almost works, except that there are times I need to be able to write credentials without prompting the user first.  As far as I can tell, there's no way to do this with CredUIPromptForCredentials.  Are there any other options available?

    Cheers,
    Colin
    i think you need to use the API CredGetSessionTypes, which tells you the maximum persistence type supported by the current OS.

    i created a nice wrapper function, 
     
             PersistType = CredGetMaxPersistType(CRED_TYPE_GENERIC);

    Then when filling your CREDENTIAL structure, you can give it the max:

            credential.Type = CRED_TYPE_GENERIC;
            credential.Persist = PersistType;


    i can show you my CredGetMaxPersistType wrapper function (really, i use a byref parameter, with a boolean result to indicate that the call worked):

    //For a given CRED_TYPE, return the maximum supported CRED_PERSIST level
    function CredGetMaxPersistType(CredType: DWORD): DWORD;
    const
    CRED_TYPE_MAXIMUM = 5;
    var
    _CredGetSessionTypes: TCredGetSessionTypes;
    MaximumPersist: array[0..CRED_TYPE_MAXIMUM-1] of DWORD;
    bResult: BOOL;
    begin
    Result := _CredGetSessionTypes(CRED_TYPE_MAXIMUM, PDWORD(@MaximumPersist[0]));
    if Result then
    Result := MaximumPersist[CredType]
    else
    Result := 0;
    end;


    One thing i am curious about, and probably only you can tell me. But does CredPromptForCredentials actually store the credentials in the same place on an OS that doesn't support CRED_PERSIST_LOCALMACHINE? i wonder if, instead, they store it to the registry, or a file somewhere. If it does, then you would want to check that the maximum supported persistence type is Session, rather than LocalMachine, i take actions to store it elsewhere.

    Or perhaps CredPromptForCredentials just doesn't even persist the credentials across sessions if the OS doesn't support it?

    Until i can get a debugger hooked up to a Home version of Windows, i won't be able to reverse engineer what CredPromptForCredentials does. But it's not magic, it's calling API calls just like we can.
    Saturday, February 27, 2010 3:38 PM
  • Thanks for the detailed response!  Sadly, I ended up deciding it wasn't worth my effort to figure out the correct solution for this problem, as it only affects a small small number of our users.  Instead I put some hack in place that they can use as a work around if they encounter the problem.  It's far from an ideal solution, but there are higher priority issues/projects that I'm currently working on.  I'll keep this in mind though, if I have a chance to come back and clean things up some day.

    Cheers,
    Colin
    Monday, March 1, 2010 3:58 AM
  • Hi @colindb. Could you please explain me how you are using CredRead and CredWrite function. I can't use any of them. Please help me !!!
    Monday, August 23, 2010 7:29 AM
  • i can give  you the code I use to store credentials with CredRead and CredWrite. It's written in native Delphi code, so you'll have to translate it into the language you like.

     

     

     

     

     

    function CredReadGenericCredentials(const Target: WideString; var Username, Password: WideString): Boolean;

    var

    Credential: PCREDENTIALW;

    begin

    Credential := nil;

    if CredReadW(PWideChar(Target), CRED_TYPE_GENERIC, 0, Credential) then

    begin

    try

    username := Credential.UserName;

    password := WideCharToWideString(PWideChar(Credential.CredentialBlob), Credential.CredentialBlobSize); //By convention blobs that contain strings do not have a trailing NULL.

    finally

    CredFree(Credential);

    end;

     

    Result := True;

    end

    else

    Result := False;

    end;

    function CredWriteGenericCredentials(const Target, Username, Password: WideString): Boolean;

    var

    PersistType: DWORD;

    Credentials: CREDENTIALW;

    begin

    if not CredGetMaxPersistType(CRED_TYPE_GENERIC, PersistType) then

    begin

    Result := False;

    Exit;

    end;

     

    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 := PersistType; //CRED_PERSIST_ENTERPRISE; //local machine and roaming

    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

    Credentials.UserName := PWideChar(Username);

    Result := CredWriteW(Credentials, 0);

    end;

     

     

     

     

    function CredDeleteGenericCredentials(const Target: WideString): Boolean;

    begin

    Result := CredDelete(Target, CRED_TYPE_GENERIC);

    end;

     

     

    Sample Usage:

     

    //Save credentials for my thing

    CredWriteGenericCredentials('TED5000 MTU1', 'one_in_one', 'password1');

     

    //Read saved credentials for my thing

    var

       username: string;

       password: string;

     

       CredReadGenericCredentials('TED5000 MTU1', username, password);

     

    //Delete the saved credentials

    CredDeleteGenericCredentials('TED5000 MTU1');




    Edit: i fought with Microsoft's text editor too long - and now i give up. The text is bolded and italized - and i can't stop it. Tough.

    Monday, August 23, 2010 11:24 AM