2008-10-31 9 views
3

En réponse à la question this j'espère que quelqu'un peut aider avec l'API CredEnumerate.Aide avec CredEnumerate

D'après ce que je comprends de la documentation, le paramètre PCREDENTIALS out est un "pointeur vers un tableau de pointeurs vers des informations d'identification". Je suis capable d'appeler l'API CredEnumerate en utilisant C#, mais je ne suis pas sûr de savoir comment convertir les PCREDENTIALS en quelque chose d'utile (comme une liste d'informations d'identification).

Edit: Voici le code que je utilise:

 int count = 0; 
     IntPtr pCredentials = IntPtr.Zero; 
     bool ret = false; 
     ret = CredEnumerate(null, 0, out count, out pCredentials); 
     if (ret != false) 
     { 
      IntPtr[] credentials = new IntPtr[count]; 
      IntPtr p = pCredentials; 
      for (int i = 0; i < count; i++) 
      { 
       p = new IntPtr(p.ToInt32() + i); 
       credentials[i] = Marshal.ReadIntPtr(p); 
      } 
      List<Credential> creds = new List<Credential>(credentials.Length); 
      foreach (IntPtr ptr in credentials) 
      { 
       creds.Add((Credential)Marshal.PtrToStructure(ptr, typeof(Credential))); 
      } 
     } 

Malheureusement, alors que cela fonctionne pour la première lettres de créance dans le tableau-il est généré et ajouté à la liste des éléments du tableau correctement-après la bombe au maréchal. PtrToStructure avec l'erreur suivante:

Vous avez tenté de lire ou d'écrire de la mémoire protégée. C'est souvent une indication que l'autre mémoire est corrompue.

Des idées? N'importe qui? Bueller?

Répondre

5

Vous devez déréférencer le pointeur sur le tableau pour obtenir le tableau, puis pour chaque élément du tableau, vous devrez déréférencer l'élément pour obtenir l'instance PCREDENTIALS.

Je trouve this post with some example code pour effectuer ce que vous voulez faire:

[DllImport("advapi32", SetLastError = true, CharSet=CharSet.Unicode)] 
static extern bool CredEnumerate(string filter, int flag, out int count, out IntPtr 
pCredentials); 

...

int count = 0; 
IntPtr pCredentials = IntPtr.Zero; 
IntPtr[] credentials = null; 
bool ret = CredEnumerate(null, 0, out count, out pCredentials); 
if (ret != false) 
{ 
    credentials = new IntPtr[count]; 
    IntPtr p = pCredentials; 
    for (int n = 0; n < count; n++) 
    { 
     credentials[n] = Marshal.ReadIntPtr(pCredentials, 
      n * Marshal.SizeOf(typeof(IntPtr))); 
    } 
} 
else 
// failed.... 

Ensuite, pour chaque pointeur que vous aurez besoin d'utiliser Marshal.PtrToStructure pour déréférencer le pointeur dans un PCREDENTIALS struct instance (désolé je ne trouve pas le typedef pour PCREDENTIALS n'importe où, je suppose que vous l'avez - et si vous ne l'oubliez pas les attributs MarshalAs et l'attribut StructLayout corrects lorsque vous le définissez):

// assuming you have declared struct PCREDENTIALS 
var creds = new List<PCREDENTIALS>(credentials.Length); 
foreach (var ptr in credentials) 
{ 
    creds.Add((PCREDENTIALS)Marshal.PtrToStructure(ptr, typeof(PCREDENTIALS))); 
} 

Vous devrez évidemment combiner l'exemple et PtrToStructure code pour des résultats optimaux, mais je voulais quitter l'intégrité de l'exemple intact.

+1

La structure PCREDENTIAL sera probablement ceci: http://msdn.microsoft.com/en-us/library/aa374788(v = vs.85) .aspx –

+0

La définition de 'p = new IntPtr (p.ToIntNN() + n)' signifie que le décalage du tableau saute de plus en plus vite. Mieux vaut remplacer l'ensemble de la boucle interne par credentials [n] = Marshal.ReadIntPtr (pCredentials, n * Marshal.SizeOf (typeof (IntPtr))); ' – Brian

+0

Oui cela fait plus de sens, mettra à jour. – cfeduke

1

Vous devez également calculer 'IntPtr p' correctement le code ci-dessus est manquant cela et il ira seulement chercher la 1ère structure.

Th code suivant obtenir toutes les structures 'IntPtr pCredentials de

int count; 
IntPtr pCredentials; 

if (CredEnumerate(filter, 0, out count, out pCredentials) != 0) 
{ 
    m_list = new List<PCREDENTIALS >(count); 
    int sz = Marshal.SizeOf(pCredentials); 

    for (int index = 0; index < count; index++) 
    { 
     IntPtr p = new IntPtr((sz == 4 ? pCredentials.ToInt32() : pCredentials.ToInt64()) + index * sz); 
     m_list.Add((PCREDENTIALS)Marshal.PtrToStructure(p, typeof(PCREDENTIALS))); 
    } 
}