[pkg-wine-party] [SCM] Debian Wine packaging branch, wheezy, updated. wine-1.4-7-302-gb61b690

Alexandre Julliard julliard at winehq.org
Sun Jun 17 20:01:08 UTC 2012


The following commit has been merged in the wheezy branch:
commit b4331372bf4fb3409dd1a0cf88c2f58c68f320cb
Author: Hans Leidekker <hans at codeweavers.com>
Date:   Thu Mar 8 20:27:37 2012 +0100

    advapi32: Implement CredMarshalCredential and CredUnmarshalCredential.
    (cherry picked from commit d5d2f01d3e8ed076ecf8f990210454047817fb72)

diff --git a/dlls/advapi32/advapi32.spec b/dlls/advapi32/advapi32.spec
index 5bf0a02..2b5db2b 100644
--- a/dlls/advapi32/advapi32.spec
+++ b/dlls/advapi32/advapi32.spec
@@ -148,8 +148,8 @@
 # @ stub CredIsMarshaledCredentialW
 # @ stub CredIsProtectedA
 # @ stub CredIsProtectedW
-# @ stub CredMarshalCredentialA
-# @ stub CredMarshalCredentialW
+@ stdcall CredMarshalCredentialA(long ptr ptr)
+@ stdcall CredMarshalCredentialW(long ptr ptr)
 # @ stub CredpConvertOneCredentialSize
 # @ stub CredpEncodeSecret
 @ stub CredProfileLoaded
@@ -164,8 +164,8 @@
 # @ stub CredRenameA
 # @ stub CredRenameW
 # @ stub CredRestoreCredentials
-# @ stub CredUnmarshalCredentialA
-# @ stub CredUnmarshalCredentialW
+@ stdcall CredUnmarshalCredentialA(str ptr ptr)
+@ stdcall CredUnmarshalCredentialW(wstr ptr ptr)
 # @ stub CredUnprotectA
 # @ stub CredUnprotectW
 @ stdcall CredWriteA(ptr long)
diff --git a/dlls/advapi32/cred.c b/dlls/advapi32/cred.c
index c7af18b..432eb5c 100644
--- a/dlls/advapi32/cred.c
+++ b/dlls/advapi32/cred.c
@@ -1900,3 +1900,264 @@ WINADVAPI BOOL WINAPI CredGetSessionTypes(DWORD persistCount, LPDWORD persists)
     }
     return TRUE;
 }
