Wine-0_9_4 vendor drop
Modified: vendor/wine/dlls/comctl32/current/tooltips.c
Modified: vendor/wine/dlls/comctl32/current/treeview.c
Modified: vendor/wine/dlls/commdlg/current/finddlg32.c
Modified: vendor/wine/dlls/commdlg/current/fontdlg.c
Modified: vendor/wine/dlls/crypt32/current/cert.c
Modified: vendor/wine/dlls/crypt32/current/encode.c
Modified: vendor/wine/dlls/mpr/current/mpr_main.c
Modified: vendor/wine/dlls/msi/current/dialog.c
Modified: vendor/wine/dlls/msi/current/format.c
Modified: vendor/wine/dlls/ole32/current/errorinfo.c
Modified: vendor/wine/dlls/ole32/current/ole16.c
Modified: vendor/wine/dlls/ole32/current/ole2.c
Modified: vendor/wine/dlls/ole32/current/rpc.c
Modified: vendor/wine/dlls/ole32/current/stg_stream.c
Modified: vendor/wine/dlls/ole32/current/storage32.c
Modified: vendor/wine/dlls/ole32/current/storage32.h
Modified: vendor/wine/dlls/oleaut32/current/oleaut.c
Modified: vendor/wine/dlls/oleaut32/current/safearray.c
Modified: vendor/wine/dlls/oleaut32/current/typelib.c
Modified: vendor/wine/dlls/riched20/current/editor.c
Modified: vendor/wine/dlls/shell32/current/shellpath.c
Modified: vendor/wine/dlls/shell32/current/shlview.c
Modified: vendor/wine/dlls/shlwapi/current/regstream.c
Modified: vendor/wine/dlls/urlmon/current/binding.c
Modified: vendor/wine/dlls/urlmon/current/file.c
Modified: vendor/wine/dlls/urlmon/current/umstream.c
Modified: vendor/wine/tools/winebuild/current/build.h
Modified: vendor/wine/tools/winebuild/current/import.c
Modified: vendor/wine/tools/winebuild/current/parser.c
Modified: vendor/wine/tools/winebuild/current/relay.c
Modified: vendor/wine/tools/winebuild/current/spec32.c
Modified: vendor/wine/tools/winebuild/current/utils.c
Modified: vendor/wine/tools/winebuild/current/winebuild.man.in

Modified: vendor/wine/dlls/comctl32/current/tooltips.c
--- vendor/wine/dlls/comctl32/current/tooltips.c	2005-12-26 20:40:45 UTC (rev 20339)
+++ vendor/wine/dlls/comctl32/current/tooltips.c	2005-12-26 20:46:36 UTC (rev 20340)
@@ -2400,7 +2400,7 @@
     DWORD dwStyle = GetWindowLongW (hwnd, GWL_STYLE);
     DWORD dwExStyle = GetWindowLongW (hwnd, GWL_EXSTYLE);
 
-    dwStyle &= 0x0000FFFF;
+    dwStyle &= ~(WS_CHILD | /*WS_MAXIMIZE |*/ WS_BORDER | WS_DLGFRAME);
     dwStyle |= (WS_POPUP | WS_BORDER | WS_CLIPSIBLINGS);
 
     /* WS_BORDER only draws a border round the window rect, not the

Modified: vendor/wine/dlls/comctl32/current/treeview.c
--- vendor/wine/dlls/comctl32/current/treeview.c	2005-12-26 20:40:45 UTC (rev 20339)
+++ vendor/wine/dlls/comctl32/current/treeview.c	2005-12-26 20:46:36 UTC (rev 20340)
@@ -565,7 +565,7 @@
     TRACE("code:%d action:%x olditem:%p newitem:%p\n",
 	  code, action, oldItem, newItem);
 
-    ZeroMemory(&nmhdr, sizeof(NMTREEVIEWA));
+    ZeroMemory(&nmhdr, sizeof(NMTREEVIEWW));
 
     nmhdr.hdr.hwndFrom = hwnd;
     nmhdr.hdr.idFrom = GetWindowLongPtrW(hwnd, GWLP_ID);

Modified: vendor/wine/dlls/commdlg/current/finddlg32.c
--- vendor/wine/dlls/commdlg/current/finddlg32.c	2005-12-26 20:40:45 UTC (rev 20339)
+++ vendor/wine/dlls/commdlg/current/finddlg32.c	2005-12-26 20:46:36 UTC (rev 20340)
@@ -385,7 +385,7 @@
         		hmod = (HMODULE)pdata->fr.hInstance;
                         if(pdata->fr.Flags & FR_WINE_UNICODE)
                         {
-				htemplate = FindResourceW(hmod, (LPWSTR)pdata->fr.lpTemplateName, (LPWSTR)RT_DIALOG);
+				htemplate = FindResourceW(hmod, (LPCWSTR)pdata->fr.lpTemplateName, (LPWSTR)RT_DIALOG);
                         }
                         else
                         {

Modified: vendor/wine/dlls/commdlg/current/fontdlg.c
--- vendor/wine/dlls/commdlg/current/fontdlg.c	2005-12-26 20:40:45 UTC (rev 20339)
+++ vendor/wine/dlls/commdlg/current/fontdlg.c	2005-12-26 20:46:36 UTC (rev 20340)
@@ -1076,7 +1076,6 @@
         HDC hdc;
         HPEN hOrigPen;
         HFONT hOrigFont;
-        COLORREF rgbPrev;
         LOGFONTW lf = *(lpcf->lpLogFont);
 
         MapWindowPoints( 0, hDlg, (LPPOINT) &info.rcWindow, 2);
@@ -1104,7 +1103,7 @@
         info.rcWindow.top++;
         info.rcWindow.left++;
         hOrigFont = SelectObject( hdc, CreateFontIndirectW( &lf ) );
-        rgbPrev=SetTextColor( hdc, lpcf->rgbColors );
+        SetTextColor( hdc, lpcf->rgbColors );
 
         DrawTextW( hdc,
                 sample_lang_text[CHARSET_ORDER[lpcf->lpLogFont->lfCharSet]],

Modified: vendor/wine/dlls/crypt32/current/cert.c
--- vendor/wine/dlls/crypt32/current/cert.c	2005-12-26 20:40:45 UTC (rev 20339)
+++ vendor/wine/dlls/crypt32/current/cert.c	2005-12-26 20:46:36 UTC (rev 20340)
@@ -313,14 +313,6 @@
 static const void * WINAPI CRYPT_ReadSerializedElement(const BYTE *pbElement,
  DWORD cbElement, DWORD dwContextTypeFlags, DWORD *pdwContentType);
 
-/* filter for page-fault exceptions */
-static WINE_EXCEPTION_FILTER(page_fault)
-{
-    if (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION)
-        return EXCEPTION_EXECUTE_HANDLER;
-    return EXCEPTION_CONTINUE_SEARCH;
-}
-
 static void CRYPT_InitStore(WINECRYPT_CERTSTORE *store, HCRYPTPROV hCryptProv,
  DWORD dwFlags, CertStoreType type)
 {
@@ -1885,6 +1877,22 @@
     return ret;
 }
 
