この件名はこことここの前に提起されており、指示に従ったと思いますが、lastError が 0 の間、パスワードの一部がまだリセットされていません。私のコードは次のとおりです。
namespace ResetCredentials
{
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text;
using NDesk.Options;
using FILETIME = System.Runtime.InteropServices.ComTypes.FILETIME;
internal class Program
{
public enum CredPersist : uint
{
Session = 1,
LocalMachine = 2,
Enterprise = 3,
}
public enum CredType : uint
{
Generic = 1,
DomainPassword = 2,
DomainCertificate = 3,
DomainVisiblePassword = 4,
GenericCertificate = 5,
DomainExtended = 6,
Maximum = 7, // Maximum supported cred type
MaximumEx = (Maximum + 1000), // Allow new applications to run on old OSes
}
[DllImport("advapi32", SetLastError = true, CharSet = CharSet.Unicode)]
private static extern bool CredEnumerate(
string filter, int flag, out int count, out IntPtr pCredentials);
[DllImport("Advapi32.dll", EntryPoint = "CredReadW", CharSet = CharSet.Unicode, SetLastError = true)]
private static extern bool CredRead(
string target, uint type, int reservedFlag, out IntPtr credentialPtr);
[DllImport("Advapi32.dll", EntryPoint = "CredWriteW", CharSet = CharSet.Unicode, SetLastError = true)]
private static extern bool CredWrite(
[In] ref Credential userCredential, [In] UInt32 flags);
private static void DisplayUsage(OptionSet options)
{
Console.WriteLine("Usage: ResetCredentials.exe");
options.WriteOptionDescriptions(Console.Out);
}
private static void Main(string[] args)
{
string newPass = String.Empty;
string user = String.Empty;
OptionSet options = new OptionSet().Add("u=|user=", s
=> user = s).Add("n=|newPass=", s => newPass = s);
options.Parse(args);
if (String.IsNullOrWhiteSpace(user) || String.IsNullOrWhiteSpace(newPass))
{
DisplayUsage(options);
return;
}
int count;
IntPtr pCredentials;
bool ret = CredEnumerate(null, 0, out count, out pCredentials);
if (ret)
{
var credentials = new IntPtr[count];
for (int n = 0; n < count; n++)
credentials[n] = Marshal.ReadIntPtr(
pCredentials, n * Marshal.SizeOf(typeof(IntPtr)));
var creds = new List<Credential>(credentials.Length);
foreach (IntPtr ptr in credentials)
{
var credential = (Credential)Marshal.PtrToStructure(ptr, typeof(Credential));
creds.Add(credential);
if (credential.userName.Equals(
user, StringComparison.InvariantCultureIgnoreCase))
{
IntPtr ptr1;
bool b1 = CredRead(credential.targetName, credential.type, 0, out ptr1);
int lastError = Marshal.GetLastWin32Error();
if (b1 && lastError == 0)
{
string currentPass = String.Empty;
if (credential.credentialBlobSize > 0)
{
currentPass = Marshal.PtrToStringUni(credential.credentialBlob);
lastError = Marshal.GetLastWin32Error();
}
if (lastError == 0 && currentPass != null)
{
if (!currentPass.Equals(
newPass, StringComparison.InvariantCultureIgnoreCase))
{
credential.credentialBlobSize
= (UInt32)Encoding.Unicode.GetBytes(newPass).Length;
credential.credentialBlob
= Marshal.StringToCoTaskMemUni(newPass);
CredWrite(ref credential, 0);
lastError = Marshal.GetLastWin32Error();
Console.WriteLine(lastError == 0
? "Token: {0} password changed"
: "Could not reset password for {0}",
credential.targetName);
}
}
else
Console.WriteLine(
"Could not retrieve password for {0}", credential.targetName);
}
else
Trace.WriteLine("Error: " + lastError);
}
}
}
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
private struct Credential
{
public readonly UInt32 flags;
public readonly UInt32 type;
public readonly string targetName;
public readonly string comment;
public readonly FILETIME lastWritten;
public UInt32 credentialBlobSize;
public IntPtr credentialBlob;
public readonly UInt32 persist;
public readonly UInt32 attributeCount;
public readonly IntPtr credAttribute;
public readonly string targetAlias;
public readonly string userName;
}
}
}
私は何が間違っているのでしょうか?