secur32: add Negotiate security provider dummy

Kai Blin blin at gmx.net
Sat Aug 13 06:15:44 CDT 2005


Add the Negotiate security provider package to secur32. Fix a couple of
todo_wine tests that are now working. This is still a dummy, actuall
functionality to be added as the next step.

Changelog:
Kai Blin <blin at gmx.net>
Added Negotiate security provider dummy. Removed todos from the test.

-- 
Kai Blin, (blin at gmx dot net)
Vail's Second Axiom:
	The amount of work to be done increases in proportion to the
	amount of work already completed.
-------------- next part --------------
Index: dlls/secur32/Makefile.in
===================================================================
RCS file: /home/wine/wine/dlls/secur32/Makefile.in,v
retrieving revision 1.4
diff -u -3 -r1.4 Makefile.in
--- dlls/secur32/Makefile.in	3 Aug 2005 13:08:49 -0000	1.4
+++ dlls/secur32/Makefile.in	13 Aug 2005 10:45:05 -0000
@@ -8,6 +8,7 @@
 
 C_SRCS = \
 	schannel.c \
+	negotiate.c \
 	secur32.c \
 	thunks.c \
 	wrapper.c
Index: dlls/secur32/secur32.c
===================================================================
RCS file: /home/wine/wine/dlls/secur32/secur32.c,v
retrieving revision 1.7
diff -u -3 -r1.7 secur32.c
--- dlls/secur32/secur32.c	18 Jul 2005 09:11:14 -0000	1.7
+++ dlls/secur32/secur32.c	13 Aug 2005 10:45:11 -0000
@@ -609,6 +609,7 @@
     InitializeCriticalSection(&cs);
     /* First load built-in providers */
     SECUR32_initSchannelSP();
+    SECUR32_initNegotiateSP();
     /* Now load providers from registry */
     apiRet = RegOpenKeyExW(HKEY_LOCAL_MACHINE, securityProvidersKeyW, 0,
      KEY_READ, &key);
Index: dlls/secur32/secur32_priv.h
===================================================================
RCS file: /home/wine/wine/dlls/secur32/secur32_priv.h,v
retrieving revision 1.2
diff -u -3 -r1.2 secur32_priv.h
--- dlls/secur32/secur32_priv.h	13 May 2005 17:44:47 -0000	1.2
+++ dlls/secur32/secur32_priv.h	13 Aug 2005 10:45:11 -0000
@@ -79,5 +79,6 @@
 
 /* Initialization functions for built-in providers */
 void SECUR32_initSchannelSP(void);
+void SECUR32_initNegotiateSP(void);
 
 #endif /* ndef __SECUR32_PRIV_H__ */
Index: dlls/secur32/tests/main.c
===================================================================
RCS file: /home/wine/wine/dlls/secur32/tests/main.c,v
retrieving revision 1.2
diff -u -3 -r1.2 main.c
--- dlls/secur32/tests/main.c	11 Aug 2005 17:08:06 -0000	1.2
+++ dlls/secur32/tests/main.c	13 Aug 2005 10:45:14 -0000
@@ -88,11 +88,9 @@
         sec_status = (sft->AcquireCredentialsHandle)(NULL, "Negotiate", 
                 SECPKG_CRED_OUTBOUND, NULL, NULL, NULL, NULL, cred_handle,
                 &ttl);
-        todo_wine{
-            ok(sec_status == SEC_E_OK, 
-                    "Client AcquireCredentialsHandle should not return %s\n",
-                    getSecStatusError(sec_status) );
-        }
+        ok(sec_status == SEC_E_OK, 
+                "Client AcquireCredentialsHandle should not return %s\n",
+                getSecStatusError(sec_status) );
     }
 
     out_sec_buff_desc.ulVersion = 0;
@@ -288,24 +286,20 @@
     
     sec_status = setupPackageA(sec_pkg_name, &pkg_info);
 