+static BOOL CRYPT_GetCertHashProp(PWINE_CERT_CONTEXT context, DWORD dwPropId,
+ ALG_ID algID, const BYTE *toHash, DWORD toHashLen, void *pvData,
+ DWORD *pcbData)
+{
+    BOOL ret = CryptHashCertificate(0, algID, 0, toHash, toHashLen, pvData,
+     pcbData);
+    if (ret)
+    {
+        CRYPT_DATA_BLOB blob = { *pcbData, pvData };
+
+        ret = CRYPT_SetCertificateContextProperty(context, dwPropId,
+         0, &blob);
+    }
+    return ret;
+}
+
 static BOOL WINAPI CRYPT_GetCertificateContextProperty(
  PWINE_CERT_CONTEXT context, DWORD dwPropId, void *pvData, DWORD *pcbData)
 {
@@ -1927,26 +1935,34 @@
         switch (dwPropId)
         {
         case CERT_SHA1_HASH_PROP_ID:
-            ret = CryptHashCertificate(0, CALG_SHA1, 0,
+            ret = CRYPT_GetCertHashProp(context, dwPropId, CALG_SHA1,
              context->cert.pbCertEncoded, context->cert.cbCertEncoded, pvData,
              pcbData);
-            if (ret)
-            {
-                CRYPT_DATA_BLOB blob = { *pcbData, pvData };
-
-                ret = CRYPT_SetCertificateContextProperty(context, dwPropId,
-                 0, &blob);
-            }
             break;
-        case CERT_KEY_PROV_INFO_PROP_ID:
         case CERT_MD5_HASH_PROP_ID:
+            ret = CRYPT_GetCertHashProp(context, dwPropId, CALG_MD5,
+             context->cert.pbCertEncoded, context->cert.cbCertEncoded, pvData,
+             pcbData);
+            break;
+        case CERT_SUBJECT_NAME_MD5_HASH_PROP_ID:
+            ret = CRYPT_GetCertHashProp(context, dwPropId, CALG_MD5,
+             context->cert.pCertInfo->Subject.pbData,
+             context->cert.pCertInfo->Subject.cbData,
+             pvData, pcbData);
+            break;
+        case CERT_SUBJECT_PUBLIC_KEY_MD5_HASH_PROP_ID:
+            ret = CRYPT_GetCertHashProp(context, dwPropId, CALG_MD5,
+             context->cert.pCertInfo->SubjectPublicKeyInfo.PublicKey.pbData,
+             context->cert.pCertInfo->SubjectPublicKeyInfo.PublicKey.cbData,
+             pvData, pcbData);
+            break;
         case CERT_SIGNATURE_HASH_PROP_ID:
-        case CERT_KEY_IDENTIFIER_PROP_ID:
-        case CERT_SUBJECT_PUBLIC_KEY_MD5_HASH_PROP_ID:
         case CERT_ISSUER_SERIAL_NUMBER_MD5_HASH_PROP_ID:
-        case CERT_SUBJECT_NAME_MD5_HASH_PROP_ID:
             FIXME("implicit property %ld\n", dwPropId);
+            SetLastError(CRYPT_E_NOT_FOUND);
             break;
+        default:
+            SetLastError(CRYPT_E_NOT_FOUND);
         }
     }
     LeaveCriticalSection(&context->cs);
@@ -2108,6 +2124,7 @@
         case CERT_PVK_FILE_PROP_ID:
         case CERT_SIGNATURE_HASH_PROP_ID:
         case CERT_ISSUER_PUBLIC_KEY_MD5_HASH_PROP_ID:
+        case CERT_SUBJECT_NAME_MD5_HASH_PROP_ID:
         case CERT_SUBJECT_PUBLIC_KEY_MD5_HASH_PROP_ID:
         case CERT_ENROLLMENT_PROP_ID:
         case CERT_CROSS_CERT_DIST_POINTS_PROP_ID:
@@ -2787,7 +2804,7 @@
             }
         }
     }