+
+/******************************************************************************
+ * CredMarshalCredentialA [ADVAPI32.@]
+ */
+BOOL WINAPI CredMarshalCredentialA( CRED_MARSHAL_TYPE type, PVOID cred, LPSTR *out )
+{
+    BOOL ret;
+    WCHAR *outW;
+
+    TRACE("%u, %p, %p\n", type, cred, out);
+
+    if ((ret = CredMarshalCredentialW( type, cred, &outW )))
+    {
+        int len = WideCharToMultiByte( CP_ACP, 0, outW, -1, NULL, 0, NULL, NULL );
+        if (!(*out = HeapAlloc( GetProcessHeap(), 0, len )))
+        {
+            HeapFree( GetProcessHeap(), 0, outW );
+            return FALSE;
+        }
+        WideCharToMultiByte( CP_ACP, 0, outW, -1, *out, len, NULL, NULL );
+        HeapFree( GetProcessHeap(), 0, outW );
+    }
+    return ret;
+}
+
+static UINT cred_encode( const char *bin, unsigned int len, WCHAR *cred )
+{
+    static char enc[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789#-";
+    UINT n = 0, x;
+
+    while (len > 0)
+    {
+        cred[n++] = enc[bin[0] & 0x3f];
+        x = (bin[0] & 0xc0) >> 6;
+        if (len == 1)
+        {
+            cred[n++] = enc[x];
+            break;
+        }
+        cred[n++] = enc[((bin[1] & 0xf) << 2) | x];
+        x = (bin[1] & 0xf0) >> 4;
+        if (len == 2)
+        {
+            cred[n++] = enc[x];
+            break;
+        }
+        cred[n++] = enc[((bin[2] & 0x3) << 4) | x];
+        cred[n++] = enc[(bin[2] & 0xfc) >> 2];
+        bin += 3;
+        len -= 3;
+    }
+    return n;
+}
+
+/******************************************************************************
+ * CredMarshalCredentialW [ADVAPI32.@]
+ */
+BOOL WINAPI CredMarshalCredentialW( CRED_MARSHAL_TYPE type, PVOID cred, LPWSTR *out )
+{
+    CERT_CREDENTIAL_INFO *cert = cred;
+    USERNAME_TARGET_CREDENTIAL_INFO *target = cred;
+    DWORD len, size;
+    WCHAR *p;
+
+    TRACE("%u, %p, %p\n", type, cred, out);
+
+    if (!cred || (type == CertCredential && cert->cbSize < sizeof(*cert)) ||
+        (type != CertCredential && type != UsernameTargetCredential && type != BinaryBlobCredential) ||
+        (type == UsernameTargetCredential && (!target->UserName || !target->UserName[0])))
+    {
+        SetLastError( ERROR_INVALID_PARAMETER );
+        return FALSE;
+    }
+    switch (type)
+    {
+    case CertCredential:
+    {
+        char hash[CERT_HASH_LENGTH + 2];
+
+        memcpy( hash, cert->rgbHashOfCert, sizeof(cert->rgbHashOfCert) );
+        memset( hash + sizeof(cert->rgbHashOfCert), 0, sizeof(hash) - sizeof(cert->rgbHashOfCert) );
+
+        size = sizeof(hash) * 4 / 3;
+        if (!(p = HeapAlloc( GetProcessHeap(), 0, (size + 4) * sizeof(WCHAR) ))) return FALSE;
+        p[0] = '@';
+        p[1] = '@';
+        p[2] = 'A' + type;
+        len = cred_encode( (const char *)hash, sizeof(hash), p + 3 );
+        p[len] = 0;
+        break;
+    }
+    case UsernameTargetCredential:
+    {
+        len = strlenW( target->UserName );
+        size = (sizeof(DWORD) + len * sizeof(WCHAR) + 2) * 4 / 3;
+        if (!(p = HeapAlloc( GetProcessHeap(), 0, (size + 4) * sizeof(WCHAR) ))) return FALSE;
+        p[0] = '@';
+        p[1] = '@';
+        p[2] = 'A' + type;
+        size = len * sizeof(WCHAR);
+        len = cred_encode( (const char *)&size, sizeof(DWORD), p + 3 );
+        len += cred_encode( (const char *)target->UserName, size, p + 3 + len );
+        p[len + 3] = 0;
+        break;
+    }
+    case BinaryBlobCredential:
+        FIXME("BinaryBlobCredential not implemented\n");
+        return FALSE;
+    default:
+        return FALSE;
+    }
+    *out = p;
+    return TRUE;
+}
+
+/******************************************************************************
+ * CredUnmarshalCredentialA [ADVAPI32.@]
+ */
+BOOL WINAPI CredUnmarshalCredentialA( LPCSTR cred, PCRED_MARSHAL_TYPE type, PVOID *out )
+{
+    BOOL ret;
+    WCHAR *credW = NULL;
+
+    TRACE("%s, %p, %p\n", debugstr_a(cred), type, out);
+
+    if (cred)
+    {
+        int len = MultiByteToWideChar( CP_ACP, 0, cred, -1, NULL, 0 );
+        if (!(credW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) return FALSE;
+        MultiByteToWideChar( CP_ACP, 0, cred, -1, credW, len );
+    }
+    ret = CredUnmarshalCredentialW( credW, type, out );
+    HeapFree( GetProcessHeap(), 0, credW );
+    return ret;
+}
+
+static inline char char_decode( WCHAR c )
+{
+    if (c >= 'A' && c <= 'Z') return c - 'A';
+    if (c >= 'a' && c <= 'z') return c - 'a' + 26;
+    if (c >= '0' && c <= '9') return c - '0' + 52;
+    if (c == '#') return 62;
+    if (c == '-') return 63;
+    return 64;
+}
+
+static BOOL cred_decode( const WCHAR *cred, unsigned int len, char *buf )
+{
+    unsigned int i = 0;
+    char c0, c1, c2, c3;
+    const WCHAR *p = cred;
+
+    while (len >= 4)
+    {
+        if ((c0 = char_decode( p[0] )) > 63) return FALSE;
+        if ((c1 = char_decode( p[1] )) > 63) return FALSE;
+        if ((c2 = char_decode( p[2] )) > 63) return FALSE;
+        if ((c3 = char_decode( p[3] )) > 63) return FALSE;
+
+        buf[i + 0] = (c1 << 6) | c0;
+        buf[i + 1] = (c2 << 4) | (c1 >> 2);
+        buf[i + 2] = (c3 << 2) | (c2 >> 4);
+        len -= 4;
+        i += 3;
+        p += 4;
+    }
+    if (len == 3)
+    {
+        if ((c0 = char_decode( p[0] )) > 63) return FALSE;
+        if ((c1 = char_decode( p[1] )) > 63) return FALSE;
+        if ((c2 = char_decode( p[2] )) > 63) return FALSE;
+
+        buf[i + 0] = (c1 << 6) | c0;
+        buf[i + 1] = (c2 << 4) | (c1 >> 2);
+        buf[i + 2] = c2 >> 4;
+    }
+    else if (len == 2)
+    {
+        if ((c0 = char_decode( p[0] )) > 63) return FALSE;
+        if ((c1 = char_decode( p[1] )) > 63) return FALSE;
+
+        buf[i + 0] = (c1 << 6) | c0;
+        buf[i + 1] = c1 >> 2;
+        buf[i + 2] = 0;
+    }
+    else if (len == 1)
+    {
+        if ((c0 = char_decode( p[0] )) > 63) return FALSE;
+
+        buf[i + 0] = c0;
+        buf[i + 1] = 0;
+        buf[i + 2] = 0;
+    }
+    return TRUE;
+}
+
+/******************************************************************************
+ * CredUnmarshalCredentialW [ADVAPI32.@]
+ */
+BOOL WINAPI CredUnmarshalCredentialW( LPCWSTR cred, PCRED_MARSHAL_TYPE type, PVOID *out )
+{
+    unsigned int len, buflen, size;
+
+    TRACE("%s, %p, %p\n", debugstr_w(cred), type, out);
+
+    if (!cred || cred[0] != '@' || cred[1] != '@' || !cred[2] || !cred[3])
+    {
+        SetLastError( ERROR_INVALID_PARAMETER );
+        return FALSE;
+    }
+    len = strlenW( cred + 3 );
+    switch (cred[2] - 'A')
+    {
+    case CertCredential:
+    {
+        char hash[CERT_HASH_LENGTH + 2];
+        CERT_CREDENTIAL_INFO *cert;
+
+        if (len != 27 || !cred_decode( cred + 3, len, hash ))
+        {
+            SetLastError( ERROR_INVALID_PARAMETER );
+            return FALSE;
+        }
+        if (!(cert = HeapAlloc( GetProcessHeap(), 0, sizeof(*cert) ))) return FALSE;
+        memcpy( cert->rgbHashOfCert, hash, sizeof(cert->rgbHashOfCert) );
+        cert->cbSize = sizeof(*cert);
+        *type = CertCredential;
+        *out = cert;
+        break;
+    }
+    case UsernameTargetCredential:
+    {
+        USERNAME_TARGET_CREDENTIAL_INFO *target;
+
+        if (len < 9 || !cred_decode( cred + 3, 6, (char *)&size ) || !size || size % sizeof(WCHAR))
+        {
+            SetLastError( ERROR_INVALID_PARAMETER );
+            return FALSE;
+        }
+        buflen = sizeof(*target) + size + sizeof(WCHAR);
+        if (!(target = HeapAlloc( GetProcessHeap(), 0, buflen ))) return FALSE;
+        if (!cred_decode( cred + 9, len - 6, (char *)(target + 1) ))
+        {
+            HeapFree( GetProcessHeap(), 0, target );
+            return FALSE;
+        }
+        target->UserName = (WCHAR *)(target + 1);
+        target->UserName[size / sizeof(WCHAR)] = 0;
+        *type = UsernameTargetCredential;
+        *out = target;
+        break;
+    }
+    case BinaryBlobCredential:
+        FIXME("BinaryBlobCredential not implemented\n");
+        return FALSE;
+    default:
+        WARN("unhandled type %u\n", cred[2] - 'A');
+        return FALSE;
+    }
+    return TRUE;
+}
diff --git a/include/wincred.h b/include/wincred.h
index 59f2489..fb18a01 100644
--- a/include/wincred.h
+++ b/include/wincred.h
@@ -150,6 +150,32 @@ typedef struct _CREDUI_INFOW
 DECL_WINELIB_TYPE_AW(CREDUI_INFO)
 DECL_WINELIB_TYPE_AW(PCREDUI_INFO)
 
+typedef enum _CRED_MARSHAL_TYPE
+{
+    CertCredential = 1,
+    UsernameTargetCredential,
+    BinaryBlobCredential
+} CRED_MARSHAL_TYPE, *PCRED_MARSHAL_TYPE;
+
+#define CERT_HASH_LENGTH    20
+
+typedef struct _CERT_CREDENTIAL_INFO
+{
+    ULONG cbSize;
+    UCHAR rgbHashOfCert[CERT_HASH_LENGTH];
+} CERT_CREDENTIAL_INFO, *PCERT_CREDENTIAL_INFO;
+
+typedef struct _USERNAME_TARGET_CREDENTIAL_INFO
+{
+    LPWSTR UserName;
+} USERNAME_TARGET_CREDENTIAL_INFO;
+
+typedef struct _BINARY_BLOB_CREDENTIAL_INFO
+{
+    ULONG cbBlob;
+    LPBYTE pbBlob;
+} BINARY_BLOB_CREDENTIAL_INFO, *PBINARY_BLOB_CREDENTIAL_INFO;
+
 #define CRED_MAX_STRING_LENGTH              256
 #define CRED_MAX_USERNAME_LENGTH            513
 #define CRED_MAX_GENERIC_TARGET_NAME_LENGTH 32767
@@ -222,6 +248,9 @@ WINADVAPI BOOL  WINAPI CredEnumerateW(LPCWSTR,DWORD,DWORD *,PCREDENTIALW **);
 #define                CredEnumerate WINELIB_NAME_AW(CredEnumerate)
 WINADVAPI VOID  WINAPI CredFree(PVOID);
 WINADVAPI BOOL  WINAPI CredGetSessionTypes(DWORD,LPDWORD);
+WINADVAPI BOOL  WINAPI CredMarshalCredentialA(CRED_MARSHAL_TYPE,PVOID,LPSTR *);
+WINADVAPI BOOL  WINAPI CredMarshalCredentialW(CRED_MARSHAL_TYPE,PVOID,LPWSTR *);
+#define                CredMarshalCredential WINELIB_NAME_AW(CredMarshalCredential)
 WINADVAPI BOOL  WINAPI CredReadA(LPCSTR,DWORD,DWORD,PCREDENTIALA *);
 WINADVAPI BOOL  WINAPI CredReadW(LPCWSTR,DWORD,DWORD,PCREDENTIALW *);
 #define                CredRead WINELIB_NAME_AW(CredRead)
@@ -231,6 +260,9 @@ WINADVAPI BOOL  WINAPI CredReadDomainCredentialsW(PCREDENTIAL_TARGET_INFORMATION
 WINADVAPI BOOL  WINAPI CredRenameA(LPCSTR,LPCSTR,DWORD,DWORD);
 WINADVAPI BOOL  WINAPI CredRenameW(LPCWSTR,LPCWSTR,DWORD,DWORD);
 #define                CredRename WINELIB_NAME_AW(CredRename)
+WINADVAPI BOOL  WINAPI CredUnmarshalCredentialA(LPCSTR,PCRED_MARSHAL_TYPE,PVOID *);
+WINADVAPI BOOL  WINAPI CredUnmarshalCredentialW(LPCWSTR,PCRED_MARSHAL_TYPE,PVOID *);
+#define                CredUnmarshalCredential WINELIB_NAME_AW(CredUnmarshalCredential)
 WINADVAPI BOOL  WINAPI CredWriteA(PCREDENTIALA,DWORD);
 WINADVAPI BOOL  WINAPI CredWriteW(PCREDENTIALW,DWORD);
 #define                CredWrite WINELIB_NAME_AW(CredWrite)

-- 
Debian Wine packaging



More information about the pkg-wine-party mailing list