oleaut32: Add a test for loading/saving an empty picture.
[wine] / dlls / secur32 / wrapper.c
1 /* Copyright (C) 2004 Juan Lang
2  *
3  * Implements secur32 functions that forward to (wrap) an SSP's implementation.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18  */
19 #include <stdarg.h>
20 #include "windef.h"
21 #include "winbase.h"
22 #include "winnls.h"
23 #include "sspi.h"
24 #include "secur32_priv.h"
25
26 #include "wine/debug.h"
27
28 WINE_DEFAULT_DEBUG_CHANNEL(secur32);
29
30 /* Tries to allocate a new SecHandle, into which it stores package (in
31  * phSec->dwUpper) and a copy of realHandle (allocated with SECUR32_ALLOC,
32  * and stored in phSec->dwLower).  SecHandle is equivalent to both a
33  * CredHandle and a CtxtHandle.
34  */
35 static SECURITY_STATUS SECUR32_makeSecHandle(PSecHandle phSec,
36  SecurePackage *package, PSecHandle realHandle)
37 {
38     SECURITY_STATUS ret;
39
40     TRACE("%p %p %p\n", phSec, package, realHandle);
41
42     if (phSec && package && realHandle)
43     {
44         PSecHandle newSec = HeapAlloc(GetProcessHeap(), 0, sizeof(SecHandle));
45
46         if (newSec)
47         {
48             *newSec = *realHandle;
49             phSec->dwUpper = (ULONG_PTR)package;
50             phSec->dwLower = (ULONG_PTR)newSec;
51             ret = SEC_E_OK;
52         }
53         else
54             ret = SEC_E_INSUFFICIENT_MEMORY;
55     }
56     else
57         ret = SEC_E_INVALID_HANDLE;
58     return ret;
59 }
60
61 /***********************************************************************
62  *              AcquireCredentialsHandleA (SECUR32.@)
63  */
64 SECURITY_STATUS WINAPI AcquireCredentialsHandleA(
65  SEC_CHAR *pszPrincipal, SEC_CHAR *pszPackage, ULONG fCredentialsUse,
66  PLUID pvLogonID, PVOID pAuthData, SEC_GET_KEY_FN pGetKeyFn,
67  PVOID pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry)
68 {
69     SECURITY_STATUS ret;
70
71     TRACE("%s %s %d %p %p %p %p %p %p\n", debugstr_a(pszPrincipal),
72      debugstr_a(pszPackage), fCredentialsUse, pvLogonID, pAuthData, pGetKeyFn,
73      pvGetKeyArgument, phCredential, ptsExpiry);
74     if (pszPackage)
75     {
76         SecurePackage *package = SECUR32_findPackageA(pszPackage);
77
78         if (package && package->provider)
79         {
80             if (package->provider->fnTableA.AcquireCredentialsHandleA)
81             {
82                 CredHandle myCred;
83
84                 ret = package->provider->fnTableA.AcquireCredentialsHandleA(
85                  pszPrincipal, pszPackage, fCredentialsUse, pvLogonID,
86                  pAuthData, pGetKeyFn, pvGetKeyArgument, &myCred,
87                  ptsExpiry);
88                 if (ret == SEC_E_OK)
89                 {
90                     ret = SECUR32_makeSecHandle(phCredential, package, &myCred);
91                     if (ret != SEC_E_OK)
92                         package->provider->fnTableW.FreeCredentialsHandle(
93                          &myCred);
94                 }
95             }
96             else
97                 ret = SEC_E_UNSUPPORTED_FUNCTION;
98         }
99         else
100             ret = SEC_E_SECPKG_NOT_FOUND;
101     }
102     else
103         ret = SEC_E_SECPKG_NOT_FOUND;
104     return ret;
105 }
106
107 /***********************************************************************
108  *              AcquireCredentialsHandleW (SECUR32.@)
109  */
110 SECURITY_STATUS WINAPI AcquireCredentialsHandleW(
111  SEC_WCHAR *pszPrincipal, SEC_WCHAR *pszPackage, ULONG fCredentialsUse,
112  PLUID pvLogonID, PVOID pAuthData, SEC_GET_KEY_FN pGetKeyFn,
113  PVOID pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry)
114 {
115     SECURITY_STATUS ret;
116
117     TRACE("%s %s %d %p %p %p %p %p %p\n", debugstr_w(pszPrincipal),
118      debugstr_w(pszPackage), fCredentialsUse, pvLogonID, pAuthData, pGetKeyFn,
119      pvGetKeyArgument, phCredential, ptsExpiry);
120     if (pszPackage)
121     {
122         SecurePackage *package = SECUR32_findPackageW(pszPackage);
123
124         if (package && package->provider)
125         {
126             if (package->provider->fnTableW.AcquireCredentialsHandleW)
127             {
128                 CredHandle myCred;
129
130                 ret = package->provider->fnTableW.AcquireCredentialsHandleW(
131                  pszPrincipal, pszPackage, fCredentialsUse, pvLogonID,
132                  pAuthData, pGetKeyFn, pvGetKeyArgument, &myCred,
133                  ptsExpiry);
134                 if (ret == SEC_E_OK)
135                 {
136                     ret = SECUR32_makeSecHandle(phCredential, package, &myCred);
137                     if (ret != SEC_E_OK)
138                         package->provider->fnTableW.FreeCredentialsHandle(
139                          &myCred);
140                 }
141             }
142             else
143                 ret = SEC_E_UNSUPPORTED_FUNCTION;
144         }
145         else
146             ret = SEC_E_SECPKG_NOT_FOUND;
147     }
148     else
149         ret = SEC_E_SECPKG_NOT_FOUND;
150     return ret;
151 }
152
153 /***********************************************************************
154  *              FreeCredentialsHandle (SECUR32.@)
155  */
156 SECURITY_STATUS WINAPI FreeCredentialsHandle(
157  PCredHandle phCredential)
158 {
159     SECURITY_STATUS ret;
160
161     TRACE("%p\n", phCredential);
162     if (phCredential)
163     {
164         SecurePackage *package = (SecurePackage *)phCredential->dwUpper;
165         PCredHandle cred = (PCredHandle)phCredential->dwLower;
166
167         if (package && package->provider &&
168          package->provider->fnTableW.FreeCredentialsHandle)
169             ret = package->provider->fnTableW.FreeCredentialsHandle(cred);
170         else
171             ret = SEC_E_INVALID_HANDLE;
172         HeapFree(GetProcessHeap(), 0, cred);
173     }
174     else
175         ret = SEC_E_INVALID_HANDLE;
176     return ret;
177 }
178
179 /***********************************************************************
180  *              QueryCredentialsAttributesA (SECUR32.@)
181  */
182 SECURITY_STATUS WINAPI QueryCredentialsAttributesA(
183  PCredHandle phCredential, ULONG ulAttribute, void *pBuffer)
184 {
185     SECURITY_STATUS ret;
186
187     TRACE("%p %d %p\n", phCredential, ulAttribute, pBuffer);
188     if (phCredential)
189     {
190         SecurePackage *package = (SecurePackage *)phCredential->dwUpper;
191         PCredHandle cred = (PCredHandle)phCredential->dwLower;
192
193         if (package && package->provider)
194         {
195             if (package->provider->fnTableA.QueryCredentialsAttributesA)
196                 ret = package->provider->fnTableA.QueryCredentialsAttributesA(
197                  cred, ulAttribute, pBuffer);
198             else
199                 ret = SEC_E_UNSUPPORTED_FUNCTION;
200         }
201         else
202             ret = SEC_E_INVALID_HANDLE;
203     }
204     else
205         ret = SEC_E_INVALID_HANDLE;
206     return ret;
207 }
208
209 /***********************************************************************
210  *              QueryCredentialsAttributesW (SECUR32.@)
211  */
212 SECURITY_STATUS WINAPI QueryCredentialsAttributesW(
213  PCredHandle phCredential, ULONG ulAttribute, void *pBuffer)
214 {
215     SECURITY_STATUS ret;
216
217     TRACE("%p %d %p\n", phCredential, ulAttribute, pBuffer);
218     if (phCredential)
219     {
220         SecurePackage *package = (SecurePackage *)phCredential->dwUpper;
221         PCredHandle cred = (PCredHandle)phCredential->dwLower;
222
223         if (package && package->provider)
224         {
225             if (package->provider->fnTableW.QueryCredentialsAttributesW)
226                 ret = package->provider->fnTableW.QueryCredentialsAttributesW(
227                  cred, ulAttribute, pBuffer);
228             else
229                 ret = SEC_E_UNSUPPORTED_FUNCTION;
230         }
231         else
232             ret = SEC_E_INVALID_HANDLE;
233     }
234     else
235         ret = SEC_E_INVALID_HANDLE;
236     return ret;
237 }
238
239 /***********************************************************************
240  *              InitializeSecurityContextA (SECUR32.@)
241  */
242 SECURITY_STATUS WINAPI InitializeSecurityContextA(
243  PCredHandle phCredential, PCtxtHandle phContext,
244  SEC_CHAR *pszTargetName, ULONG fContextReq,
245  ULONG Reserved1, ULONG TargetDataRep, PSecBufferDesc pInput,
246  ULONG Reserved2, PCtxtHandle phNewContext, PSecBufferDesc pOutput,
247  ULONG *pfContextAttr, PTimeStamp ptsExpiry)
248 {
249     SECURITY_STATUS ret;
250     SecurePackage *package = NULL;
251     PCredHandle cred = NULL;
252     PCredHandle ctxt = NULL;
253
254     TRACE("%p %p %s 0x%08x %d %d %p %d %p %p %p %p\n", phCredential, phContext,
255      debugstr_a(pszTargetName), fContextReq, Reserved1, TargetDataRep, pInput,
256      Reserved1, phNewContext, pOutput, pfContextAttr, ptsExpiry);
257
258     if (phContext)
259     {
260         package = (SecurePackage *)phContext->dwUpper;
261         ctxt = (PCtxtHandle)phContext->dwLower;
262     }
263     if (phCredential)
264     {
265         package = (SecurePackage *)phCredential->dwUpper;
266         cred = (PCredHandle)phCredential->dwLower;
267     }
268
269     if (package && package->provider)
270     {
271         if (package->provider->fnTableA.InitializeSecurityContextA)
272         {
273             CtxtHandle myCtxt;
274
275             if (phContext)
276             {
277                 PCtxtHandle realCtxt = (PCtxtHandle)phContext->dwLower;
278                 myCtxt.dwUpper = realCtxt->dwUpper;
279                 myCtxt.dwLower = realCtxt->dwLower;
280             }
281
282             ret = package->provider->fnTableA.InitializeSecurityContextA(
283                  cred, ctxt, pszTargetName, fContextReq,
284                  Reserved1, TargetDataRep, pInput, Reserved2, phNewContext ? &myCtxt : NULL,
285                  pOutput, pfContextAttr, ptsExpiry);
286             if ((ret == SEC_E_OK || ret == SEC_I_CONTINUE_NEEDED) &&
287                 phNewContext && phNewContext != phContext)
288             {
289                 SECURITY_STATUS ret2;
290                 ret2 = SECUR32_makeSecHandle(phNewContext, package, &myCtxt);
291                 if (ret2 != SEC_E_OK)
292                     package->provider->fnTableA.DeleteSecurityContext(&myCtxt);
293             }
294         }
295         else
296             ret = SEC_E_UNSUPPORTED_FUNCTION;
297     }
298     else
299         ret = SEC_E_INVALID_HANDLE;
300     return ret;
301 }
302
303 /***********************************************************************
304  *              InitializeSecurityContextW (SECUR32.@)
305  */
306 SECURITY_STATUS WINAPI InitializeSecurityContextW(
307  PCredHandle phCredential, PCtxtHandle phContext,
308  SEC_WCHAR *pszTargetName, ULONG fContextReq,
309  ULONG Reserved1, ULONG TargetDataRep, PSecBufferDesc pInput,
310  ULONG Reserved2, PCtxtHandle phNewContext, PSecBufferDesc pOutput,
311  ULONG *pfContextAttr, PTimeStamp ptsExpiry)
312 {
313     SECURITY_STATUS ret;
314     SecurePackage *package = NULL;
315     PCredHandle cred = NULL;
316     PCredHandle ctxt = NULL;
317
318     TRACE("%p %p %s %d %d %d %p %d %p %p %p %p\n", phCredential, phContext,
319      debugstr_w(pszTargetName), fContextReq, Reserved1, TargetDataRep, pInput,
320      Reserved1, phNewContext, pOutput, pfContextAttr, ptsExpiry);
321
322     if (phContext)
323     {
324         package = (SecurePackage *)phContext->dwUpper;
325         ctxt = (PCtxtHandle)phContext->dwLower;
326     }
327     if (phCredential)
328     {
329         package = (SecurePackage *)phCredential->dwUpper;
330         cred = (PCredHandle)phCredential->dwLower;
331     }
332
333     if (package && package->provider)
334     {
335         if (package->provider->fnTableW.InitializeSecurityContextW)
336         {
337             CtxtHandle myCtxt;
338
339             if (phContext)
340             {
341                 PCtxtHandle realCtxt = (PCtxtHandle)phContext->dwLower;
342                 myCtxt.dwUpper = realCtxt->dwUpper;
343                 myCtxt.dwLower = realCtxt->dwLower;
344             }
345
346             ret = package->provider->fnTableW.InitializeSecurityContextW(
347                  cred, ctxt, pszTargetName, fContextReq,
348                  Reserved1, TargetDataRep, pInput, Reserved2, phNewContext ? &myCtxt : NULL,
349                  pOutput, pfContextAttr, ptsExpiry);
350             if ((ret == SEC_E_OK || ret == SEC_I_CONTINUE_NEEDED) &&
351                 phNewContext && phNewContext != phContext)
352             {
353                 SECURITY_STATUS ret2;
354                 ret2 = SECUR32_makeSecHandle(phNewContext, package, &myCtxt);
355                 if (ret2 != SEC_E_OK)
356                     package->provider->fnTableW.DeleteSecurityContext(&myCtxt);
357             }
358         }
359         else
360             ret = SEC_E_UNSUPPORTED_FUNCTION;
361     }
362     else
363         ret = SEC_E_INVALID_HANDLE;
364     return ret;
365 }
366
367 /***********************************************************************
368  *              AcceptSecurityContext (SECUR32.@)
369  */
370 SECURITY_STATUS WINAPI AcceptSecurityContext(
371  PCredHandle phCredential, PCtxtHandle phContext, PSecBufferDesc pInput,
372  ULONG fContextReq, ULONG TargetDataRep, PCtxtHandle phNewContext,
373  PSecBufferDesc pOutput, ULONG *pfContextAttr, PTimeStamp ptsExpiry)
374 {
375     SECURITY_STATUS ret;
376
377     TRACE("%p %p %p %d %d %p %p %p %p\n", phCredential, phContext, pInput,
378      fContextReq, TargetDataRep, phNewContext, pOutput, pfContextAttr,
379      ptsExpiry);
380     if (phCredential)
381     {
382         SecurePackage *package = (SecurePackage *)phCredential->dwUpper;
383         PCredHandle cred = (PCredHandle)phCredential->dwLower;
384
385         if (package && package->provider)
386         {
387             if (package->provider->fnTableW.AcceptSecurityContext)
388             {
389                 CtxtHandle myCtxt;
390
391                 if(phContext)
392                 {
393                     PCtxtHandle realCtxt = (PCtxtHandle)phContext->dwLower;
394                     TRACE("realCtx: %p\n", realCtxt);
395                     myCtxt.dwUpper = realCtxt->dwUpper;
396                     myCtxt.dwLower = realCtxt->dwLower;
397                 }
398                 
399                 ret = package->provider->fnTableW.AcceptSecurityContext(
400                  cred, phContext ? &myCtxt : NULL, pInput, fContextReq,
401                  TargetDataRep, &myCtxt, pOutput, pfContextAttr, ptsExpiry);
402                 if (ret == SEC_E_OK || ret == SEC_I_CONTINUE_NEEDED)
403                 {
404                     SECURITY_STATUS ret2;
405                     ret2 = SECUR32_makeSecHandle(phNewContext, package, &myCtxt);
406                     if (ret2 != SEC_E_OK)
407                         package->provider->fnTableW.DeleteSecurityContext(
408                          &myCtxt);
409                 }
410             }
411             else
412                 ret = SEC_E_UNSUPPORTED_FUNCTION;
413         }
414         else
415             ret = SEC_E_INVALID_HANDLE;
416     }
417     else
418         ret = SEC_E_INVALID_HANDLE;
419     return ret;
420 }
421
422 /***********************************************************************
423  *              CompleteAuthToken (SECUR32.@)
424  */
425 SECURITY_STATUS WINAPI CompleteAuthToken(PCtxtHandle phContext,
426  PSecBufferDesc pToken)
427 {
428     SECURITY_STATUS ret;
429
430     TRACE("%p %p\n", phContext, pToken);
431     if (phContext)
432     {
433         SecurePackage *package = (SecurePackage *)phContext->dwUpper;
434         PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
435
436         if (package && package->provider)
437         {
438             if (package->provider->fnTableW.CompleteAuthToken)
439                 ret = package->provider->fnTableW.CompleteAuthToken(ctxt,
440                  pToken);
441             else
442                 ret = SEC_E_UNSUPPORTED_FUNCTION;
443         }
444         else
445             ret = SEC_E_INVALID_HANDLE;
446     }
447     else
448         ret = SEC_E_INVALID_HANDLE;
449     return ret;
450 }
451
452 /***********************************************************************
453  *              DeleteSecurityContext (SECUR32.@)
454  */
455 SECURITY_STATUS WINAPI DeleteSecurityContext(PCtxtHandle phContext)
456 {
457     SECURITY_STATUS ret;
458
459     TRACE("%p\n", phContext);
460     if (phContext)
461     {
462         SecurePackage *package = (SecurePackage *)phContext->dwUpper;
463         PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
464
465         if (package && package->provider &&
466          package->provider->fnTableW.DeleteSecurityContext)
467             ret = package->provider->fnTableW.DeleteSecurityContext(ctxt);
468         else
469             ret = SEC_E_INVALID_HANDLE;
470         HeapFree(GetProcessHeap(), 0, ctxt);
471     }
472     else
473         ret = SEC_E_INVALID_HANDLE;
474     return ret;
475 }
476
477 /***********************************************************************
478  *              ApplyControlToken (SECUR32.@)
479  */
480 SECURITY_STATUS WINAPI ApplyControlToken(PCtxtHandle phContext,
481  PSecBufferDesc pInput)
482 {
483     SECURITY_STATUS ret;
484
485     TRACE("%p %p\n", phContext, pInput);
486     if (phContext)
487     {
488         SecurePackage *package = (SecurePackage *)phContext->dwUpper;
489         PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
490
491         if (package && package->provider)
492         {
493             if (package->provider->fnTableW.ApplyControlToken)
494                 ret = package->provider->fnTableW.ApplyControlToken(
495                  ctxt, pInput);
496             else
497                 ret = SEC_E_UNSUPPORTED_FUNCTION;
498         }
499         else
500             ret = SEC_E_INVALID_HANDLE;
501     }
502     else
503         ret = SEC_E_INVALID_HANDLE;
504     return ret;
505 }
506
507 /***********************************************************************
508  *              QueryContextAttributesA (SECUR32.@)
509  */
510 SECURITY_STATUS WINAPI QueryContextAttributesA(PCtxtHandle phContext,
511  ULONG ulAttribute, void *pBuffer)
512 {
513     SECURITY_STATUS ret;
514
515     TRACE("%p %d %p\n", phContext, ulAttribute, pBuffer);
516     if (phContext)
517     {
518         SecurePackage *package = (SecurePackage *)phContext->dwUpper;
519         PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
520
521         if (package && package->provider)
522         {
523             if (package->provider->fnTableA.QueryContextAttributesA)
524                 ret = package->provider->fnTableA.QueryContextAttributesA(
525                  ctxt, ulAttribute, pBuffer);
526             else
527                 ret = SEC_E_UNSUPPORTED_FUNCTION;
528         }
529         else
530             ret = SEC_E_INVALID_HANDLE;
531     }
532     else
533         ret = SEC_E_INVALID_HANDLE;
534     return ret;
535 }
536
537 /***********************************************************************
538  *              QueryContextAttributesW (SECUR32.@)
539  */
540 SECURITY_STATUS WINAPI QueryContextAttributesW(PCtxtHandle phContext,
541  ULONG ulAttribute, void *pBuffer)
542 {
543     SECURITY_STATUS ret;
544
545     TRACE("%p %d %p\n", phContext, ulAttribute, pBuffer);
546     if (phContext)
547     {
548         SecurePackage *package = (SecurePackage *)phContext->dwUpper;
549         PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
550
551         if (package && package->provider)
552         {
553             if (package->provider->fnTableW.QueryContextAttributesW)
554                 ret = package->provider->fnTableW.QueryContextAttributesW(
555                  ctxt, ulAttribute, pBuffer);
556             else
557                 ret = SEC_E_UNSUPPORTED_FUNCTION;
558         }
559         else
560             ret = SEC_E_INVALID_HANDLE;
561     }
562     else
563         ret = SEC_E_INVALID_HANDLE;
564     return ret;
565 }
566
567 /***********************************************************************
568  *              ImpersonateSecurityContext (SECUR32.@)
569  */
570 SECURITY_STATUS WINAPI ImpersonateSecurityContext(PCtxtHandle phContext)
571 {
572     SECURITY_STATUS ret;
573
574     TRACE("%p\n", phContext);
575     if (phContext)
576     {
577         SecurePackage *package = (SecurePackage *)phContext->dwUpper;
578         PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
579
580         if (package && package->provider)
581         {
582             if (package->provider->fnTableW.ImpersonateSecurityContext)
583                 ret = package->provider->fnTableW.ImpersonateSecurityContext(
584                  ctxt);
585             else
586                 ret = SEC_E_UNSUPPORTED_FUNCTION;
587         }
588         else
589             ret = SEC_E_INVALID_HANDLE;
590     }
591     else
592         ret = SEC_E_INVALID_HANDLE;
593     return ret;
594 }
595
596 /***********************************************************************
597  *              RevertSecurityContext (SECUR32.@)
598  */
599 SECURITY_STATUS WINAPI RevertSecurityContext(PCtxtHandle phContext)
600 {
601     SECURITY_STATUS ret;
602
603     TRACE("%p\n", phContext);
604     if (phContext)
605     {
606         SecurePackage *package = (SecurePackage *)phContext->dwUpper;
607         PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
608
609         if (package && package->provider)
610         {
611             if (package->provider->fnTableW.RevertSecurityContext)
612                 ret = package->provider->fnTableW.RevertSecurityContext(
613                  ctxt);
614             else
615                 ret = SEC_E_UNSUPPORTED_FUNCTION;
616         }
617         else
618             ret = SEC_E_INVALID_HANDLE;
619     }
620     else
621         ret = SEC_E_INVALID_HANDLE;
622     return ret;
623 }
624
625 /***********************************************************************
626  *              MakeSignature (SECUR32.@)
627  */
628 SECURITY_STATUS WINAPI MakeSignature(PCtxtHandle phContext, ULONG fQOP,
629  PSecBufferDesc pMessage, ULONG MessageSeqNo)
630 {
631     SECURITY_STATUS ret;
632
633     TRACE("%p %d %p %d\n", phContext, fQOP, pMessage, MessageSeqNo);
634     if (phContext)
635     {
636         SecurePackage *package = (SecurePackage *)phContext->dwUpper;
637         PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
638
639         if (package && package->provider)
640         {
641             if (package->provider->fnTableW.MakeSignature)
642                 ret = package->provider->fnTableW.MakeSignature(
643                  ctxt, fQOP, pMessage, MessageSeqNo);
644             else
645                 ret = SEC_E_UNSUPPORTED_FUNCTION;
646         }
647         else
648             ret = SEC_E_INVALID_HANDLE;
649     }
650     else
651         ret = SEC_E_INVALID_HANDLE;
652     return ret;
653 }
654
655 /***********************************************************************
656  *              VerifySignature (SECUR32.@)
657  */
658 SECURITY_STATUS WINAPI VerifySignature(PCtxtHandle phContext,
659  PSecBufferDesc pMessage, ULONG MessageSeqNo, PULONG pfQOP)
660 {
661     SECURITY_STATUS ret;
662
663     TRACE("%p %p %d %p\n", phContext, pMessage, MessageSeqNo, pfQOP);
664     if (phContext)
665     {
666         SecurePackage *package = (SecurePackage *)phContext->dwUpper;
667         PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
668
669         if (package && package->provider)
670         {
671             if (package->provider->fnTableW.VerifySignature)
672                 ret = package->provider->fnTableW.VerifySignature(
673                  ctxt, pMessage, MessageSeqNo, pfQOP);
674             else
675                 ret = SEC_E_UNSUPPORTED_FUNCTION;
676         }
677         else
678             ret = SEC_E_INVALID_HANDLE;
679     }
680     else
681         ret = SEC_E_INVALID_HANDLE;
682     return ret;
683 }
684
685 /***********************************************************************
686  *              QuerySecurityPackageInfoA (SECUR32.@)
687  */
688 SECURITY_STATUS WINAPI QuerySecurityPackageInfoA(SEC_CHAR *pszPackageName,
689  PSecPkgInfoA *ppPackageInfo)
690 {
691     SECURITY_STATUS ret;
692    
693     TRACE("%s %p\n", debugstr_a(pszPackageName), ppPackageInfo);
694     if (pszPackageName)
695     {
696         SecurePackage *package = SECUR32_findPackageA(pszPackageName);
697
698         if (package)
699         {
700             size_t bytesNeeded = sizeof(SecPkgInfoA);
701             int nameLen = 0, commentLen = 0;
702
703             if (package->infoW.Name)
704             {
705                 nameLen = WideCharToMultiByte(CP_ACP, 0,
706                  package->infoW.Name, -1, NULL, 0, NULL, NULL);
707                 bytesNeeded += nameLen;
708             }
709             if (package->infoW.Comment)
710             {
711                 commentLen = WideCharToMultiByte(CP_ACP, 0,
712                  package->infoW.Comment, -1, NULL, 0, NULL, NULL);
713                 bytesNeeded += commentLen;
714             }
715             *ppPackageInfo = HeapAlloc(GetProcessHeap(), 0, bytesNeeded);
716             if (*ppPackageInfo)
717             {
718                 PSTR nextString = (PSTR)((PBYTE)*ppPackageInfo +
719                  sizeof(SecPkgInfoA));
720
721                 memcpy(*ppPackageInfo, &package->infoW, sizeof(package->infoW));
722                 if (package->infoW.Name)
723                 {
724                     (*ppPackageInfo)->Name = nextString;
725                     nextString += WideCharToMultiByte(CP_ACP, 0,
726                      package->infoW.Name, -1, nextString, nameLen, NULL, NULL);
727                 }
728                 else
729                     (*ppPackageInfo)->Name = NULL;
730                 if (package->infoW.Comment)
731                 {
732                     (*ppPackageInfo)->Comment = nextString;
733                     nextString += WideCharToMultiByte(CP_ACP, 0,
734                      package->infoW.Comment, -1, nextString, commentLen, NULL,
735                      NULL);
736                 }
737                 else
738                     (*ppPackageInfo)->Comment = NULL;
739                 ret = SEC_E_OK;
740             }
741             else
742                 ret = SEC_E_INSUFFICIENT_MEMORY;
743         }
744         else
745             ret = SEC_E_SECPKG_NOT_FOUND;
746     }
747     else
748         ret = SEC_E_SECPKG_NOT_FOUND;
749     return ret;
750 }
751
752 /***********************************************************************
753  *              QuerySecurityPackageInfoW (SECUR32.@)
754  */
755 SECURITY_STATUS WINAPI QuerySecurityPackageInfoW(SEC_WCHAR *pszPackageName,
756  PSecPkgInfoW *ppPackageInfo)
757 {
758     SECURITY_STATUS ret;
759     SecurePackage *package = SECUR32_findPackageW(pszPackageName);
760
761     TRACE("%s %p\n", debugstr_w(pszPackageName), ppPackageInfo);
762     if (package)
763     {
764         size_t bytesNeeded = sizeof(SecPkgInfoW);
765         int nameLen = 0, commentLen = 0;
766
767         if (package->infoW.Name)
768         {
769             nameLen = lstrlenW(package->infoW.Name) + 1;
770             bytesNeeded += nameLen * sizeof(WCHAR);
771         }
772         if (package->infoW.Comment)
773         {
774             commentLen = lstrlenW(package->infoW.Comment) + 1;
775             bytesNeeded += commentLen * sizeof(WCHAR);
776         }
777         *ppPackageInfo = HeapAlloc(GetProcessHeap(), 0, bytesNeeded);
778         if (*ppPackageInfo)
779         {
780             PWSTR nextString = (PWSTR)((PBYTE)*ppPackageInfo +
781              sizeof(SecPkgInfoW));
782
783             **ppPackageInfo = package->infoW;
784             if (package->infoW.Name)
785             {
786                 (*ppPackageInfo)->Name = nextString;
787                 lstrcpynW(nextString, package->infoW.Name, nameLen);
788                 nextString += nameLen;
789             }
790             else
791                 (*ppPackageInfo)->Name = NULL;
792             if (package->infoW.Comment)
793             {
794                 (*ppPackageInfo)->Comment = nextString;
795                 lstrcpynW(nextString, package->infoW.Comment, commentLen);
796             }
797             else
798                 (*ppPackageInfo)->Comment = NULL;
799             ret = SEC_E_OK;
800         }
801         else
802             ret = SEC_E_INSUFFICIENT_MEMORY;
803     }
804     else
805         ret = SEC_E_SECPKG_NOT_FOUND;
806     return ret;
807 }
808
809 /***********************************************************************
810  *              ExportSecurityContext (SECUR32.@)
811  */
812 SECURITY_STATUS WINAPI ExportSecurityContext(PCtxtHandle phContext,
813  ULONG fFlags, PSecBuffer pPackedContext, void **pToken)
814 {
815     SECURITY_STATUS ret;
816
817     TRACE("%p %d %p %p\n", phContext, fFlags, pPackedContext, pToken);
818     if (phContext)
819     {
820         SecurePackage *package = (SecurePackage *)phContext->dwUpper;
821         PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
822
823         if (package && package->provider)
824         {
825             if (package->provider->fnTableW.ExportSecurityContext)
826                 ret = package->provider->fnTableW.ExportSecurityContext(
827                  ctxt, fFlags, pPackedContext, pToken);
828             else
829                 ret = SEC_E_UNSUPPORTED_FUNCTION;
830         }
831         else
832             ret = SEC_E_INVALID_HANDLE;
833     }
834     else
835         ret = SEC_E_INVALID_HANDLE;
836     return ret;
837 }
838
839 /***********************************************************************
840  *              ImportSecurityContextA (SECUR32.@)
841  */
842 SECURITY_STATUS WINAPI ImportSecurityContextA(SEC_CHAR *pszPackage,
843  PSecBuffer pPackedContext, void *Token, PCtxtHandle phContext)
844 {
845     SECURITY_STATUS ret;
846     SecurePackage *package = SECUR32_findPackageA(pszPackage);
847  
848     TRACE("%s %p %p %p\n", debugstr_a(pszPackage), pPackedContext, Token,
849      phContext);
850     if (package && package->provider)
851     {
852         if (package->provider->fnTableA.ImportSecurityContextA)
853         {
854             CtxtHandle myCtxt;
855
856             ret = package->provider->fnTableA.ImportSecurityContextA(
857              pszPackage, pPackedContext, Token, &myCtxt);
858             if (ret == SEC_E_OK)
859             {
860                 ret = SECUR32_makeSecHandle(phContext, package, &myCtxt);
861                 if (ret != SEC_E_OK)
862                     package->provider->fnTableW.DeleteSecurityContext(&myCtxt);
863             }
864         }
865         else
866             ret = SEC_E_UNSUPPORTED_FUNCTION;
867     }
868     else
869         ret = SEC_E_SECPKG_NOT_FOUND;
870     return ret;
871
872 }
873
874 /***********************************************************************
875  *              ImportSecurityContextW (SECUR32.@)
876  */
877 SECURITY_STATUS WINAPI ImportSecurityContextW(SEC_WCHAR *pszPackage,
878  PSecBuffer pPackedContext, void *Token, PCtxtHandle phContext)
879 {
880     SECURITY_STATUS ret;
881     SecurePackage *package = SECUR32_findPackageW(pszPackage);
882
883     TRACE("%s %p %p %p\n", debugstr_w(pszPackage), pPackedContext, Token,
884      phContext);
885     if (package && package->provider)
886     {
887         if (package->provider->fnTableW.ImportSecurityContextW)
888         {
889             CtxtHandle myCtxt;
890
891             ret = package->provider->fnTableW.ImportSecurityContextW(
892              pszPackage, pPackedContext, Token, &myCtxt);
893             if (ret == SEC_E_OK)
894             {
895                 ret = SECUR32_makeSecHandle(phContext, package, &myCtxt);
896                 if (ret != SEC_E_OK)
897                     package->provider->fnTableW.DeleteSecurityContext(&myCtxt);
898             }
899         }
900         else
901             ret = SEC_E_UNSUPPORTED_FUNCTION;
902     }
903     else
904         ret = SEC_E_SECPKG_NOT_FOUND;
905     return ret;
906 }
907
908 /***********************************************************************
909  *              AddCredentialsA (SECUR32.@)
910  */
911 SECURITY_STATUS WINAPI AddCredentialsA(PCredHandle hCredentials,
912  SEC_CHAR *pszPrincipal, SEC_CHAR *pszPackage, ULONG fCredentialUse,
913  void *pAuthData, SEC_GET_KEY_FN pGetKeyFn, void *pvGetKeyArgument,
914  PTimeStamp ptsExpiry)
915 {
916     SECURITY_STATUS ret;
917
918     TRACE("%p %s %s %d %p %p %p %p\n", hCredentials, debugstr_a(pszPrincipal),
919      debugstr_a(pszPackage), fCredentialUse, pAuthData, pGetKeyFn,
920      pvGetKeyArgument, ptsExpiry);
921     if (hCredentials)
922     {
923         SecurePackage *package = (SecurePackage *)hCredentials->dwUpper;
924         PCredHandle cred = (PCtxtHandle)hCredentials->dwLower;
925
926         if (package && package->provider)
927         {
928             if (package->provider->fnTableA.AddCredentialsA)
929                 ret = package->provider->fnTableA.AddCredentialsA(
930                  cred, pszPrincipal, pszPackage, fCredentialUse, pAuthData,
931                  pGetKeyFn, pvGetKeyArgument, ptsExpiry);
932             else
933                 ret = SEC_E_UNSUPPORTED_FUNCTION;
934         }
935         else
936             ret = SEC_E_INVALID_HANDLE;
937     }
938     else
939         ret = SEC_E_INVALID_HANDLE;
940     return ret;
941 }
942
943 /***********************************************************************
944  *              AddCredentialsW (SECUR32.@)
945  */
946 SECURITY_STATUS WINAPI AddCredentialsW(PCredHandle hCredentials,
947  SEC_WCHAR *pszPrincipal, SEC_WCHAR *pszPackage, ULONG fCredentialUse,
948  void *pAuthData, SEC_GET_KEY_FN pGetKeyFn, void *pvGetKeyArgument,
949  PTimeStamp ptsExpiry)
950 {
951     SECURITY_STATUS ret;
952
953     TRACE("%p %s %s %d %p %p %p %p\n", hCredentials, debugstr_w(pszPrincipal),
954      debugstr_w(pszPackage), fCredentialUse, pAuthData, pGetKeyFn,
955      pvGetKeyArgument, ptsExpiry);
956     if (hCredentials)
957     {
958         SecurePackage *package = (SecurePackage *)hCredentials->dwUpper;
959         PCredHandle cred = (PCtxtHandle)hCredentials->dwLower;
960
961         if (package && package->provider)
962         {
963             if (package->provider->fnTableW.AddCredentialsW)
964                 ret = package->provider->fnTableW.AddCredentialsW(
965                  cred, pszPrincipal, pszPackage, fCredentialUse, pAuthData,
966                  pGetKeyFn, pvGetKeyArgument, ptsExpiry);
967             else
968                 ret = SEC_E_UNSUPPORTED_FUNCTION;
969         }
970         else
971             ret = SEC_E_INVALID_HANDLE;
972     }
973     else
974         ret = SEC_E_INVALID_HANDLE;
975     return ret;
976 }
977
978 /***********************************************************************
979  *              QuerySecurityContextToken (SECUR32.@)
980  */
981 SECURITY_STATUS WINAPI QuerySecurityContextToken(PCtxtHandle phContext,
982  HANDLE *phToken)
983 {
984     SECURITY_STATUS ret;
985
986     TRACE("%p %p\n", phContext, phToken);
987     if (phContext)
988     {
989         SecurePackage *package = (SecurePackage *)phContext->dwUpper;
990         PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
991
992         if (package && package->provider)
993         {
994             if (package->provider->fnTableW.QuerySecurityContextToken)
995                 ret = package->provider->fnTableW.QuerySecurityContextToken(
996                  ctxt, phToken);
997             else
998                 ret = SEC_E_UNSUPPORTED_FUNCTION;
999         }
1000         else
1001             ret = SEC_E_INVALID_HANDLE;
1002     }
1003     else
1004         ret = SEC_E_INVALID_HANDLE;
1005     return ret;
1006 }
1007
1008 /***********************************************************************
1009  *              EncryptMessage (SECUR32.@)
1010  */
1011 SECURITY_STATUS WINAPI EncryptMessage(PCtxtHandle phContext, ULONG fQOP,
1012  PSecBufferDesc pMessage, ULONG MessageSeqNo)
1013 {
1014     SECURITY_STATUS ret;
1015
1016     TRACE("%p %d %p %d\n", phContext, fQOP, pMessage, MessageSeqNo);
1017     if (phContext)
1018     {
1019         SecurePackage *package = (SecurePackage *)phContext->dwUpper;
1020         PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
1021
1022         if (package && package->provider)
1023         {
1024             if (package->provider->fnTableW.EncryptMessage)
1025                 ret = package->provider->fnTableW.EncryptMessage(
1026                  ctxt, fQOP, pMessage, MessageSeqNo);
1027             else
1028                 ret = SEC_E_UNSUPPORTED_FUNCTION;
1029         }
1030         else
1031             ret = SEC_E_INVALID_HANDLE;
1032     }
1033     else
1034         ret = SEC_E_INVALID_HANDLE;
1035     return ret;
1036 }
1037
1038 /***********************************************************************
1039  *              DecryptMessage (SECUR32.@)
1040  */
1041 SECURITY_STATUS WINAPI DecryptMessage(PCtxtHandle phContext,
1042  PSecBufferDesc pMessage, ULONG MessageSeqNo, PULONG pfQOP)
1043 {
1044     SECURITY_STATUS ret;
1045
1046     TRACE("%p %p %d %p\n", phContext, pMessage, MessageSeqNo, pfQOP);
1047     if (phContext)
1048     {
1049         SecurePackage *package = (SecurePackage *)phContext->dwUpper;
1050         PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
1051
1052         if (package && package->provider)
1053         {
1054             if (package->provider->fnTableW.DecryptMessage)
1055                 ret = package->provider->fnTableW.DecryptMessage(
1056                  ctxt, pMessage, MessageSeqNo, pfQOP);
1057             else
1058                 ret = SEC_E_UNSUPPORTED_FUNCTION;
1059         }
1060         else
1061             ret = SEC_E_INVALID_HANDLE;
1062     }
1063     else
1064         ret = SEC_E_INVALID_HANDLE;
1065     return ret;
1066 }
1067
1068 /***********************************************************************
1069  *              SetContextAttributesA (SECUR32.@)
1070  */
1071 SECURITY_STATUS WINAPI SetContextAttributesA(PCtxtHandle phContext,
1072  ULONG ulAttribute, void *pBuffer, ULONG cbBuffer)
1073 {
1074     SECURITY_STATUS ret;
1075
1076     TRACE("%p %d %p %d\n", phContext, ulAttribute, pBuffer, cbBuffer);
1077     if (phContext)
1078     {
1079         SecurePackage *package = (SecurePackage *)phContext->dwUpper;
1080         PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
1081
1082         if (package && package->provider)
1083         {
1084             if (package->provider->fnTableA.SetContextAttributesA)
1085                 ret = package->provider->fnTableA.SetContextAttributesA(
1086                  ctxt, ulAttribute, pBuffer, cbBuffer);
1087             else
1088                 ret = SEC_E_UNSUPPORTED_FUNCTION;
1089         }
1090         else
1091             ret = SEC_E_INVALID_HANDLE;
1092     }
1093     else
1094         ret = SEC_E_INVALID_HANDLE;
1095     return ret;
1096 }
1097
1098 /***********************************************************************
1099  *              SetContextAttributesW (SECUR32.@)
1100  */
1101 SECURITY_STATUS WINAPI SetContextAttributesW(PCtxtHandle phContext,
1102  ULONG ulAttribute, void *pBuffer, ULONG cbBuffer)
1103 {
1104     SECURITY_STATUS ret;
1105
1106     TRACE("%p %d %p %d\n", phContext, ulAttribute, pBuffer, cbBuffer);
1107     if (phContext)
1108     {
1109         SecurePackage *package = (SecurePackage *)phContext->dwUpper;
1110         PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
1111
1112         if (package && package->provider)
1113         {
1114             if (package->provider->fnTableW.SetContextAttributesW)
1115                 ret = package->provider->fnTableW.SetContextAttributesW(
1116                  ctxt, ulAttribute, pBuffer, cbBuffer);
1117             else
1118                 ret = SEC_E_UNSUPPORTED_FUNCTION;
1119         }
1120         else
1121             ret = SEC_E_INVALID_HANDLE;
1122     }
1123     else
1124         ret = SEC_E_INVALID_HANDLE;
1125     return ret;
1126 }