-    __EXCEPT(page_fault)
+    __EXCEPT_PAGE_FAULT
     {
         SetLastError(STATUS_ACCESS_VIOLATION);
         context = NULL;

Modified: vendor/wine/dlls/crypt32/current/encode.c
--- vendor/wine/dlls/crypt32/current/encode.c	2005-12-26 20:40:45 UTC (rev 20339)
+++ vendor/wine/dlls/crypt32/current/encode.c	2005-12-26 20:46:36 UTC (rev 20340)
@@ -61,8 +61,8 @@
 #define ASN_UTCTIME         (ASN_UNIVERSAL | ASN_PRIMITIVE | 0x17)
 #define ASN_GENERALTIME     (ASN_UNIVERSAL | ASN_PRIMITIVE | 0x18)
 
-#define ASN_FLAGS_MASK 0xf0
-#define ASN_TYPE_MASK  0x0f
+#define ASN_FLAGS_MASK 0xe0
+#define ASN_TYPE_MASK  0x1f
 
 WINE_DEFAULT_DEBUG_CHANNEL(crypt);
 
@@ -134,10 +134,11 @@
  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo);
 static BOOL WINAPI CRYPT_AsnDecodeOid(const BYTE *pbEncoded, DWORD cbEncoded,
  DWORD dwFlags, LPSTR pszObjId, DWORD *pcbObjId);
-/* Assumes algo->Parameters.pbData is set ahead of time */
+/* Assumes algo->Parameters.pbData is set ahead of time.  Internal func. */
 static BOOL WINAPI CRYPT_AsnDecodeAlgorithmId(DWORD dwCertEncodingType,
  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo);
+/* Internal function */
 static BOOL WINAPI CRYPT_AsnDecodeBool(DWORD dwCertEncodingType,
  LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
  PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo);
@@ -171,14 +172,6 @@
  DWORD cbEncoded, DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara,
  void *pvStructInfo, DWORD *pcbStructInfo);
 
-/* filter for page-fault exceptions */
-static WINE_EXCEPTION_FILTER(page_fault)
-{
-    if (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION)
-        return EXCEPTION_EXECUTE_HANDLER;
-    return EXCEPTION_CONTINUE_SEARCH;
-}
-
 BOOL WINAPI CryptEncodeObject(DWORD dwCertEncodingType, LPCSTR lpszStructType,
  const void *pvStructInfo, BYTE *pbEncoded, DWORD *pcbEncoded)
 {
@@ -311,6 +304,9 @@
         ret = items[i].encodeFunc(dwCertEncodingType, NULL,
          items[i].pvStructInfo, dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, NULL,
          NULL, &items[i].size);
+        /* Some functions propagate their errors through the size */
+        if (!ret)
+            *pcbEncoded = items[i].size;
         dataLen += items[i].size;
     }
     if (ret)
@@ -336,6 +332,9 @@
                     ret = items[i].encodeFunc(dwCertEncodingType, NULL,
                      items[i].pvStructInfo, dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG,
                      NULL, pbEncoded, &items[i].size);
+                    /* Some functions propagate their errors through the size */
+                    if (!ret)
+                        *pcbEncoded = items[i].size;
                     pbEncoded += items[i].size;
                 }
             }
@@ -381,11 +380,47 @@
             ret = item->encodeFunc(dwCertEncodingType, lpszStructType,
              item->pvStructInfo, dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, NULL,
              pbEncoded, &len);
+            if (!ret)
+            {
+                /* Some functions propagate their errors through the size */
+                *pcbEncoded = len;
+            }
         }
     }
+    else
+    {
+        /* Some functions propagate their errors through the size */
+        *pcbEncoded = len;
+    }
     return ret;
 }
 
+struct AsnEncodeTagSwappedItem
+{
+    BYTE                    tag;
+    const void             *pvStructInfo;
+    CryptEncodeObjectExFunc encodeFunc;
+};
+
+/* Sort of a wacky hack, it encodes something using the struct
+ * AsnEncodeTagSwappedItem's encodeFunc, then replaces the tag byte with the tag
+ * given in the struct AsnEncodeTagSwappedItem.
+ */
+static BOOL WINAPI CRYPT_AsnEncodeSwapTag(DWORD dwCertEncodingType,
+ LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
+ PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded)
+{
+    BOOL ret;
+    const struct AsnEncodeTagSwappedItem *item =
+     (const struct AsnEncodeTagSwappedItem *)pvStructInfo;
+
+    ret = item->encodeFunc(dwCertEncodingType, lpszStructType,
+     item->pvStructInfo, dwFlags, pEncodePara, pbEncoded, pcbEncoded);
+    if (ret && pbEncoded)
+        *pbEncoded = item->tag;
+    return ret;
+}
+
 static BOOL WINAPI CRYPT_AsnEncodeCertVersion(DWORD dwCertEncodingType,
  LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
  PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded)
@@ -495,7 +530,7 @@
          sizeof(items) / sizeof(items[0]), dwFlags, pEncodePara, pbEncoded,
          pcbEncoded);
     }
