Sorry, I should have been more specific in my first post.
As previously mentioned, I have downloaded and have been playing around with the PasswordFilters sample which is found in the Microsoft Platform SDK.
I would like to modify this function to allow for a minimum of 1 letter (a-zA-Z) or 1 special character (#,$,@,_) AND 1 number. The letters and numbers are not a problem. It is detecting the 4 special characters which I am having problems with.
GetStringTypeW is used to get the character type from a PUNICODE_STRING. If the type is NOT C1_ALPHA or C1_DIGIT, we would like to look at the actual character value (from PUNICODE_STRING) to determine if it is one of (#,$,@,_). If it is NOT any of these characters, then an invalid character has been entered and we would break out of the loop and return FALSE to indicate an invalid password.
Any other suggestions?
The full function (unedited) is:
Code:
BOOL
NTAPI
PasswordFilter(
PUNICODE_STRING UserName,
PUNICODE_STRING FullName,
PUNICODE_STRING Password,
BOOL SetOperation
)
/*++
Routine Description:
This (optional) routine is notified of a password change.
Arguments:
UserName - Name of user whose password changed
FullName - Full name of the user whose password changed
NewPassword - Cleartext new password for the user
SetOperation - TRUE if the password was SET rather than CHANGED
Return Value:
TRUE if the specified Password is suitable (complex, long, etc).
The system will continue to evaluate the password update request
through any other installed password change packages.
FALSE if the specified Password is unsuitable. The password change
on the specified account will fail.
--*/
{
BOOL bComplex = FALSE; // assume the password in not complex enough
DWORD cchPassword;
PWORD CharType;
DWORD i;
DWORD dwNum = 0;
DWORD dwUpper = 0;
DWORD dwLower = 0;
//
// check if the password is complex enough for our liking by
// checking that at least two of the four character types are
// present.
//
CharType = HeapAlloc(GetProcessHeap(), 0, Password->Length);
if (CharType == NULL) return FALSE;
cchPassword = Password->Length / sizeof(WCHAR);
if (GetStringTypeW(
CT_CTYPE1,
Password->Buffer,
cchPassword,
CharType
))
{
for (i = 0 ; i < cchPassword ; i++)
{
//
// keep track of what type of characters we have encountered
//
if (CharType[i] & C1_DIGIT)
{
dwNum = 1;
continue;
}
if (CharType[i] & C1_UPPER)
{
dwUpper = 1;
continue;
}
if (CharType[i] & C1_LOWER)
{
dwLower = 1;
continue;
}
if (!(CharType[i] & (C1_ALPHA | C1_DIGIT) ))
{
//
// any other character types make the password complex
//
dwNum = 2;
break;
}
} // for
//
// Indicate whether we encountered enough password complexity
//
if ( (dwNum + dwUpper + dwLower) >= 2 )
bComplex = TRUE;
ZeroMemory( CharType, Password->Length );
} // if
HeapFree(GetProcessHeap(), 0, CharType);
return bComplex;
}
Thanks,
Jody