locked
CredUIPromptForWindowsCredentials Vista SP0 RRS feed

  • Question

  • Hello Everyone, I am working on a new application, of which a portion requires a prompt for user credentials for an online service. For this task, I am using the CredUIPromptForWindowsCredentials call from CredUI.dll. This function, in the form I use it, works perfectly on Windows 7. On Vista SP0, I am getting an error, ERROR_BAD_ARGUMENTS. I am importing the API call into C#.

    Import signature:
    [DllImport(DLL_CREDUI, EntryPoint = "CredUIPromptForWindowsCredentialsW", CharSet = CharSet.Unicode)] 
    
    
    
    public static extern CREDUI_RESULT CredUIPromptForWindowsCredentials(
    ref CREDUI_INFO pUiInfo,
    uint dwAuthError,
    ref
    IntPtr pulAuthPackage,
    IntPtr pvInAuthBuffer,
    ulong ulInAuthBufferSize,
    out IntPtr ppvOutAuthBuffer,
    out ulong pulOutAuthBufferSize,
    ref
    bool pfSave, CREDUIWIN_FLAGS flags);

    The actual call has the following attributes:
    pUiInfo -> CRED_INFO containing caption, message and hwnd of parent form
    dwAuthError = 0
    pulAuthPackage -> IntPtr that is 0
    pvInAuthBuffer -> IntPtr that is 0
    ulInAuthBufferSize = 0
    ppvOutAuthBuffer -> IntPtr to hold result
    pulOutAuthBufferSize -> ulong to hold result
    pfSave -> bool that is false
    flags = CREDUIWIN_GENERIC (0x1)

    I don't know where the problem lies, except that it has to do with my parameters. The dialog does not appear at all. I am suspecting this might have to do with a null auth package, but the msdn docs, http://msdn.microsoft.com/en-us/library/aa375178(VS.85).aspx, seem to indicate that NULL is valid for just plain credentials.

    Any help that could be provided would be awesome.

    Thanks,
    ThreeSevenths

    • Edited by ThreeSevenths Monday, October 19, 2009 12:14 PM Formatting issues
    Monday, October 19, 2009 12:11 PM

Answers

  • Hello all, sorry to have bothered everyone. I had the signature wrong. Upon further inspection, ulInAuthBufferSize and pulOutAuthBufferSize are 32 bits wide, declared as ulong in C++. In C#, ulong is 64-bits wide. Interestingly, this was okay for the 64bit call, but as expected, broke the 32bit call. The proper signature is
    [DllImport(DLL_CREDUI, EntryPoint = "CredUIPromptForWindowsCredentialsW", CharSet = CharSet.Unicode)]
    public static extern CREDUI_RESULT CredUIPromptForWindowsCredentials(
        ref CREDUI_INFO pUiInfo, 
        uint dwAuthError, 
        ref IntPtr pulAuthPackage, 
        IntPtr pvInAuthBuffer, 
        UInt32 ulInAuthBufferSize, 
        out IntPtr ppvOutAuthBuffer, 
        out UInt32 pulOutAuthBufferSize, 
        ref bool pfSave, 
        CREDUIWIN_FLAGS flags);
    Thanks everyone for your great ideas.
    ThreeSevenths
    • Marked as answer by ThreeSevenths Monday, October 19, 2009 10:48 PM
    Monday, October 19, 2009 10:48 PM

All replies

  • This is probably a pretty subtle error and I'm more familiar with using these functions in C++ not C# so take my advice with a grain of salt, but what about the following:

    1) pvInAuthBuffer says it should be a ptr to a BLOB, not an int ptr.  The docs say that you should just pass NULL instead of a ptr if you don't want to prepopulate credentials.  Have you tried that?

    2) ppvOutAuthBuffer also says it should be a ptr to a BLOB, not an int ptr.
    Monday, October 19, 2009 4:37 PM
  • Hi Adam, thank you for your response. IntPtr in C# is a void* for C++ folks. In this respect, we treat all pointers as untyped.

    Thanks,
    ThreeSevenths
    Monday, October 19, 2009 5:58 PM
  • Oh, ok that makes sense. Yeah it's hard to know what is wrong without the code and the documentation is a bit unclear in certain places. The documentation does mention specifying a CREDUIWIN_AUTHPACKAGE_ONLY flag that could be set if the auth package is NULL, although it doesn't specifically say if it's required in that case. Have you tried that? Maybe you could also just try passing in NULL instead of a valid ptr that is set to NULL. Those are just guesses though. I'm just as stumped as you.
    Monday, October 19, 2009 6:42 PM
  • This is probably a stupid question (you do show flags == CREDUIWIN_GENERIC above), but you're definitely not specifying CREDUIWIN_SECURE_PROMPT in the flags?  It's not supported in SP0 (which I'm sure you already know ... I'm grasping at straws!).

    -IAmHe

    Monday, October 19, 2009 10:07 PM
  • Hello iamhe, thanks for your response. I do not apply the CREDUIWIN_SECURE_PROMPT flag to the call. Passing GENERIC and SECURE_PROMPT results in an exception as well. I have upgraded the machine to SP1 and the issue still occurs. I am thinking this might be a 32/64bit issue. I am currently installing a Win7 32-bit to test, and a Vista 64-bit to test.

    Adam, I did try CREDUIWIN_AUTHPACKAGE_ONLY, no luck. Thanks for the idea though.

    Thanks all,
    ThreeSevenths
    Monday, October 19, 2009 10:11 PM
  • Hello all, sorry to have bothered everyone. I had the signature wrong. Upon further inspection, ulInAuthBufferSize and pulOutAuthBufferSize are 32 bits wide, declared as ulong in C++. In C#, ulong is 64-bits wide. Interestingly, this was okay for the 64bit call, but as expected, broke the 32bit call. The proper signature is
    [DllImport(DLL_CREDUI, EntryPoint = "CredUIPromptForWindowsCredentialsW", CharSet = CharSet.Unicode)]
    public static extern CREDUI_RESULT CredUIPromptForWindowsCredentials(
        ref CREDUI_INFO pUiInfo, 
        uint dwAuthError, 
        ref IntPtr pulAuthPackage, 
        IntPtr pvInAuthBuffer, 
        UInt32 ulInAuthBufferSize, 
        out IntPtr ppvOutAuthBuffer, 
        out UInt32 pulOutAuthBufferSize, 
        ref bool pfSave, 
        CREDUIWIN_FLAGS flags);
    Thanks everyone for your great ideas.
    ThreeSevenths
    • Marked as answer by ThreeSevenths Monday, October 19, 2009 10:48 PM
    Monday, October 19, 2009 10:48 PM