-    __EXCEPT(page_fault)
+    __EXCEPT_PAGE_FAULT
     {
         SetLastError(STATUS_ACCESS_VIOLATION);
         ret = FALSE;
@@ -526,7 +561,7 @@
          sizeof(items) / sizeof(items[0]), dwFlags, pEncodePara, pbEncoded,
          pcbEncoded);
     }
-    __EXCEPT(page_fault)
+    __EXCEPT_PAGE_FAULT
     {
         SetLastError(STATUS_ACCESS_VIOLATION);
         ret = FALSE;
@@ -595,7 +630,7 @@
         ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items, cItem,
          dwFlags, pEncodePara, pbEncoded, pcbEncoded);
     }
-    __EXCEPT(page_fault)
+    __EXCEPT_PAGE_FAULT
     {
         SetLastError(STATUS_ACCESS_VIOLATION);
         ret = FALSE;
@@ -739,7 +774,7 @@
         ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items, cItem,
          dwFlags, pEncodePara, pbEncoded, pcbEncoded);
     }
-    __EXCEPT(page_fault)
+    __EXCEPT_PAGE_FAULT
     {
         SetLastError(STATUS_ACCESS_VIOLATION);
         ret = FALSE;
@@ -823,7 +858,7 @@
             }
         }
     }
-    __EXCEPT(page_fault)
+    __EXCEPT_PAGE_FAULT
     {
         SetLastError(STATUS_ACCESS_VIOLATION);
         ret = FALSE;
@@ -1031,7 +1066,7 @@
                 }
                 else
                 {
-                    *pbEncoded++ = ASN_CONSTRUCTOR | ASN_SEQUENCE;
+                    *pbEncoded++ = ASN_SEQUENCE;
                     CRYPT_EncodeLen(bytesNeeded - lenBytes - 1, pbEncoded,
                      &lenBytes);
                     pbEncoded += lenBytes;
@@ -1140,7 +1175,7 @@
                 CryptMemFree(blobs[i].pbData);
         }
     }
-    __EXCEPT(page_fault)
+    __EXCEPT_PAGE_FAULT
     {
         SetLastError(STATUS_ACCESS_VIOLATION);
         ret = FALSE;
@@ -1202,7 +1237,7 @@
             }
         }
     }
-    __EXCEPT(page_fault)
+    __EXCEPT_PAGE_FAULT
     {
         SetLastError(STATUS_ACCESS_VIOLATION);
         ret = FALSE;
@@ -1339,7 +1374,6 @@
     {
         const CERT_ALT_NAME_INFO *info =
          (const CERT_ALT_NAME_INFO *)pvStructInfo;
-
         DWORD bytesNeeded, dataLen, lenBytes, i;
 
         ret = TRUE;
@@ -1399,7 +1433,7 @@
             }
         }
     }
-    __EXCEPT(page_fault)
+    __EXCEPT_PAGE_FAULT
     {
         SetLastError(STATUS_ACCESS_VIOLATION);
         ret = FALSE;
@@ -1436,7 +1470,7 @@
         ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items, cItem,
          dwFlags, pEncodePara, pbEncoded, pcbEncoded);
     }
-    __EXCEPT(page_fault)
+    __EXCEPT_PAGE_FAULT
     {
         SetLastError(STATUS_ACCESS_VIOLATION);
         ret = FALSE;
@@ -1477,7 +1511,7 @@
              pcbEncoded);
         }
     }
-    __EXCEPT(page_fault)
+    __EXCEPT_PAGE_FAULT
     {
         SetLastError(STATUS_ACCESS_VIOLATION);
         ret = FALSE;
@@ -1522,7 +1556,7 @@
             }
         }
     }
-    __EXCEPT(page_fault)
+    __EXCEPT_PAGE_FAULT
     {
         SetLastError(STATUS_ACCESS_VIOLATION);
         ret = FALSE;
@@ -1593,7 +1627,7 @@
             }
         }
     }
-    __EXCEPT(page_fault)
+    __EXCEPT_PAGE_FAULT
     {
         SetLastError(STATUS_ACCESS_VIOLATION);
         ret = FALSE;
@@ -1632,7 +1666,7 @@
              &newBlob, dwFlags, pEncodePara, pbEncoded, pcbEncoded);
         CryptMemFree(newBlob.pbData);
     }
-    __EXCEPT(page_fault)
+    __EXCEPT_PAGE_FAULT
     {
         SetLastError(STATUS_ACCESS_VIOLATION);
         ret = FALSE;
@@ -1731,7 +1765,7 @@
             }
         }
     }
-    __EXCEPT(page_fault)
+    __EXCEPT_PAGE_FAULT
     {
         SetLastError(STATUS_ACCESS_VIOLATION);
         ret = FALSE;
@@ -1802,7 +1836,7 @@
             }
         }
     }
-    __EXCEPT(page_fault)
+    __EXCEPT_PAGE_FAULT
     {
         SetLastError(STATUS_ACCESS_VIOLATION);
         ret = FALSE;
@@ -1881,7 +1915,7 @@
             }
         }
     }
-    __EXCEPT(page_fault)
+    __EXCEPT_PAGE_FAULT
     {
         SetLastError(STATUS_ACCESS_VIOLATION);
         ret = FALSE;
@@ -1930,7 +1964,7 @@
             }
         }
     }
-    __EXCEPT(page_fault)
+    __EXCEPT_PAGE_FAULT
     {
         SetLastError(STATUS_ACCESS_VIOLATION);
         ret = FALSE;
@@ -1960,7 +1994,7 @@
              lpszStructType, pvStructInfo, dwFlags, pEncodePara, pbEncoded,
              pcbEncoded);
     }
