|
|
/*--
Copyright (c) 2000-2001 Microsoft Corporation
Module Name:
creduit.cxx
Abstract:
Test program for the credential manager UI API.
Author:
16-Jan-2001 (cliffv)
Environment:
User mode only. Contains NT-specific code. Requires ANSI C extensions: slash-slash comments, long external names.
Revision History:
--*/
#define UNICODE
#include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <windows.h>
#include <shellapi.h>
#include <wincred.h>
#include <credp.h>
#include <stdio.h>
#include <stdlib.h>
#include <lmerr.h>
#include <align.h>
#define _CREDUI_
#include <wincrui.h>
#include <lmcons.h>
extern "C" { #include <names.h>
#include <rpcutil.h>
} #include <winerror.dbg>
//
// Structure defining a array of parsed strings
//
typedef struct _STRING_ARRAY { BOOLEAN Specified; DWORD Count; #define STRING_ARRAY_COUNT 100
LPWSTR Strings[STRING_ARRAY_COUNT]; } STRING_ARRAY, *PSTRING_ARRAY;
//
// Parsed Parameters
//
LPWSTR CommandLine; DWORD GlCommand = 0xFFFFFFFF;
BOOLEAN GlAnsi; BOOLEAN GlDoGui;
LPWSTR GlUserName; LPWSTR GlTargetName; LPWSTR GlMessage; LPWSTR GlTitle; LPWSTR GlAuthError; DWORD GlCreduiFlags; BOOLEAN GlNoConfirm; BOOL GlSave;
//
// Table of valid parameters to the command.
//
struct _PARAMAMTER_DEF { LPWSTR Name; // Name of the parameter
LPSTR ValueName; // Test describing parameter value
DWORD Type; // Parameter type
#define PARM_COMMAND 1 // Parameter defines a command
#define PARM_COMMAND_STR 2 // Parameter defines a command (and has text string)
#define PARM_COMMAND_OPTSTR 3 // Parameter defines a command (and optionaly has text string)
#define PARM_STRING 4 // Parameter defines a text string
#define PARM_STRING_ENUM 5 // Parameter is an enumeration of text strings
#define PARM_STRING_ARRAY 6 // Parameter is an array of text strings
#define PARM_BOOLEAN 7 // Parameter set a boolean
#define PARM_BIT 8 // Parameter sets a bit in a DWORD
PVOID Global; // Address of global to write
LPWSTR *EnumStrings;
//
// Describe relationships to other parameters.
//
DWORD Relationships; #define ALLOW_CRED 0x01 // If specified, this parameter allows other IS_CRED parameters
#define IS_CRED 0x02 // This parameter is only allow if an ALLOW_CRED parameter has been seen previously
#define ALLOW_TI 0x10 // If specified, this parameter allows other IS_TI or IS_TIX parameters
#define IS_TI 0x20 // This parameter is only allow if an ALLOW_TI parameter has been seen previously
#define IS_TIX 0x40 // This parameter is only allow if an ALLOW_TI parameter has been seen previously
LPSTR Comment; } ParameterDefinitions[] = { {L"UserName", "UserName", PARM_STRING, &GlUserName, NULL, 0, "User Name" }, {L"TargetName", "TargetName", PARM_STRING, &GlTargetName, NULL, 0, "Target Name" }, {L"Message", "Message", PARM_STRING, &GlMessage, NULL, 0, "Message for dialog box" }, {L"Title", "Title", PARM_STRING, &GlTitle, NULL, 0, "Title for dialog box" }, {L"Gui", NULL, PARM_BOOLEAN, &GlDoGui, NULL, 0, "Call GUI version of API" }, {L"Ansi", NULL, PARM_BOOLEAN, &GlAnsi, NULL, 0, "Use ANSI version of APIs" }, { NULL }, {L"ReqSmartcard", (LPSTR)ULongToPtr(CREDUI_FLAGS_REQUIRE_SMARTCARD), PARM_BIT, &GlCreduiFlags, NULL, 0, "Require smartcard" }, {L"ReqCertificate", (LPSTR)ULongToPtr(CREDUI_FLAGS_REQUIRE_CERTIFICATE), PARM_BIT, &GlCreduiFlags, NULL, 0, "Require certificate" }, {L"ExcCertificates",(LPSTR)ULongToPtr(CREDUI_FLAGS_EXCLUDE_CERTIFICATES), PARM_BIT, &GlCreduiFlags, NULL, 0, "Exclude certificates" }, { NULL }, {L"GenericCreds", (LPSTR)ULongToPtr(CREDUI_FLAGS_GENERIC_CREDENTIALS), PARM_BIT, &GlCreduiFlags, NULL, 0, "Generic Credentials" }, {L"RunasCreds", (LPSTR)ULongToPtr(CREDUI_FLAGS_USERNAME_TARGET_CREDENTIALS),PARM_BIT,&GlCreduiFlags, NULL, 0, "Runas Credentials" }, { NULL }, {L"Persist", (LPSTR)ULongToPtr(CREDUI_FLAGS_PERSIST), PARM_BIT, &GlCreduiFlags, NULL, 0, "Always save Credentials" }, {L"NoPersist", (LPSTR)ULongToPtr(CREDUI_FLAGS_DO_NOT_PERSIST), PARM_BIT, &GlCreduiFlags, NULL, 0, "Never save Credentials" }, {L"ShowSaveCheckbox:(T/F)",(LPSTR)ULongToPtr(CREDUI_FLAGS_SHOW_SAVE_CHECK_BOX), PARM_BIT, &GlCreduiFlags, ((LPWSTR *)&GlSave), 0, "Show Save checkbox (initial value)" }, { NULL }, {L"ValidateUsername",(LPSTR)ULongToPtr(CREDUI_FLAGS_VALIDATE_USERNAME), PARM_BIT, &GlCreduiFlags, NULL, 0, "Validate Username" }, {L"CompleteUsername",(LPSTR)ULongToPtr(CREDUI_FLAGS_COMPLETE_USERNAME), PARM_BIT, &GlCreduiFlags, NULL, 0, "Complete Username" }, { NULL }, {L"Confirm", (LPSTR)ULongToPtr(CREDUI_FLAGS_EXPECT_CONFIRMATION), PARM_BIT, &GlCreduiFlags, NULL, 0, "Confirm that the credential worked" }, {L"NoConfirm", NULL, PARM_BOOLEAN,&GlNoConfirm,NULL, 0, "Confirm that the credential failed" }, { NULL }, {L"AlwaysShowUi",(LPSTR)ULongToPtr(CREDUI_FLAGS_ALWAYS_SHOW_UI), PARM_BIT, &GlCreduiFlags, NULL, 0, "Always Show UI" }, {L"IncorrectPassword",(LPSTR)ULongToPtr(CREDUI_FLAGS_INCORRECT_PASSWORD), PARM_BIT, &GlCreduiFlags, NULL, 0, "Show 'incorrect password' tip" }, {L"AuthError", "ErrorNum", PARM_STRING, &GlAuthError, NULL, 0, "Previous auth error number" },
}; #define PARAMETER_COUNT (sizeof(ParameterDefinitions)/sizeof(ParameterDefinitions[0]))
VOID PrintOneUsage( LPWSTR Argument OPTIONAL, ULONG ArgumentIndex ) /*++
Routine Description:
Print the command line parameter usage for one parameter
Arguments:
Argument - Argument as typed by caller NULL if printing complete list of arguments
ArugmentIndex - Index of the parameter to print
Return Value:
None
--*/ { ULONG j;
if ( ParameterDefinitions[ArgumentIndex].Name == NULL ) { fprintf( stderr, "\n" ); return; }
if ( Argument != NULL ) { fprintf( stderr, "\nSyntax of '%ls' parameter is:\n", Argument ); }
fprintf( stderr, " /%ls", ParameterDefinitions[ArgumentIndex].Name );
switch ( ParameterDefinitions[ArgumentIndex].Type ) { case PARM_COMMAND: case PARM_BOOLEAN: break; case PARM_BIT: if ( ParameterDefinitions[ArgumentIndex].EnumStrings == NULL ) { break; } else { fprintf( stderr, ":{T/F}" ); break; } case PARM_COMMAND_OPTSTR: fprintf( stderr, "[:<%s>]", ParameterDefinitions[ArgumentIndex].ValueName ); break; case PARM_STRING: case PARM_COMMAND_STR: fprintf( stderr, ":<%s>", ParameterDefinitions[ArgumentIndex].ValueName ); break; case PARM_STRING_ENUM: fprintf( stderr, ":<" ); for ( j=0; ParameterDefinitions[ArgumentIndex].EnumStrings[j] != NULL; j++) { if ( j!= 0 ) { fprintf( stderr, "|"); } fprintf( stderr, "%ls", ParameterDefinitions[ArgumentIndex].EnumStrings[j] ); } fprintf( stderr, ">" );
break; case PARM_STRING_ARRAY: fprintf( stderr, ":<%s>", ParameterDefinitions[ArgumentIndex].ValueName ); break; }
if ( Argument == NULL ) { fprintf( stderr, " - %s", ParameterDefinitions[ArgumentIndex].Comment ); }
fprintf( stderr, "\n" );
}
VOID PrintUsage( ) /*++
Routine Description:
Print the command line parameter usage.
Arguments:
None
Return Value:
None
--*/ { ULONG i;
fprintf( stderr, "\nUsage: creduit [Options]\n\nWhere options are:\n\n");
for ( i=0; i<PARAMETER_COUNT; i++ ) { PrintOneUsage( NULL, i ); }
}
LPSTR FindSymbolicNameForStatus( DWORD Id ) { ULONG i;
i = 0; if (Id == 0) { return "NO_ERROR"; }
#ifdef notdef
if (Id & 0xC0000000) { while (ntstatusSymbolicNames[ i ].SymbolicName) { if (ntstatusSymbolicNames[ i ].MessageId == (NTSTATUS)Id) { return ntstatusSymbolicNames[ i ].SymbolicName; } else { i += 1; } } } #endif // notdef
while (winerrorSymbolicNames[ i ].SymbolicName) { if (winerrorSymbolicNames[ i ].MessageId == Id) { return winerrorSymbolicNames[ i ].SymbolicName; } else { i += 1; } }
#ifdef notdef
while (neteventSymbolicNames[ i ].SymbolicName) { if (neteventSymbolicNames[ i ].MessageId == Id) { return neteventSymbolicNames[ i ].SymbolicName } else { i += 1; } } #endif // notdef
return NULL; }
VOID PrintStatus( DWORD NetStatus ) /*++
Routine Description:
Print a net status code.
Arguments:
NetStatus - The net status code to print.
Return Value:
None
--*/ { printf( "Status = %lu 0x%lx", NetStatus, NetStatus );
switch (NetStatus) { case NERR_Success: printf( " NERR_Success" ); break;
case NERR_DCNotFound: printf( " NERR_DCNotFound" ); break;
case NERR_UserNotFound: printf( " NERR_UserNotFound" ); break;
case NERR_NetNotStarted: printf( " NERR_NetNotStarted" ); break;
case NERR_WkstaNotStarted: printf( " NERR_WkstaNotStarted" ); break;
case NERR_ServerNotStarted: printf( " NERR_ServerNotStarted" ); break;
case NERR_BrowserNotStarted: printf( " NERR_BrowserNotStarted" ); break;
case NERR_ServiceNotInstalled: printf( " NERR_ServiceNotInstalled" ); break;
case NERR_BadTransactConfig: printf( " NERR_BadTransactConfig" ); break;
default: printf( " %s", FindSymbolicNameForStatus( NetStatus ) ); break;
}
printf( "\n" ); }
VOID PrintBytes( PVOID Buffer, DWORD BufferSize ) /*++
Routine Description:
Dumps the buffer content as hex and characters.
Arguments:
Buffer: buffer pointer.
BufferSize: size of the buffer.
Return Value:
none
--*/ { #define NUM_CHARS 16
DWORD i, limit; CHAR TextBuffer[NUM_CHARS + 1]; LPBYTE BufferPtr = (LPBYTE)Buffer; BOOLEAN DumpDwords = FALSE;
//
// Preprocess
//
if ( BufferSize > NUM_CHARS ) { printf("\n"); // Ensure this starts on a new line
printf("------------------------------------\n"); } else { if ( BufferSize % sizeof(DWORD) == 0 ) { DumpDwords = TRUE; } }
//
// Hex dump of the bytes
//
limit = ((BufferSize - 1) / NUM_CHARS + 1) * NUM_CHARS;
for (i = 0; i < limit; i++) {
if (i < BufferSize) {
if ( DumpDwords ) { if ( i % sizeof(DWORD) == 0 ) { DWORD ADword; RtlCopyMemory( &ADword, &BufferPtr[i], sizeof(DWORD) ); printf("%08x ", ADword); } } else { printf("%02x ", BufferPtr[i]); }
if ( isprint(BufferPtr[i]) ) { TextBuffer[i % NUM_CHARS] = (CHAR) BufferPtr[i]; } else { TextBuffer[i % NUM_CHARS] = '.'; }
} else {
if ( DumpDwords ) { TextBuffer[i % NUM_CHARS] = '\0'; } else { if ( BufferSize > NUM_CHARS ) { printf(" "); TextBuffer[i % NUM_CHARS] = ' '; } else { TextBuffer[i % NUM_CHARS] = '\0'; } }
}
if ((i + 1) % NUM_CHARS == 0) { TextBuffer[NUM_CHARS] = 0; printf(" %s\n", TextBuffer); }
}
if ( BufferSize > NUM_CHARS ) { printf("------------------------------------\n"); } else if ( BufferSize < NUM_CHARS ) { printf("\n"); } }
VOID PrintTime( LPSTR Comment, LPFILETIME ConvertTime ) /*++
Routine Description:
Print the specified time
Arguments:
Comment - Comment to print in front of the time
Time - GMT time to print (Nothing is printed if this is zero)
Return Value:
None
--*/ { //
// If we've been asked to convert an NT GMT time to ascii,
// Do so
//
if ( ConvertTime->dwLowDateTime != 0 || ConvertTime->dwHighDateTime != 0 ) { SYSTEMTIME SystemTime; FILETIME LocalFileTime;
printf( "%s", Comment );
if ( !FileTimeToLocalFileTime( ConvertTime, &LocalFileTime ) ) { printf( "Can't convert time from GMT to Local time: " ); PrintStatus( GetLastError() ); return; }
if ( !FileTimeToSystemTime( &LocalFileTime, &SystemTime ) ) { printf( "Can't convert time from file time to system time: " ); PrintStatus( GetLastError() ); return; }
printf( "%ld/%ld/%ld %ld:%2.2ld:%2.2ld\n", SystemTime.wMonth, SystemTime.wDay, SystemTime.wYear, SystemTime.wHour, SystemTime.wMinute, SystemTime.wSecond ); } }
BOOLEAN ParseParameters( VOID ) /*++
Routine Description:
Parse the command line parameters
Arguments:
None
Return Value:
TRUE if parse was successful.
--*/ { LPWSTR *argvw; int argcw; int i; ULONG j;
LPWSTR OrigArgument; LPWSTR Argument;
//
// Get the command line in Unicode
//
CommandLine = GetCommandLine();
argvw = CommandLineToArgvW( CommandLine, &argcw );
if ( argvw == NULL ) { fprintf( stderr, "Can't convert command line to Unicode: %ld\n", GetLastError() );
return FALSE; }
//
// Loop through the command line arguments
//
for ( i=1; i<argcw; i++ ) {
OrigArgument = Argument = argvw[i];
//
// Check if the Argument is a switch
//
if ( Argument[0] == '-' || Argument[0] == '/' ) { DWORD ArgumentIndex; ULONG ArgumentLength; PWCHAR ColonPointer; Argument ++;
//
// Find the colon at the end of the argument
//
ColonPointer = wcschr( Argument, L':' ); if ( ColonPointer != NULL ) { *ColonPointer = '\0'; } ArgumentLength = wcslen(Argument);
//
// Loop through the list of valid arguments finding all that match
//
ArgumentIndex = 0xFFFFFFFF; for ( j=0; j<PARAMETER_COUNT; j++ ) {
//
// Ignore placeholders
//
if ( ParameterDefinitions[j].Name == NULL ) { continue; }
//
// Compare the names
//
if ( _wcsnicmp( Argument, ParameterDefinitions[j].Name, ArgumentLength ) == 0 ) { //
// If more than one matches,
// it's an error
//
if ( ArgumentIndex != 0xFFFFFFFF ) { fprintf( stderr, "\nArgument '%ls' is ambiguous: %ls or %ls.\n", OrigArgument, ParameterDefinitions[j].Name, ParameterDefinitions[ArgumentIndex].Name );
return FALSE; }
ArgumentIndex = j;
//
// If this is an exact match,
// we're done.
//
if ( ArgumentLength == wcslen(ParameterDefinitions[j].Name)) { break; } } }
//
// If there were not matches,
// complain.
//
if ( ArgumentIndex == 0xFFFFFFFF ) { fprintf( stderr, "\nArgument '%ls' is invalid.\n", OrigArgument ); PrintUsage(); return FALSE; }
//
// Ensure the : is present as required
//
//
// Return TRUE if the specified argument should have a : character after the
// argument name.
//
if ( ParameterDefinitions[ArgumentIndex].Type == PARM_COMMAND || ParameterDefinitions[ArgumentIndex].Type == PARM_BOOLEAN || (ParameterDefinitions[ArgumentIndex].Type == PARM_BIT && ParameterDefinitions[ArgumentIndex].EnumStrings == NULL ) ) {
if ( ColonPointer != NULL ) { PrintOneUsage( OrigArgument, ArgumentIndex ); return FALSE; }
} else {
if ( ColonPointer == NULL ) { if ( ParameterDefinitions[ArgumentIndex].Type != PARM_COMMAND_OPTSTR ) { PrintOneUsage( OrigArgument, ArgumentIndex ); return FALSE; } } else { Argument = ColonPointer + 1; }
}
//
// Parse the rest of the argument
//
// Handle commands
//
switch ( ParameterDefinitions[ArgumentIndex].Type ) { case PARM_COMMAND: case PARM_COMMAND_STR: case PARM_COMMAND_OPTSTR: if ( GlCommand != 0xFFFFFFFF ) { fprintf( stderr, "\nArgument '%ls' and '/%ls' are mutually exclusive.\n", OrigArgument, ParameterDefinitions[GlCommand].Name );
return FALSE; } GlCommand = ArgumentIndex;
/* Drop through */
//
// Handle parameters of the form /xxx:string
//
case PARM_STRING: { LPWSTR *StringPointer; StringPointer = (LPWSTR *)(ParameterDefinitions[ArgumentIndex].Global);
//
// If a string is not present,
// we're done.
//
if ( ColonPointer == NULL ) { break; }
//
// Ensure argument only specified once.
//
if ( *StringPointer != NULL ) { fprintf( stderr, "\nArgument '%ls' may only be specified once.\n", OrigArgument );
return FALSE;
}
//
// Ensure an actual string was specified.
//
if ( *Argument == '\0' ) { fprintf( stderr, "\nArgument '%ls' requires a value.\n", OrigArgument );
return FALSE; }
*StringPointer = Argument; break; }
//
// Handle parameters of the form /xxx:a|b|c
//
case PARM_STRING_ENUM: { ULONG EnumIndex; LPDWORD DwordPointer; LPWSTR *EnumStrings;
//
// Ensure argument only specified once.
//
DwordPointer = (LPDWORD)(ParameterDefinitions[ArgumentIndex].Global);
if ( *DwordPointer != 0 ) { fprintf( stderr, "\nArgument '%ls' may only be specified once.\n", OrigArgument );
return FALSE;
}
EnumStrings = ParameterDefinitions[ArgumentIndex].EnumStrings; ArgumentLength = wcslen(Argument);
//
// Loop through the list of valid values finding all that match
//
EnumIndex = 0xFFFFFFFF; for ( j=0; EnumStrings[j] != NULL; j++ ) {
//
// Compare the names
//
if ( _wcsnicmp( Argument, EnumStrings[j], ArgumentLength ) == 0 ) {
//
// If more than one matches,
// it's an error
//
if ( EnumIndex != 0xFFFFFFFF ) {
PrintOneUsage( OrigArgument, ArgumentIndex );
fprintf( stderr, "\nValue '%ls' is ambiguous: %ls or %ls.\n", Argument, EnumStrings[j], EnumStrings[EnumIndex] );
return FALSE; }
EnumIndex = j;
//
// If this is an exact match,
// we're done.
//
if ( ArgumentLength == wcslen(EnumStrings[j]) ) { break; } } }
//
// If there were not matches,
// complain.
//
if ( EnumIndex == 0xFFFFFFFF ) {
PrintOneUsage( OrigArgument, ArgumentIndex );
fprintf( stderr, "\nValue '%ls' is invalid.\n", Argument );
return FALSE; } *DwordPointer = EnumIndex + 1; break; }
//
// Handle parameters of the form /xxx:a,b,c
//
case PARM_STRING_ARRAY: { PWCHAR CommaPointer; PSTRING_ARRAY StringArray;
StringArray = ((PSTRING_ARRAY)(ParameterDefinitions[ArgumentIndex].Global));
//
// Ensure argument only specified once.
//
if ( StringArray->Specified ) { fprintf( stderr, "\nArgument '%ls' may only be specified once.\n", OrigArgument );
return FALSE;
} StringArray->Specified = TRUE;
//
// Loop through the values specified by the user
//
for (;;) {
//
// Ensure an actual string was specified.
//
if ( *Argument == '\0' ) { fprintf( stderr, "\nArgument '%ls' requires a value.\n", OrigArgument );
return FALSE; }
//
// Save it
//
StringArray->Count ++;
if ( StringArray->Count >= STRING_ARRAY_COUNT ) { fprintf( stderr, "\nArgument '%ls' has too many values.\n", OrigArgument );
return FALSE; }
StringArray->Strings[StringArray->Count-1] = Argument;
//
// Determine if there is another value
//
CommaPointer = wcschr( Argument, L',' ); if ( CommaPointer == NULL ) { break; }
*CommaPointer = '\0'; Argument = CommaPointer + 1;
};
break; }
//
// Handle parameters of the form /xxx
//
case PARM_BOOLEAN: { BOOLEAN *BooleanPointer; BooleanPointer = (BOOLEAN *)(ParameterDefinitions[ArgumentIndex].Global);
*BooleanPointer = TRUE; break; }
//
// Handle parameters of the form /xxx that imply setting a bit
//
case PARM_BIT: { DWORD *DwordPointer; DwordPointer = (DWORD *)(ParameterDefinitions[ArgumentIndex].Global);
*DwordPointer |= PtrToUlong( ParameterDefinitions[ArgumentIndex].ValueName );
//
// Some of these have TRUE or FALSE as an optional argument
//
if ( ParameterDefinitions[ArgumentIndex].EnumStrings != NULL ) { if ( toupper(*Argument) == 'T' ) { *((BOOL *)(ParameterDefinitions[ArgumentIndex].EnumStrings)) = TRUE; } else if ( toupper(*Argument) == 'F' ) { *((BOOL *)(ParameterDefinitions[ArgumentIndex].EnumStrings)) = FALSE; } else { fprintf( stderr, "\nArgument '%ls' requires a T or F as value.\n", OrigArgument );
return FALSE; } } break; }
default: fprintf( stderr, "\nArgument '%ls' had an internal error.\n", OrigArgument ); return FALSE;
}
//
// Handle arguments that aren't switches.
//
} else {
//
// All current arguments are switches
//
PrintUsage(); return FALSE;
}
}
return TRUE; }
//
// Include routines to support the /ANSI parameter
//
LPSTR NetpAllocAStrFromWStr ( IN LPCWSTR Unicode )
/*++
Routine Description:
Convert an UNICODE (zero terminated) string to the corresponding ANSI string.
Arguments:
Unicode - Specifies the UNICODE zero terminated string to convert.
Return Value:
NULL - There was some error in the conversion.
Otherwise, it returns a pointer to the zero terminated ANSI string in an allocated buffer. The buffer must be freed using NetApiBufferFree.
--*/
{ ANSI_STRING AnsiString; UNICODE_STRING UnicodeString;
RtlInitUnicodeString( &UnicodeString, Unicode );
AnsiString.MaximumLength = (USHORT) RtlUnicodeStringToAnsiSize( &UnicodeString );
AnsiString.Buffer = (PCHAR) LocalAlloc( 0, AnsiString.MaximumLength );
if ( AnsiString.Buffer == NULL) { return (NULL); }
if(!NT_SUCCESS( RtlUnicodeStringToAnsiString( &AnsiString, &UnicodeString, FALSE))){ (void) LocalFree( AnsiString.Buffer ); return NULL; }
return AnsiString.Buffer;
} // NetpAllocStrFromWStr
extern "C" BOOL DllMain( HINSTANCE instance, DWORD reason, VOID * );
int __cdecl main( IN int argc, IN char ** argv ) /*++
Routine Description:
Drive the credential manager API.
Arguments:
argc - the number of command-line arguments.
argv - an array of pointers to the arguments.
Return Value:
Exit status
--*/ { DWORD WinStatus; WCHAR Password[CREDUI_MAX_PASSWORD_LENGTH + 1]; WCHAR UserName[CREDUI_MAX_USERNAME_LENGTH + 1]; DWORD AuthError = NO_ERROR; CREDUI_INFOW UiInfoW; PCREDUI_INFOW UiInfoWptr = NULL;
//
// Parse the command line parameters
//
UserName[0] = '\0'; Password[0] = '\0';
if ( !ParseParameters() ) { return 1; }
//
// Fill in the parameters
//
if ( GlUserName != NULL) { wcscpy( UserName, GlUserName ); }
//
// Get the error number
//
if ( GlAuthError != NULL ) { LPWSTR End;
AuthError = wcstoul( GlAuthError, &End, 10 ); }
//
// Handle special parameters
//
if ( GlNoConfirm ) { GlCreduiFlags |= CREDUI_FLAGS_EXPECT_CONFIRMATION; }
//
// Build the UI info
//
if ( GlMessage || GlTitle ) { UiInfoWptr = &UiInfoW;
ZeroMemory( &UiInfoW, sizeof(UiInfoW) );
UiInfoW.cbSize = sizeof(UiInfoW); UiInfoW.pszMessageText = GlMessage; UiInfoW.pszCaptionText = GlTitle; }
//
// Execute the requested command
//
switch ( GlCommand ) { case 0xFFFFFFFF: if ( GlAnsi ) { printf( "We don't yet do ansi.\n"); } else {
if ( GlDoGui ) { WinStatus = CredUIPromptForCredentialsW( UiInfoWptr, GlTargetName, NULL, // No security context
AuthError, UserName, sizeof(UserName)/sizeof(WCHAR), Password, sizeof(Password)/sizeof(WCHAR), &GlSave, GlCreduiFlags ); } else { WinStatus = CredUICmdLinePromptForCredentialsW( GlTargetName, NULL, // No security context
AuthError, UserName, sizeof(UserName)/sizeof(WCHAR), Password, sizeof(Password)/sizeof(WCHAR), &GlSave, GlCreduiFlags );
}
if ( WinStatus != NO_ERROR ) { fprintf( stderr, "CredUIPromptForCredentialsW failed: \n" ); PrintStatus( WinStatus ); return 1; }
printf( "UserName: '%ws'\n", UserName ); printf( "Password: '%ws'\n", Password ); printf( "Save: %ld\n", GlSave );
//
// Do confirmation
//
if ( GlCreduiFlags & CREDUI_FLAGS_EXPECT_CONFIRMATION ) {
WinStatus = CredUIConfirmCredentialsW( GlTargetName, !GlNoConfirm );
if ( WinStatus != NO_ERROR ) { fprintf( stderr, "CredUIConfirmCredentialsW failed: \n" ); PrintStatus( WinStatus ); }
} } break;
default: fprintf( stderr, "Internal error: %ld\n", GlCommand ); return 1; }
fprintf( stderr, "Command completed successfully.\n" ); return 0; }
|