-    todo_wine{
-        ok(sec_status == SEC_E_OK, 
-           "Return value of QuerySecurityPackageInfo() shouldn't be %s\n",
-           getSecStatusError(sec_status) );
-        ok(pkg_info != NULL, 
+    ok(sec_status == SEC_E_OK, 
+       "Return value of QuerySecurityPackageInfo() shouldn't be %s\n",
+       getSecStatusError(sec_status) );
+    ok(pkg_info != NULL, 
                 "QuerySecurityPackageInfo should give struct SecPkgInfo, but is NULL\n");
-    }
+    
     if(pkg_info != NULL){
         max_token = pkg_info->cbMaxToken;
         version   = pkg_info->wVersion;
     }
-    todo_wine{
-        ok(version == 1, "wVersion always should be 1, but is %d\n", version);
-        ok(max_token == 12000, "cbMaxToken for Negotiate is %ld, not 12000.\n",
-                max_token);
-    }
-
-    trace("Max token = %ld\n", max_token);
+    
+    ok(version == 1, "wVersion always should be 1, but is %d\n", version);
+    ok(max_token == 12000, "cbMaxToken for Negotiate is %ld, not 12000.\n",
+            max_token);
 
     sec_status = FreeContextBuffer(&pkg_info);
     
@@ -360,11 +354,9 @@
             SECPKG_CRED_INBOUND, NULL, NULL, NULL, NULL, &server_cred, 
             &server_ttl);
 
-    todo_wine{
-        ok(sec_status == SEC_E_OK, 
-                "Server's AcquireCredentialsHandle returned %s.\n", 
-                getSecStatusError(sec_status) );
-    }
+    ok(sec_status == SEC_E_OK, 
+            "Server's AcquireCredentialsHandle returned %s.\n", 
+            getSecStatusError(sec_status) );
 
     
     genClientContext(NULL, 0, server_buff, &count_server, &done, "foo", 
@@ -379,6 +371,8 @@
                 &count_server, &done, "foo", &client_cred, &client_ctxt, sft);
     }
 
+    FreeContextBuffer(&client_buff);
+    FreeContextBuffer(&server_buff);
 
 }
 