-    __EXCEPT(page_fault)
+    __EXCEPT_PAGE_FAULT
     {
         SetLastError(STATUS_ACCESS_VIOLATION);
         ret = FALSE;
@@ -2009,7 +2043,7 @@
             }
         }
     }
-    __EXCEPT(page_fault)
+    __EXCEPT_PAGE_FAULT
     {
         SetLastError(STATUS_ACCESS_VIOLATION);
         ret = FALSE;
@@ -2018,6 +2052,145 @@
     return ret;
 }
 
+static BOOL CRYPT_AsnEncodeDistPoint(const CRL_DIST_POINT *distPoint,
+ BYTE *pbEncoded, DWORD *pcbEncoded)
+{
+    BOOL ret = TRUE;
+    struct AsnEncodeSequenceItem items[3] = { { 0 } };
+    struct AsnConstructedItem constructed = { 0 };
+    struct AsnEncodeTagSwappedItem swapped[3] = { { 0 } };
+    DWORD cItem = 0, cSwapped = 0;
+
+    switch (distPoint->DistPointName.dwDistPointNameChoice)
+    {
+    case CRL_DIST_POINT_NO_NAME:
+        /* do nothing */
+        break;
+    case CRL_DIST_POINT_FULL_NAME:
+        swapped[cSwapped].tag = ASN_CONTEXT | ASN_CONSTRUCTOR | 0;
+        swapped[cSwapped].pvStructInfo = &distPoint->DistPointName.u.FullName;
+        swapped[cSwapped].encodeFunc = CRYPT_AsnEncodeAltName;
+        constructed.tag = 0;
+        constructed.pvStructInfo = &swapped[cSwapped];
+        constructed.encodeFunc = CRYPT_AsnEncodeSwapTag;
+        items[cItem].pvStructInfo = &constructed;
+        items[cItem].encodeFunc = CRYPT_AsnEncodeConstructed;
+        cSwapped++;
+        cItem++;
+        break;
+    case CRL_DIST_POINT_ISSUER_RDN_NAME:
+        FIXME("unimplemented for CRL_DIST_POINT_ISSUER_RDN_NAME\n");
+        ret = FALSE;
+        break;
+    default:
+        ret = FALSE;
+    }
+    if (ret && distPoint->ReasonFlags.cbData)
+    {
+        swapped[cSwapped].tag = ASN_CONTEXT | 1;
+        swapped[cSwapped].pvStructInfo = &distPoint->ReasonFlags;
+        swapped[cSwapped].encodeFunc = CRYPT_AsnEncodeBits;
+        items[cItem].pvStructInfo = &swapped[cSwapped];
+        items[cItem].encodeFunc = CRYPT_AsnEncodeSwapTag;
+        cSwapped++;
+        cItem++;
+    }
+    if (ret && distPoint->CRLIssuer.cAltEntry)
+    {
+        swapped[cSwapped].tag = ASN_CONTEXT | ASN_CONSTRUCTOR | 2;
+        swapped[cSwapped].pvStructInfo = &distPoint->CRLIssuer;
+        swapped[cSwapped].encodeFunc = CRYPT_AsnEncodeAltName;
+        items[cItem].pvStructInfo = &swapped[cSwapped];
+        items[cItem].encodeFunc = CRYPT_AsnEncodeSwapTag;
+        cSwapped++;
+        cItem++;
+    }
+    if (ret)
+        ret = CRYPT_AsnEncodeSequence(X509_ASN_ENCODING, items, cItem, 0, NULL,
+         pbEncoded, pcbEncoded);
+    return ret;
+}
+
+static BOOL WINAPI CRYPT_AsnEncodeCRLDistPoints(DWORD dwCertEncodingType,
+ LPCSTR lpszStructType, const void *pvStructInfo, DWORD dwFlags,
+ PCRYPT_ENCODE_PARA pEncodePara, BYTE *pbEncoded, DWORD *pcbEncoded)
+{
+    BOOL ret;
+
+    __TRY
+    {
+        const CRL_DIST_POINTS_INFO *info =
+         (const CRL_DIST_POINTS_INFO *)pvStructInfo;
+
+        if (!info->cDistPoint)
+        {
+            SetLastError(HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER));
+            ret = FALSE;
+        }
+        else
+        {
+            DWORD bytesNeeded, dataLen, lenBytes, i;
+
+            ret = TRUE;
+            for (i = 0, dataLen = 0; ret && i < info->cDistPoint; i++)
+            {
+                DWORD len;
+
+                ret = CRYPT_AsnEncodeDistPoint(&info->rgDistPoint[i], NULL,
+                 &len);
+                if (ret)
+                    dataLen += len;
+                else if (GetLastError() == CRYPT_E_INVALID_IA5_STRING)
+                {
+                    /* Have to propagate index of failing character */
+                    *pcbEncoded = len;
+                }
+            }
+            if (ret)
+            {
+                CRYPT_EncodeLen(dataLen, NULL, &lenBytes);
+                bytesNeeded = 1 + lenBytes + dataLen;
+                if (!pbEncoded)
+                {
+                    *pcbEncoded = bytesNeeded;
+                    ret = TRUE;
+                }
+                else
+                {
+                    if ((ret = CRYPT_EncodeEnsureSpace(dwFlags, pEncodePara,
+                     pbEncoded, pcbEncoded, bytesNeeded)))
+                    {
+                        if (dwFlags & CRYPT_ENCODE_ALLOC_FLAG)
+                            pbEncoded = *(BYTE **)pbEncoded;
+                        *pbEncoded++ = ASN_SEQUENCEOF;
+                        CRYPT_EncodeLen(dataLen, pbEncoded, &lenBytes);
+                        pbEncoded += lenBytes;
+                        for (i = 0; ret && i < info->cDistPoint; i++)
+                        {
+                            DWORD len = dataLen;
+
+                            ret = CRYPT_AsnEncodeDistPoint(
+                             &info->rgDistPoint[i], pbEncoded, &len);
+                            if (ret)
+                            {
+                                pbEncoded += len;
+                                dataLen -= len;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+    __EXCEPT_PAGE_FAULT
+    {
+        SetLastError(STATUS_ACCESS_VIOLATION);
+        ret = FALSE;
+    }
+    __ENDTRY
+    return ret;
+}
+
 BOOL WINAPI CryptEncodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType,
  const void *pvStructInfo, DWORD dwFlags, PCRYPT_ENCODE_PARA pEncodePara,
  void *pvEncoded, DWORD *pcbEncoded)
@@ -2105,6 +2278,9 @@
         case (WORD)PKCS_UTC_TIME:
             encodeFunc = CRYPT_AsnEncodeUtcTime;
             break;
+        case (WORD)X509_CRL_DIST_POINTS:
+            encodeFunc = CRYPT_AsnEncodeCRLDistPoints;
+            break;
         default:
             FIXME("%d: unimplemented\n", LOWORD(lpszStructType));
         }
@@ -2291,7 +2467,9 @@
     return ret;
 }
 
-/* A few of the members need explanation:
+/* tag:
+ *     The expected tag of the item.  If tag is 0, decodeFunc is called
+ *     regardless of the tag value seen.
  * offset:
  *     A sequence is decoded into a struct.  The offset member is the
  *     offset of this item within that struct.
@@ -2301,9 +2479,9 @@
  * minSize:
  *     The minimum amount of space occupied after decoding.  You must set this.
  * optional:
- *     If true, and a decoding function fails with CRYPT_E_ASN1_BADTAG, then
- *     minSize space is filled with 0 for this member.  (Any other failure
- *     results in CRYPT_AsnDecodeSequence failing.)
+ *     If true, and the tag doesn't match the expected tag for this item,
+ *     or the decodeFunc fails with CRYPT_E_ASN1_BADTAG, then minSize space is
+ *     filled with 0 for this member.
  * hasPointer, pointerOffset, minSize:
  *     If the item has dynamic data, set hasPointer to TRUE, pointerOffset to
  *     the offset within the (outer) struct of the data pointer (or to the
@@ -2313,6 +2491,7 @@
  */
 struct AsnDecodeSequenceItem
 {
+    BYTE                    tag;
     DWORD                   offset;
     CryptDecodeObjectExFunc decodeFunc;
     DWORD                   minSize;
@@ -2322,6 +2501,114 @@
     DWORD                   size;
 };
 
+static BOOL CRYPT_AsnDecodeSequenceItems(DWORD dwCertEncodingType,
+ struct AsnDecodeSequenceItem items[], DWORD cItem, const BYTE *pbEncoded,
+ DWORD cbEncoded, DWORD dwFlags, void *pvStructInfo, BYTE *nextData)
+{
+    BOOL ret;
+    DWORD i;
+    const BYTE *ptr;
+
+    ptr = pbEncoded + 1 + GET_LEN_BYTES(pbEncoded[1]);
+    for (i = 0, ret = TRUE; ret && i < cItem; i++)
+    {
+        if (cbEncoded - (ptr - pbEncoded) != 0)
+        {
+            DWORD nextItemLen;
+
+            if ((ret = CRYPT_GetLen(ptr, cbEncoded - (ptr - pbEncoded),
+             &nextItemLen)))
+            {
+                BYTE nextItemLenBytes = GET_LEN_BYTES(ptr[1]);
+
+                if (ptr[0] == items[i].tag || !items[i].tag)
+                {
+                    if (nextData && pvStructInfo && items[i].hasPointer)
+                    {
+                        TRACE("Setting next pointer to %p\n",
+                         nextData);
+                        *(BYTE **)((BYTE *)pvStructInfo +
+                         items[i].pointerOffset) = nextData;
+                    }
+                    if (items[i].decodeFunc)
+                    {
+                        if (pvStructInfo)
+                            TRACE("decoding item %ld\n", i);
+                        else
+                            TRACE("sizing item %ld\n", i);
+                        ret = items[i].decodeFunc(dwCertEncodingType,
+                         NULL, ptr, 1 + nextItemLenBytes + nextItemLen,
+                         dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL,
+                         pvStructInfo ?  (BYTE *)pvStructInfo + items[i].offset
+                         : NULL, &items[i].size);
+                        if (ret)
+                        {
+                            if (nextData && items[i].hasPointer &&
+                             items[i].size > items[i].minSize)
+                            {
+                                nextData += items[i].size - items[i].minSize;
+                                /* align nextData to DWORD boundaries */
+                                if (items[i].size % sizeof(DWORD))
+                                    nextData += sizeof(DWORD) - items[i].size %
+                                     sizeof(DWORD);
+                            }
+                            /* Account for alignment padding */
+                            if (items[i].size % sizeof(DWORD))
+                                items[i].size += sizeof(DWORD) -
+                                 items[i].size % sizeof(DWORD);
+                            ptr += 1 + nextItemLenBytes + nextItemLen;
+                        }
+                        else if (items[i].optional &&
+                         GetLastError() == CRYPT_E_ASN1_BADTAG)
+                        {
+                            TRACE("skipping optional item %ld\n", i);
+                            items[i].size = items[i].minSize;
+                            SetLastError(NOERROR);
+                            ret = TRUE;
+                        }
+                        else
+                            TRACE("item %ld failed: %08lx\n", i,
+                             GetLastError());
+                    }
+                    else
+                        items[i].size = items[i].minSize;
+                }
+                else if (items[i].optional)
+                {
+                    TRACE("skipping optional item %ld\n", i);
+                    items[i].size = items[i].minSize;
+                }
+                else
+                {
+                    TRACE("tag %02x doesn't match expected %02x\n",
+                     ptr[0], items[i].tag);
+                    SetLastError(CRYPT_E_ASN1_BADTAG);
+                    ret = FALSE;
+                }
+            }
+        }
+        else if (items[i].optional)
+        {
+            TRACE("missing optional item %ld, skipping\n", i);
+            items[i].size = items[i].minSize;
+        }
+        else
+        {
+            TRACE("not enough bytes for item %ld, failing\n", i);
+            SetLastError(CRYPT_E_ASN1_CORRUPT);
+            ret = FALSE;
+        }
+    }
+    if (cbEncoded - (ptr - pbEncoded) != 0)
+    {
+        TRACE("%ld remaining bytes, failing\n", cbEncoded -
+         (ptr - pbEncoded));
+        SetLastError(CRYPT_E_ASN1_CORRUPT);
+        ret = FALSE;
+    }
+    return ret;
+}
+
 /* This decodes an arbitrary sequence into a contiguous block of memory
  * (basically, a struct.)  Each element being decoded is described by a struct
  * AsnDecodeSequenceItem, see above.
@@ -2348,70 +2635,160 @@
 
         if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
         {
+            DWORD i;
+
+            ret = CRYPT_AsnDecodeSequenceItems(dwFlags, items, cItem, pbEncoded,
+             cbEncoded, dwFlags, NULL, NULL);
+            if (ret)
+            {
+                DWORD bytesNeeded = 0, structSize = 0;
+
+                for (i = 0; i < cItem; i++)
+                {
+                    bytesNeeded += items[i].size;
+                    structSize += items[i].minSize;
+                }
+                if (!pvStructInfo)
+                    *pcbStructInfo = bytesNeeded;
+                else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags,
+                 pDecodePara, pvStructInfo, pcbStructInfo, bytesNeeded)))
+                {
+                    BYTE *nextData;
+
+                    if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
+                        pvStructInfo = *(BYTE **)pvStructInfo;
+                    if (startingPointer)
+                        nextData = (BYTE *)startingPointer;
+                    else
+                        nextData = (BYTE *)pvStructInfo + structSize;
+                    memset(pvStructInfo, 0, structSize);
+                    ret = CRYPT_AsnDecodeSequenceItems(dwFlags, items, cItem,
+                     pbEncoded, cbEncoded, dwFlags, pvStructInfo, nextData);
+                }
+            }
+        }
+    }
+    else
+    {
+        SetLastError(CRYPT_E_ASN1_BADTAG);
+        ret = FALSE;
+    }
+    TRACE("returning %d (%08lx)\n", ret, GetLastError());
+    return ret;
+}
+
+/* tag:
+ *     The expected tag of the entire encoded array (usually a variant
+ *     of ASN_SETOF or ASN_SEQUENCEOF.)
+ * decodeFunc:
+ *     used to decode each item in the array
+ * itemSize:
+ *      is the minimum size of each decoded item
+ * hasPointer:
+ *      indicates whether each item has a dynamic pointer
+ * pointerOffset:
+ *     indicates the offset within itemSize at which the pointer exists
+ */
+struct AsnArrayDescriptor
+{
+    BYTE                    tag;
+    CryptDecodeObjectExFunc decodeFunc;
+    DWORD                   itemSize;
+    BOOL                    hasPointer;
+    DWORD                   pointerOffset;
+};
+
+struct AsnArrayItemSize
+{
+    DWORD encodedLen;
+    DWORD size;
+};
+
+struct GenericArray
+{
+    DWORD cItems;
+    BYTE *rgItems;
+};
+
+/* Decodes an array of like types into a struct GenericArray.
+ * The layout and decoding of the array are described by a struct
+ * AsnArrayDescriptor.
+ */
+static BOOL CRYPT_AsnDecodeArray(const struct AsnArrayDescriptor *arrayDesc,
+ const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
+ PCRYPT_DECODE_PARA pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo,
+ void *startingPointer)
+{
+    BOOL ret = TRUE;
+
+    TRACE("%p, %p, %ld, %08lx, %p, %p, %ld, %p\n", arrayDesc, pbEncoded,
+     cbEncoded, dwFlags, pDecodePara, pvStructInfo, *pcbStructInfo,
+     startingPointer);
+
+    if (pbEncoded[0] == arrayDesc->tag)
+    {
+        DWORD dataLen;
+
+        if ((ret = CRYPT_GetLen(pbEncoded, cbEncoded, &dataLen)))
+        {
+            DWORD bytesNeeded, cItems = 0;
             BYTE lenBytes = GET_LEN_BYTES(pbEncoded[1]);
-            DWORD i, bytesNeeded = 0, minSize = 0;
-            const BYTE *ptr;
+            /* There can be arbitrarily many items, but there is often only one.
+             */
+            struct AsnArrayItemSize itemSize = { 0 }, *itemSizes = &itemSize;
 
-            ptr = pbEncoded + 1 + lenBytes;
-            for (i = 0; ret && i < cItem; i++)
+            bytesNeeded = sizeof(struct GenericArray);
+            if (dataLen)
             {
-                DWORD nextItemLen;
+                const BYTE *ptr;
 
-                minSize += items[i].minSize;
-                if (cbEncoded - (ptr - pbEncoded) != 0)
+                for (ptr = pbEncoded + 1 + lenBytes; ret &&
+                 ptr - pbEncoded - 1 - lenBytes < dataLen; )
                 {
-                    if ((ret = CRYPT_GetLen(ptr, cbEncoded - (ptr - pbEncoded),
-                     &nextItemLen)))
+                    DWORD itemLenBytes, itemDataLen, size;
+
+                    itemLenBytes = GET_LEN_BYTES(ptr[1]);
+                    /* Each item decoded may not tolerate extraneous bytes, so
+                     * get the length of the next element and pass it directly.
+                     */
+                    ret = CRYPT_GetLen(ptr, cbEncoded - (ptr - pbEncoded),
+                     &itemDataLen);
+                    if (ret)
+                        ret = arrayDesc->decodeFunc(X509_ASN_ENCODING, 0, ptr,
+                         1 + itemLenBytes + itemDataLen,
+                         dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, NULL,
+                         &size);
+                    if (ret)
                     {
-                        BYTE nextItemLenBytes = GET_LEN_BYTES(ptr[1]);
+                        DWORD nextLen;
 
-                        if (items[i].decodeFunc)
+                        cItems++;
+                        if (itemSizes != &itemSize)
+                            itemSizes = CryptMemRealloc(itemSizes,
+                             cItems * sizeof(struct AsnArrayItemSize));
+                        else
                         {
-                            TRACE("sizing item %ld\n", i);
-                            ret = items[i].decodeFunc(dwCertEncodingType, NULL,
-                             ptr, 1 + nextItemLenBytes + nextItemLen,
-                             dwFlags & ~CRYPT_DECODE_ALLOC_FLAG, NULL, NULL,
-                             &items[i].size);
+                            itemSizes =
+                             CryptMemAlloc(
+                             cItems * sizeof(struct AsnArrayItemSize));
+                            memcpy(itemSizes, &itemSize, sizeof(itemSize));
+                        }
+                        if (itemSizes)
+                        {
+                            itemSizes[cItems - 1].encodedLen = 1 + itemLenBytes
+                             + itemDataLen;
+                            itemSizes[cItems - 1].size = size;
+                            bytesNeeded += size;
+                            ret = CRYPT_GetLen(ptr,
+                             cbEncoded - (ptr - pbEncoded), &nextLen);
                             if (ret)
-                            {
-                                /* Account for alignment padding */
-                                bytesNeeded += items[i].size;
-                                if (items[i].size % sizeof(DWORD))
-                                    bytesNeeded += sizeof(DWORD) -
-                                     items[i].size % sizeof(DWORD);
-                                ptr += 1 + nextItemLenBytes + nextItemLen;
-                            }
-                            else if (items[i].optional &&
-                             GetLastError() == CRYPT_E_ASN1_BADTAG)
-                            {
-                                TRACE("skipping optional item %ld\n", i);
-                                bytesNeeded += items[i].minSize;
-                                SetLastError(NOERROR);
-                                ret = TRUE;
-                            }
-                            else
-                                TRACE("item %ld failed: %08lx\n", i,
-                                 GetLastError());
+                                ptr += nextLen + 1 + GET_LEN_BYTES(ptr[1]);
                         }
                         else
-                            bytesNeeded += items[i].minSize;
+                            ret = FALSE;
                     }
                 }
-                else if (items[i].optional)
-                    bytesNeeded += items[i].minSize;
-                else
-                {
-                    SetLastError(CRYPT_E_ASN1_CORRUPT);
-                    ret = FALSE;
-                }
             }
-            if (cbEncoded - (ptr - pbEncoded) != 0)
-            {
-                TRACE("%ld remaining bytes, failing\n", cbEncoded -
-                 (ptr - pbEncoded));
-                SetLastError(CRYPT_E_ASN1_CORRUPT);
-                ret = FALSE;
-            }
             if (ret)
             {
                 if (!pvStructInfo)
@@ -2419,75 +2796,49 @@
                 else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags,
                  pDecodePara, pvStructInfo, pcbStructInfo, bytesNeeded)))
                 {
+                    DWORD i;
                     BYTE *nextData;
+                    const BYTE *ptr;
+                    struct GenericArray *array;
 
                     if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
                         pvStructInfo = *(BYTE **)pvStructInfo;
+                    array = (struct GenericArray *)pvStructInfo;
+                    array->cItems = cItems;
                     if (startingPointer)
-                        nextData = (BYTE *)startingPointer;
+                        array->rgItems = startingPointer;
                     else
-                        nextData = (BYTE *)pvStructInfo + minSize;
-                    memset(pvStructInfo, 0, minSize);
-                    ptr = pbEncoded + 1 + lenBytes;
-                    for (i = 0; ret && i < cItem; i++)
[truncated at 1000 lines; 2943 more skipped]