2

这个主题已经在这里这里之前提出过,虽然我认为我按照说明进行操作,但我的一些密码仍然没有被重置,而 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;
    }
  }
}

我可能做错了什么?

4

0 回答 0