--- /dev/null	2005-08-12 02:44:20.313868960 +0200
+++ dlls/secur32/negotiate.c	2005-08-13 13:12:55.333122240 +0200
@@ -0,0 +1,493 @@
+/*
+ * Copyright 2005 Kai Blin
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * This file implements the negotiate provider.
+ * FIXME: So far, this beast doesn't do anything.
+ */
+#include <assert.h>
+#include <stdarg.h>
+#include "windef.h"
+#include "winbase.h"
+#include "sspi.h"
+#include "secur32_priv.h"
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(secur32);
+
+static const char nego_name_A[] = "Negotiate";
+static const WCHAR nego_name_W[] = {'N', 'e', 'g', 'o', 't', 'i', 'a', \
+    't', 'e', 0};
+
+static SECURITY_STATUS nego_QueryCredentialsAttributes(PCredHandle phCredential,
+        ULONG ulAttribute, PVOID pBuffer)
+{
+    SECURITY_STATUS ret;
+
+    /* FIXME: More attributes to ve added here. Need to fix the sspi.h header 
+     * for that, too.
+     */
+    switch(ulAttribute)
+    {
+        default:
+            ret = SEC_E_UNSUPPORTED_FUNCTION;
+    }
+    return ret;
+}
+
+/***********************************************************************
+ *              QueryCredentialsAttributesA (SECUR32.@)
+ */
+static SECURITY_STATUS SEC_ENTRY nego_QueryCredentialsAttributesA(
+        PCredHandle phCredential, ULONG ulAttribute, PVOID pBuffer)
+{
+    SECURITY_STATUS ret;
+
+    TRACE("(%p, %ld, %p)\n", phCredential, ulAttribute, pBuffer);
+
+    switch(ulAttribute)
+    {
+        case SECPKG_CRED_ATTR_NAMES:
+            FIXME("SECPKG_CRED_ATTR_NAMES: stub\n");
+            ret = SEC_E_UNSUPPORTED_FUNCTION;
+            break;
+        default:
+            ret = nego_QueryCredentialsAttributes(phCredential, ulAttribute, 
+                    pBuffer);
+    }
+    return ret;
+}
+
+/***********************************************************************
+ *              QueryCredentialsAttributesW (SECUR32.@)
+ */
+static SECURITY_STATUS SEC_ENTRY nego_QueryCredentialsAttributesW(
+        PCredHandle phCredential, ULONG ulAttribute, PVOID pBuffer)
+{
+    SECURITY_STATUS ret;
+
+    TRACE("(%p, %ld, %p)\n", phCredential, ulAttribute, pBuffer);
+
+    switch(ulAttribute)
+    {
+        case SECPKG_CRED_ATTR_NAMES:
+            FIXME("SECPKG_CRED_ATTR_NAMES: stub\n");
+            ret = SEC_E_UNSUPPORTED_FUNCTION;
+            break;
+        default:
+            ret = nego_QueryCredentialsAttributes(phCredential, ulAttribute, 
+                    pBuffer);
+    }
+    return ret;
+}
+
+static SECURITY_STATUS nego_AcquireCredentialsHandle(ULONG fCredentialsUse,
+        PCredHandle phCredential, PTimeStamp ptsExpiry)
+{
+    SECURITY_STATUS ret;
+
+    if(fCredentialsUse == SECPKG_CRED_BOTH)
+    {
+        ret = SEC_E_NO_CREDENTIALS;
+    }
+    else
+    {
+        /* Ok, just store the direction like schannel does for now.
+         * FIXME: This should probably do something useful later on
+         */
+        phCredential->dwUpper = fCredentialsUse;
+        /* Same here, shamelessly stolen from schannel.c */
+        if (ptsExpiry)
+            ptsExpiry->QuadPart = 0;
+        ret = SEC_E_OK;
+    }
+    return ret;
+}
+
+/***********************************************************************
+ *              AcquireCredentialsHandleA (SECUR32.@)
+ */
+static SECURITY_STATUS SEC_ENTRY nego_AcquireCredentialsHandleA(
+ SEC_CHAR *pszPrincipal, SEC_CHAR *pszPackage, ULONG fCredentialUse,
+ PLUID pLogonID, PVOID pAuthData, SEC_GET_KEY_FN pGetKeyFn,
+ PVOID pGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry)
+{
+    TRACE("(%s, %s, 0x%08lx, %p, %p, %p, %p, %p, %p)\n",
+     debugstr_a(pszPrincipal), debugstr_a(pszPackage), fCredentialUse,
+     pLogonID, pAuthData, pGetKeyFn, pGetKeyArgument, phCredential, ptsExpiry);
+    return nego_AcquireCredentialsHandle(fCredentialUse, phCredential,
+            ptsExpiry);
+}
+
+/***********************************************************************
+ *              AcquireCredentialsHandleW (SECUR32.@)
+ */
+static SECURITY_STATUS SEC_ENTRY nego_AcquireCredentialsHandleW(
+ SEC_WCHAR *pszPrincipal, SEC_WCHAR *pszPackage, ULONG fCredentialUse,
+ PLUID pLogonID, PVOID pAuthData, SEC_GET_KEY_FN pGetKeyFn,
+ PVOID pGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry)
+{
+    TRACE("(%s, %s, 0x%08lx, %p, %p, %p, %p, %p, %p)\n",
+     debugstr_w(pszPrincipal), debugstr_w(pszPackage), fCredentialUse,
+     pLogonID, pAuthData, pGetKeyFn, pGetKeyArgument, phCredential, ptsExpiry);
+    return nego_AcquireCredentialsHandle(fCredentialUse, phCredential,
+            ptsExpiry);
+}
+
+/***********************************************************************
+ *              InitializeSecurityContextA (SECUR32.@)
+ */
+static SECURITY_STATUS SEC_ENTRY nego_InitializeSecurityContextA(
+ PCredHandle phCredential, PCtxtHandle phContext, SEC_CHAR *pszTargetName, 
+ ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep, 
+ PSecBufferDesc pInput, ULONG Reserved2, PCtxtHandle phNewContext, 
+ PSecBufferDesc pOutput, ULONG *pfContextAttr, PTimeStamp ptsExpiry)
+{
+    SECURITY_STATUS ret;
+
+    TRACE("%p %p %s %ld %ld %ld %p %ld %p %p %p %p\n", phCredential, phContext,
+     debugstr_a(pszTargetName), fContextReq, Reserved1, TargetDataRep, pInput,
+     Reserved1, phNewContext, pOutput, pfContextAttr, ptsExpiry);
+    if(phCredential){
+        ret = SEC_E_UNSUPPORTED_FUNCTION;
+    }
+    else
+    {
+        ret = SEC_E_INVALID_HANDLE;
+    }
+    return ret;
+}
+
+/***********************************************************************
+ *              InitializeSecurityContextW (SECUR32.@)
+ */
+SECURITY_STATUS SEC_ENTRY nego_InitializeSecurityContextW(
+ PCredHandle phCredential, PCtxtHandle phContext, SEC_WCHAR *pszTargetName,
+ ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep, 
+ PSecBufferDesc pInput,ULONG Reserved2, PCtxtHandle phNewContext, 
+ PSecBufferDesc pOutput, ULONG *pfContextAttr, PTimeStamp ptsExpiry)
+{
+    SECURITY_STATUS ret;
+
+    TRACE("%p %p %s %ld %ld %ld %p %ld %p %p %p %p\n", phCredential, phContext,
+     debugstr_w(pszTargetName), fContextReq, Reserved1, TargetDataRep, pInput,
+     Reserved1, phNewContext, pOutput, pfContextAttr, ptsExpiry);
+    if (phCredential)
+    {
+        ret = SEC_E_UNSUPPORTED_FUNCTION;
+    }
+    else
+    {
+        ret = SEC_E_INVALID_HANDLE;
+    }
+    return ret;
+}
+
+/***********************************************************************
+ *              AcceptSecurityContext (SECUR32.@)
+ */
+SECURITY_STATUS SEC_ENTRY nego_AcceptSecurityContext(
+ PCredHandle phCredential, PCtxtHandle phContext, PSecBufferDesc pInput,
+ ULONG fContextReq, ULONG TargetDataRep, PCtxtHandle phNewContext, 
+ PSecBufferDesc pOutput, ULONG *pfContextAttr, PTimeStamp ptsExpiry)
+{
+    SECURITY_STATUS ret;
+
+    TRACE("%p %p %p %ld %ld %p %p %p %p\n", phCredential, phContext, pInput,
+     fContextReq, TargetDataRep, phNewContext, pOutput, pfContextAttr,
+     ptsExpiry);
+    if (phCredential)
+    {
+        ret = SEC_E_UNSUPPORTED_FUNCTION;
+    }
+    else
+    {
+        ret = SEC_E_INVALID_HANDLE;
+    }
+    return ret;
+}
+
+/***********************************************************************
+ *              CompleteAuthToken (SECUR32.@)
+ */
+SECURITY_STATUS SEC_ENTRY nego_CompleteAuthToken(PCtxtHandle phContext,
+ PSecBufferDesc pToken)
+{
+    SECURITY_STATUS ret;
+
+    TRACE("%p %p\n", phContext, pToken);
+    if (phContext)
+    {
+        ret = SEC_E_UNSUPPORTED_FUNCTION;
+    }
+    else
+    {
+        ret = SEC_E_INVALID_HANDLE;
+    }
+    return ret;
+}
+
+/***********************************************************************
+ *              DeleteSecurityContext (SECUR32.@)
+ */
+SECURITY_STATUS SEC_ENTRY nego_DeleteSecurityContext(PCtxtHandle phContext)
+{
+    SECURITY_STATUS ret;
+
+    TRACE("%p\n", phContext);
+    if (phContext)
+    {
+        ret = SEC_E_UNSUPPORTED_FUNCTION;
+    }
+    else
+    {
+        ret = SEC_E_INVALID_HANDLE;
+    }
+    return ret;
+}
+
+/***********************************************************************
+ *              ApplyControlToken (SECUR32.@)
+ */
+SECURITY_STATUS SEC_ENTRY nego_ApplyControlToken(PCtxtHandle phContext,
+ PSecBufferDesc pInput)
+{
+    SECURITY_STATUS ret;
+
+    TRACE("%p %p\n", phContext, pInput);
+    if (phContext)
+    {
+        ret = SEC_E_UNSUPPORTED_FUNCTION;
+    }
+    else
+    {
+        ret = SEC_E_INVALID_HANDLE;
+    }
+    return ret;
+}
+
+/***********************************************************************
+ *              QueryContextAttributesW (SECUR32.@)
+ */
+SECURITY_STATUS SEC_ENTRY nego_QueryContextAttributesW(PCtxtHandle phContext,
+ unsigned long ulAttribute, void *pBuffer)
+{
+    SECURITY_STATUS ret;
+
+    /* FIXME: From reading wrapper.h, I think the dwUpper part of a context is
+     * the SecurePackage part and the dwLower part is the actual context 
+     * handle. It should be easy to extract the context attributes from that.
+     */
+    TRACE("%p %ld %p\n", phContext, ulAttribute, pBuffer);
+    if (phContext)
+    {
+        ret = SEC_E_UNSUPPORTED_FUNCTION;
+    }
+    else
+    {
+        ret = SEC_E_INVALID_HANDLE;
+    }
+    return ret;
+}
+
+/***********************************************************************
+ *              QueryContextAttributesA (SECUR32.@)
+ */
+SECURITY_STATUS SEC_ENTRY nego_QueryContextAttributesA(PCtxtHandle phContext,
+ unsigned long ulAttribute, void *pBuffer)
+{
+    return nego_QueryContextAttributesW(phContext, ulAttribute, pBuffer);
+}
+
+/***********************************************************************
+ *              ImpersonateSecurityContext (SECUR32.@)
+ */
+SECURITY_STATUS SEC_ENTRY nego_ImpersonateSecurityContext(PCtxtHandle phContext)
+{
+    SECURITY_STATUS ret;
+
+    TRACE("%p\n", phContext);
+    if (phContext)
+    {
+        ret = SEC_E_UNSUPPORTED_FUNCTION;
+    }
+    else
+    {
+        ret = SEC_E_INVALID_HANDLE;
+    }
+    return ret;
+}
+
+/***********************************************************************
+ *              RevertSecurityContext (SECUR32.@)
+ */
+SECURITY_STATUS SEC_ENTRY nego_RevertSecurityContext(PCtxtHandle phContext)
+{
+    SECURITY_STATUS ret;
+
+    TRACE("%p\n", phContext);
+    if (phContext)
+    {
+        ret = SEC_E_UNSUPPORTED_FUNCTION;
+    }
+    else
+    {
+        ret = SEC_E_INVALID_HANDLE;
+    }
+    return ret;
+}
+
+/***********************************************************************
+ *              MakeSignature (SECUR32.@)
+ */
+SECURITY_STATUS SEC_ENTRY nego_MakeSignature(PCtxtHandle phContext, ULONG fQOP,
+ PSecBufferDesc pMessage, ULONG MessageSeqNo)
+{
+    SECURITY_STATUS ret;
+
+    TRACE("%p %ld %p %ld\n", phContext, fQOP, pMessage, MessageSeqNo);
+    if (phContext)
+    {
+        ret = SEC_E_UNSUPPORTED_FUNCTION;
+    }
+    else
+    {
+        ret = SEC_E_INVALID_HANDLE;
+    }
+    return ret;
+}
+
+/***********************************************************************
+ *              VerifySignature (SECUR32.@)
+ */
+SECURITY_STATUS SEC_ENTRY nego_VerifySignature(PCtxtHandle phContext,
+ PSecBufferDesc pMessage, ULONG MessageSeqNo, PULONG pfQOP)
+{
+    SECURITY_STATUS ret;
+
+    TRACE("%p %p %ld %p\n", phContext, pMessage, MessageSeqNo, pfQOP);
+    if (phContext)
+    {
+        ret = SEC_E_UNSUPPORTED_FUNCTION;
+    }
+    else
+    {
+        ret = SEC_E_INVALID_HANDLE;
+    }
+    return ret;
+}
+
+
+
+static SecurityFunctionTableA negoTableA = {
+    1,
+    NULL,   /* EnumerateSecurityPackagesA */
+    nego_QueryCredentialsAttributesA,   /* QueryCredentialsAttributesA */
+    nego_AcquireCredentialsHandleA,     /* AcquireCredentialsHandleA */
+    FreeCredentialsHandle,              /* FreeCredentialsHandle */
+    NULL,   /* Reserved2 */
+    nego_InitializeSecurityContextA,    /* InitializeSecurityContextA */
+    nego_AcceptSecurityContext,         /* AcceptSecurityContext */
+    nego_CompleteAuthToken,             /* CompleteAuthToken */
+    nego_DeleteSecurityContext,         /* DeleteSecurityContext */
+    nego_ApplyControlToken,             /* ApplyControlToken */
+    nego_QueryContextAttributesA,       /* QueryContextAttributesA */
+    nego_ImpersonateSecurityContext,    /* ImpersonateSecurityContext */
+    nego_RevertSecurityContext,         /* RevertSecurityContext */
+    nego_MakeSignature,                 /* MakeSignature */
+    nego_VerifySignature,               /* VerifySignature */
+    FreeContextBuffer,                  /* FreeContextBuffer */
+    NULL,   /* QuerySecurityPackageInfoA */
+    NULL,   /* Reserved3 */
+    NULL,   /* Reserved4 */
+    NULL,   /* ExportSecurityContext */
+    NULL,   /* ImportSecurityContextA */
+    NULL,   /* AddCredentialsA */
+    NULL,   /* Reserved8 */
+    NULL,   /* QuerySecurityContextToken */
+    NULL,   /* EncryptMessage */
+    NULL,   /* DecryptMessage */
+    NULL,   /* SetContextAttributesA */
+};
+
+static SecurityFunctionTableW negoTableW = {
+    1,
+    NULL,   /* EnumerateSecurityPackagesW */
+    nego_QueryCredentialsAttributesW,   /* QueryCredentialsAttributesW */
+    nego_AcquireCredentialsHandleW,     /* AcquireCredentialsHandleW */
+    FreeCredentialsHandle,              /* FreeCredentialsHandle */
+    NULL,   /* Reserved2 */
+    nego_InitializeSecurityContextW,    /* InitializeSecurityContextW */
+    nego_AcceptSecurityContext,         /* AcceptSecurityContext */
+    nego_CompleteAuthToken,             /* CompleteAuthToken */
+    nego_DeleteSecurityContext,         /* DeleteSecurityContext */
+    nego_ApplyControlToken,             /* ApplyControlToken */
+    nego_QueryContextAttributesW,       /* QueryContextAttributesW */
+    nego_ImpersonateSecurityContext,    /* ImpersonateSecurityContext */
+    nego_RevertSecurityContext,         /* RevertSecurityContext */
+    nego_MakeSignature,                 /* MakeSignature */
+    nego_VerifySignature,               /* VerifySignature */
+    FreeContextBuffer,                  /* FreeContextBuffer */
+    NULL,   /* QuerySecurityPackageInfoW */
+    NULL,   /* Reserved3 */
+    NULL,   /* Reserved4 */
+    NULL,   /* ExportSecurityContext */
+    NULL,   /* ImportSecurityContextW */
+    NULL,   /* AddCredentialsW */
+    NULL,   /* Reserved8 */
+    NULL,   /* QuerySecurityContextToken */
+    NULL,   /* EncryptMessage */
+    NULL,   /* DecryptMessage */
+    NULL,   /* SetContextAttributesW */
+};
+
+static const WCHAR negotiate_comment_W[] = { 'M', 'i', 'c', 'r', 'o', 's', 'o', 
+    'f', 't', ' ', 'P', 'a', 'c', 'k', 'a', 'g', 'e', ' ', 'N', 'e', 'g', 'o',
+    't', 'i', 'a', 't', 'o', 'r', 0};
+
+static const CHAR negotiate_comment_A[] = "Microsoft Package Negotiator";
+
+
+
+void SECUR32_initNegotiateSP(void)
+{
+    SecureProvider *provider = SECUR32_addProvider(&negoTableA, &negoTableW,
+            NULL);
+    /* According to Windows, Negotiate has the following capabilities. 
+     */
+    
+    static const LONG caps = 
+        SECPKG_FLAG_INTEGRITY |
+	    SECPKG_FLAG_PRIVACY |
+	    SECPKG_FLAG_CONNECTION |
+        SECPKG_FLAG_MULTI_REQUIRED |
+	    SECPKG_FLAG_EXTENDED_ERROR |
+	    SECPKG_FLAG_IMPERSONATION |
+	    SECPKG_FLAG_ACCEPT_WIN32_NAME |
+	    SECPKG_FLAG_READONLY_WITH_CHECKSUM;
+
+    static const USHORT version = 1;
+    static const USHORT rpcid = 15;
+    static const ULONG  max_token = 12000;
+    const SecPkgInfoW infoW = { caps, version, rpcid, max_token, nego_name_W, 
+        negotiate_comment_W};
+    const SecPkgInfoA infoA = { caps, version, rpcid, max_token, nego_name_A,
+        negotiate_comment_A};
+
+    SECUR32_addPackages(provider, 1L, &infoA, &infoW);        
+    
+}
+    


More information about the wine-patches mailing list