Give SetErrorMode the right argument to suppress crash dialogs.
[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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  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     if (phSec && package && realHandle)
41     {
42         PSecHandle newSec = (PSecHandle)SECUR32_ALLOC(sizeof(SecHandle));
43
44         if (newSec)
45         {
46             memcpy(newSec, realHandle, sizeof(*realHandle));
47             phSec->dwUpper = (ULONG_PTR)package;
48             phSec->dwLower = (ULONG_PTR)newSec;
49             ret = SEC_E_OK;
50         }
51         else
52             ret = SEC_E_INSUFFICIENT_MEMORY;
53     }
54     else
55         ret = SEC_E_INVALID_HANDLE;
56     return ret;
57 }
58
59 SECURITY_STATUS SEC_ENTRY AcquireCredentialsHandleA(
60  SEC_CHAR *pszPrincipal, SEC_CHAR *pszPackage, ULONG fCredentialsUse,
61  PLUID pvLogonID, PVOID pAuthData, SEC_GET_KEY_FN pGetKeyFn,
62  PVOID pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry)
63 {
64     SECURITY_STATUS ret;
65
66     TRACE("%s %s %ld %p %p %p %p %p %p\n", debugstr_a(pszPrincipal),
67      debugstr_a(pszPackage), fCredentialsUse, pvLogonID, pAuthData, pGetKeyFn,
68      pvGetKeyArgument, phCredential, ptsExpiry);
69     if (pszPackage)
70     {
71         SecurePackage *package = SECUR32_findPackageA(pszPackage);
72
73         if (package && package->provider)
74         {
75             if (package->provider->fnTableA.AcquireCredentialsHandleA)
76             {
77                 CredHandle myCred;
78
79                 ret = package->provider->fnTableA.AcquireCredentialsHandleA(
80                  pszPrincipal, pszPackage, fCredentialsUse, pvLogonID,
81                  pAuthData, pGetKeyFn, pvGetKeyArgument, &myCred,
82                  ptsExpiry);
83                 if (ret == SEC_E_OK)
84                 {
85                     ret = SECUR32_makeSecHandle(phCredential, package, &myCred);
86                     if (ret != SEC_E_OK)
87                         package->provider->fnTableW.FreeCredentialsHandle(
88                          &myCred);
89                 }
90             }
91             else
92                 ret = SEC_E_UNSUPPORTED_FUNCTION;
93         }
94         else
95             ret = SEC_E_SECPKG_NOT_FOUND;
96     }
97     else
98         ret = SEC_E_SECPKG_NOT_FOUND;
99     return ret;
100 }
101
102 SECURITY_STATUS SEC_ENTRY AcquireCredentialsHandleW(
103  SEC_WCHAR *pszPrincipal, SEC_WCHAR *pszPackage, ULONG fCredentialsUse,
104  PLUID pvLogonID, PVOID pAuthData, SEC_GET_KEY_FN pGetKeyFn,
105  PVOID pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry)
106 {
107     SECURITY_STATUS ret;
108
109     TRACE("%s %s %ld %p %p %p %p %p %p\n", debugstr_w(pszPrincipal),
110      debugstr_w(pszPackage), fCredentialsUse, pvLogonID, pAuthData, pGetKeyFn,
111      pvGetKeyArgument, phCredential, ptsExpiry);
112     if (pszPackage)
113     {
114         SecurePackage *package = SECUR32_findPackageW(pszPackage);
115
116         if (package && package->provider)
117         {
118             if (package->provider->fnTableW.AcquireCredentialsHandleW)
119             {
120                 CredHandle myCred;
121
122                 ret = package->provider->fnTableW.AcquireCredentialsHandleW(
123                  pszPrincipal, pszPackage, fCredentialsUse, pvLogonID,
124                  pAuthData, pGetKeyFn, pvGetKeyArgument, &myCred,
125                  ptsExpiry);
126                 if (ret == SEC_E_OK)
127                 {
128                     ret = SECUR32_makeSecHandle(phCredential, package, &myCred);
129                     if (ret != SEC_E_OK)
130                         package->provider->fnTableW.FreeCredentialsHandle(
131                          &myCred);
132                 }
133             }
134             else
135                 ret = SEC_E_UNSUPPORTED_FUNCTION;
136         }
137         else
138             ret = SEC_E_SECPKG_NOT_FOUND;
139     }
140     else
141         ret = SEC_E_SECPKG_NOT_FOUND;
142     return ret;
143 }
144
145 SECURITY_STATUS SEC_ENTRY FreeCredentialsHandle(
146  PCredHandle phCredential)
147 {
148     SECURITY_STATUS ret;
149
150     TRACE("%p\n", phCredential);
151     if (phCredential)
152     {
153         SecurePackage *package = (SecurePackage *)phCredential->dwUpper;
154         PCredHandle cred = (PCredHandle)phCredential->dwLower;
155
156         if (package && package->provider &&
157          package->provider->fnTableW.FreeCredentialsHandle)
158             ret = package->provider->fnTableW.FreeCredentialsHandle(cred);
159         else
160             ret = SEC_E_INVALID_HANDLE;
161         SECUR32_FREE(cred);
162     }
163     else
164         ret = SEC_E_INVALID_HANDLE;
165     return ret;
166 }
167
168 SECURITY_STATUS SEC_ENTRY QueryCredentialsAttributesA(
169  PCredHandle phCredential, unsigned long ulAttribute, void *pBuffer)
170 {
171     SECURITY_STATUS ret;
172
173     TRACE("%p %ld %p\n", phCredential, ulAttribute, pBuffer);
174     if (phCredential)
175     {
176         SecurePackage *package = (SecurePackage *)phCredential->dwUpper;
177         PCredHandle cred = (PCredHandle)phCredential->dwLower;
178
179         if (package && package->provider)
180         {
181             if (package->provider->fnTableA.QueryCredentialsAttributesA)
182                 ret = package->provider->fnTableA.QueryCredentialsAttributesA(
183                  cred, ulAttribute, pBuffer);
184             else
185                 ret = SEC_E_UNSUPPORTED_FUNCTION;
186         }
187         else
188             ret = SEC_E_INVALID_HANDLE;
189     }
190     else
191         ret = SEC_E_INVALID_HANDLE;
192     return ret;
193 }
194
195 SECURITY_STATUS SEC_ENTRY QueryCredentialsAttributesW(
196  PCredHandle phCredential, unsigned long ulAttribute, void *pBuffer)
197 {
198     SECURITY_STATUS ret;
199
200     TRACE("%p %ld %p\n", phCredential, ulAttribute, pBuffer);
201     if (phCredential)
202     {
203         SecurePackage *package = (SecurePackage *)phCredential->dwUpper;
204         PCredHandle cred = (PCredHandle)phCredential->dwLower;
205
206         if (package && package->provider)
207         {
208             if (package->provider->fnTableW.QueryCredentialsAttributesW)
209                 ret = package->provider->fnTableW.QueryCredentialsAttributesW(
210                  cred, ulAttribute, pBuffer);
211             else
212                 ret = SEC_E_UNSUPPORTED_FUNCTION;
213         }
214         else
215             ret = SEC_E_INVALID_HANDLE;
216     }
217     else
218         ret = SEC_E_INVALID_HANDLE;
219     return ret;
220 }
221
222 SECURITY_STATUS SEC_ENTRY InitializeSecurityContextA(
223  PCredHandle phCredential, PCtxtHandle phContext,
224  SEC_CHAR *pszTargetName, unsigned long fContextReq,
225  unsigned long Reserved1, unsigned long TargetDataRep, PSecBufferDesc pInput,
226  unsigned long Reserved2, PCtxtHandle phNewContext, PSecBufferDesc pOutput,
227  unsigned long *pfContextAttr, PTimeStamp ptsExpiry)
228 {
229     SECURITY_STATUS ret;
230
231     TRACE("%p %p %s %ld %ld %ld %p %ld %p %p %p %p\n", phCredential, phContext,
232      debugstr_a(pszTargetName), fContextReq, Reserved1, TargetDataRep, pInput,
233      Reserved1, phNewContext, pOutput, pfContextAttr, ptsExpiry);
234     if (phCredential)
235     {
236         SecurePackage *package = (SecurePackage *)phCredential->dwUpper;
237         PCredHandle cred = (PCredHandle)phCredential->dwLower;
238
239         if (package && package->provider)
240         {
241             if (package->provider->fnTableA.InitializeSecurityContextA)
242             {
243                 CtxtHandle myCtxt;
244
245                 ret = package->provider->fnTableA.InitializeSecurityContextA(
246                  cred, phContext ? &myCtxt : NULL, pszTargetName, fContextReq,
247                  Reserved1, TargetDataRep, pInput, Reserved2, &myCtxt,
248                  pOutput, pfContextAttr, ptsExpiry);
249                 if (ret == SEC_E_OK)
250                 {
251                     ret = SECUR32_makeSecHandle(phContext, package, &myCtxt);
252                     if (ret != SEC_E_OK)
253                         package->provider->fnTableW.DeleteSecurityContext(
254                          &myCtxt);
255                 }
256             }
257             else
258                 ret = SEC_E_UNSUPPORTED_FUNCTION;
259         }
260         else
261             ret = SEC_E_INVALID_HANDLE;
262     }
263     else
264         ret = SEC_E_INVALID_HANDLE;
265     return ret;
266 }
267
268 SECURITY_STATUS SEC_ENTRY InitializeSecurityContextW(
269  PCredHandle phCredential, PCtxtHandle phContext,
270  SEC_WCHAR *pszTargetName, unsigned long fContextReq,
271  unsigned long Reserved1, unsigned long TargetDataRep, PSecBufferDesc pInput,
272  unsigned long Reserved2, PCtxtHandle phNewContext, PSecBufferDesc pOutput,
273  unsigned long *pfContextAttr, PTimeStamp ptsExpiry)
274 {
275     SECURITY_STATUS ret;
276
277     TRACE("%p %p %s %ld %ld %ld %p %ld %p %p %p %p\n", phCredential, phContext,
278      debugstr_w(pszTargetName), fContextReq, Reserved1, TargetDataRep, pInput,
279      Reserved1, phNewContext, pOutput, pfContextAttr, ptsExpiry);
280     if (phCredential)
281     {
282         SecurePackage *package = (SecurePackage *)phCredential->dwUpper;
283         PCredHandle cred = (PCredHandle)phCredential->dwLower;
284
285         if (package && package->provider)
286         {
287             if (package->provider->fnTableW.QueryCredentialsAttributesW)
288             {
289                 CtxtHandle myCtxt;
290
291                 ret = package->provider->fnTableW.InitializeSecurityContextW(
292                  cred, phContext ? &myCtxt : NULL, pszTargetName, fContextReq,
293                  Reserved1, TargetDataRep, pInput, Reserved2, &myCtxt,
294                  pOutput, pfContextAttr, ptsExpiry);
295                 if (ret == SEC_E_OK)
296                 {
297                     ret = SECUR32_makeSecHandle(phContext, package, &myCtxt);
298                     if (ret != SEC_E_OK)
299                         package->provider->fnTableW.DeleteSecurityContext(
300                          &myCtxt);
301                 }
302             }
303             else
304                 ret = SEC_E_UNSUPPORTED_FUNCTION;
305         }
306         else
307             ret = SEC_E_INVALID_HANDLE;
308     }
309     else
310         ret = SEC_E_INVALID_HANDLE;
311     return ret;
312 }
313
314 SECURITY_STATUS SEC_ENTRY AcceptSecurityContext(
315  PCredHandle phCredential, PCtxtHandle phContext, PSecBufferDesc pInput,
316  unsigned long fContextReq, unsigned long TargetDataRep,
317  PCtxtHandle phNewContext, PSecBufferDesc pOutput,
318  unsigned long *pfContextAttr, PTimeStamp ptsExpiry)
319 {
320     SECURITY_STATUS ret;
321
322     TRACE("%p %p %p %ld %ld %p %p %p %p\n", phCredential, phContext, pInput,
323      fContextReq, TargetDataRep, phNewContext, pOutput, pfContextAttr,
324      ptsExpiry);
325     if (phCredential)
326     {
327         SecurePackage *package = (SecurePackage *)phCredential->dwUpper;
328         PCredHandle cred = (PCredHandle)phCredential->dwLower;
329
330         if (package && package->provider)
331         {
332             if (package->provider->fnTableW.AcceptSecurityContext)
333             {
334                 CtxtHandle myCtxt;
335
336                 ret = package->provider->fnTableW.AcceptSecurityContext(
337                  cred, phContext ? &myCtxt : NULL, pInput, fContextReq,
338                  TargetDataRep, &myCtxt, pOutput, pfContextAttr, ptsExpiry);
339                 if (ret == SEC_E_OK)
340                 {
341                     ret = SECUR32_makeSecHandle(phContext, package, &myCtxt);
342                     if (ret != SEC_E_OK)
343                         package->provider->fnTableW.DeleteSecurityContext(
344                          &myCtxt);
345                 }
346             }
347             else
348                 ret = SEC_E_UNSUPPORTED_FUNCTION;
349         }
350         else
351             ret = SEC_E_INVALID_HANDLE;
352     }
353     else
354         ret = SEC_E_INVALID_HANDLE;
355     return ret;
356 }
357
358 SECURITY_STATUS SEC_ENTRY CompleteAuthToken(PCtxtHandle phContext,
359  PSecBufferDesc pToken)
360 {
361     SECURITY_STATUS ret;
362
363     TRACE("%p %p\n", phContext, pToken);
364     if (phContext)
365     {
366         SecurePackage *package = (SecurePackage *)phContext->dwUpper;
367         PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
368
369         if (package && package->provider)
370         {
371             if (package->provider->fnTableW.CompleteAuthToken)
372                 ret = package->provider->fnTableW.CompleteAuthToken(ctxt,
373                  pToken);
374             else
375                 ret = SEC_E_UNSUPPORTED_FUNCTION;
376         }
377         else
378             ret = SEC_E_INVALID_HANDLE;
379     }
380     else
381         ret = SEC_E_INVALID_HANDLE;
382     return ret;
383 }
384
385 SECURITY_STATUS SEC_ENTRY DeleteSecurityContext(PCtxtHandle phContext)
386 {
387     SECURITY_STATUS ret;
388
389     TRACE("%p\n", phContext);
390     if (phContext)
391     {
392         SecurePackage *package = (SecurePackage *)phContext->dwUpper;
393         PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
394
395         if (package && package->provider &&
396          package->provider->fnTableW.DeleteSecurityContext)
397             ret = package->provider->fnTableW.DeleteSecurityContext(ctxt);
398         else
399             ret = SEC_E_INVALID_HANDLE;
400         SECUR32_FREE(ctxt);
401     }
402     else
403         ret = SEC_E_INVALID_HANDLE;
404     return ret;
405 }
406
407 SECURITY_STATUS SEC_ENTRY ApplyControlToken(PCtxtHandle phContext,
408  PSecBufferDesc pInput)
409 {
410     SECURITY_STATUS ret;
411
412     TRACE("%p %p\n", phContext, pInput);
413     if (phContext)
414     {
415         SecurePackage *package = (SecurePackage *)phContext->dwUpper;
416         PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
417
418         if (package && package->provider)
419         {
420             if (package->provider->fnTableW.ApplyControlToken)
421                 ret = package->provider->fnTableW.ApplyControlToken(
422                  ctxt, pInput);
423             else
424                 ret = SEC_E_UNSUPPORTED_FUNCTION;
425         }
426         else
427             ret = SEC_E_INVALID_HANDLE;
428     }
429     else
430         ret = SEC_E_INVALID_HANDLE;
431     return ret;
432 }
433
434 SECURITY_STATUS SEC_ENTRY QueryContextAttributesA(PCtxtHandle phContext,
435  unsigned long ulAttribute, void *pBuffer)
436 {
437     SECURITY_STATUS ret;
438
439     TRACE("%p %ld %p\n", phContext, ulAttribute, pBuffer);
440     if (phContext)
441     {
442         SecurePackage *package = (SecurePackage *)phContext->dwUpper;
443         PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
444
445         if (package && package->provider)
446         {
447             if (package->provider->fnTableA.QueryContextAttributesA)
448                 ret = package->provider->fnTableA.QueryContextAttributesA(
449                  ctxt, ulAttribute, pBuffer);
450             else
451                 ret = SEC_E_UNSUPPORTED_FUNCTION;
452         }
453         else
454             ret = SEC_E_INVALID_HANDLE;
455     }
456     else
457         ret = SEC_E_INVALID_HANDLE;
458     return ret;
459 }
460
461 SECURITY_STATUS SEC_ENTRY QueryContextAttributesW(PCtxtHandle phContext,
462  unsigned long ulAttribute, void *pBuffer)
463 {
464     SECURITY_STATUS ret;
465
466     TRACE("%p %ld %p\n", phContext, ulAttribute, pBuffer);
467     if (phContext)
468     {
469         SecurePackage *package = (SecurePackage *)phContext->dwUpper;
470         PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
471
472         if (package && package->provider)
473         {
474             if (package->provider->fnTableW.QueryContextAttributesW)
475                 ret = package->provider->fnTableW.QueryContextAttributesW(
476                  ctxt, ulAttribute, pBuffer);
477             else
478                 ret = SEC_E_UNSUPPORTED_FUNCTION;
479         }
480         else
481             ret = SEC_E_INVALID_HANDLE;
482     }
483     else
484         ret = SEC_E_INVALID_HANDLE;
485     return ret;
486 }
487
488 SECURITY_STATUS SEC_ENTRY ImpersonateSecurityContext(PCtxtHandle phContext)
489 {
490     SECURITY_STATUS ret;
491
492     TRACE("%p\n", phContext);
493     if (phContext)
494     {
495         SecurePackage *package = (SecurePackage *)phContext->dwUpper;
496         PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
497
498         if (package && package->provider)
499         {
500             if (package->provider->fnTableW.ImpersonateSecurityContext)
501                 ret = package->provider->fnTableW.ImpersonateSecurityContext(
502                  ctxt);
503             else
504                 ret = SEC_E_UNSUPPORTED_FUNCTION;
505         }
506         else
507             ret = SEC_E_INVALID_HANDLE;
508     }
509     else
510         ret = SEC_E_INVALID_HANDLE;
511     return ret;
512 }
513
514 SECURITY_STATUS SEC_ENTRY RevertSecurityContext(PCtxtHandle phContext)
515 {
516     SECURITY_STATUS ret;
517
518     TRACE("%p\n", phContext);
519     if (phContext)
520     {
521         SecurePackage *package = (SecurePackage *)phContext->dwUpper;
522         PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
523
524         if (package && package->provider)
525         {
526             if (package->provider->fnTableW.RevertSecurityContext)
527                 ret = package->provider->fnTableW.RevertSecurityContext(
528                  ctxt);
529             else
530                 ret = SEC_E_UNSUPPORTED_FUNCTION;
531         }
532         else
533             ret = SEC_E_INVALID_HANDLE;
534     }
535     else
536         ret = SEC_E_INVALID_HANDLE;
537     return ret;
538 }
539
540 SECURITY_STATUS SEC_ENTRY MakeSignature(PCtxtHandle phContext, ULONG fQOP,
541  PSecBufferDesc pMessage, ULONG MessageSeqNo)
542 {
543     SECURITY_STATUS ret;
544
545     TRACE("%p %ld %p %ld\n", phContext, fQOP, pMessage, MessageSeqNo);
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.MakeSignature)
554                 ret = package->provider->fnTableW.MakeSignature(
555                  ctxt, fQOP, pMessage, MessageSeqNo);
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 SECURITY_STATUS SEC_ENTRY VerifySignature(PCtxtHandle phContext,
568  PSecBufferDesc pMessage, ULONG MessageSeqNo, PULONG pfQOP)
569 {
570     SECURITY_STATUS ret;
571
572     TRACE("%p %p %ld %p\n", phContext, pMessage, MessageSeqNo, pfQOP);
573     if (phContext)
574     {
575         SecurePackage *package = (SecurePackage *)phContext->dwUpper;
576         PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
577
578         if (package && package->provider)
579         {
580             if (package->provider->fnTableW.VerifySignature)
581                 ret = package->provider->fnTableW.VerifySignature(
582                  ctxt, pMessage, MessageSeqNo, pfQOP);
583             else
584                 ret = SEC_E_UNSUPPORTED_FUNCTION;
585         }
586         else
587             ret = SEC_E_INVALID_HANDLE;
588     }
589     else
590         ret = SEC_E_INVALID_HANDLE;
591     return ret;
592 }
593
594 SECURITY_STATUS SEC_ENTRY QuerySecurityPackageInfoA(SEC_CHAR *pszPackageName,
595  PSecPkgInfoA *ppPackageInfo)
596 {
597     SECURITY_STATUS ret;
598    
599     TRACE("%s %p\n", debugstr_a(pszPackageName), ppPackageInfo);
600     if (pszPackageName)
601     {
602         SecurePackage *package = SECUR32_findPackageA(pszPackageName);
603
604         if (package)
605         {
606             size_t bytesNeeded = sizeof(SecPkgInfoA);
607             int nameLen = 0, commentLen = 0;
608
609             if (package->infoW.Name)
610             {
611                 nameLen = WideCharToMultiByte(CP_ACP, 0,
612                  package->infoW.Name, -1, NULL, 0, NULL, NULL);
613                 bytesNeeded += nameLen;
614             }
615             if (package->infoW.Comment)
616             {
617                 commentLen = WideCharToMultiByte(CP_ACP, 0,
618                  package->infoW.Comment, -1, NULL, 0, NULL, NULL);
619                 bytesNeeded += commentLen;
620             }
621             *ppPackageInfo = (PSecPkgInfoA)SECUR32_ALLOC(bytesNeeded);
622             if (*ppPackageInfo)
623             {
624                 PSTR nextString = (PSTR)((PBYTE)*ppPackageInfo +
625                  sizeof(SecPkgInfoA));
626
627                 memcpy(*ppPackageInfo, &package->infoW, sizeof(package->infoW));
628                 if (package->infoW.Name)
629                 {
630                     (*ppPackageInfo)->Name = nextString;
631                     nextString += WideCharToMultiByte(CP_ACP, 0,
632                      package->infoW.Name, -1, nextString, nameLen, NULL, NULL);
633                 }
634                 else
635                     (*ppPackageInfo)->Name = NULL;
636                 if (package->infoW.Comment)
637                 {
638                     (*ppPackageInfo)->Comment = nextString;
639                     nextString += WideCharToMultiByte(CP_ACP, 0,
640                      package->infoW.Comment, -1, nextString, commentLen, NULL,
641                      NULL);
642                 }
643                 else
644                     (*ppPackageInfo)->Comment = NULL;
645                 ret = SEC_E_OK;
646             }
647             else
648                 ret = SEC_E_INSUFFICIENT_MEMORY;
649         }
650         else
651             ret = SEC_E_SECPKG_NOT_FOUND;
652     }
653     else
654         ret = SEC_E_SECPKG_NOT_FOUND;
655     return ret;
656 }
657
658 SECURITY_STATUS SEC_ENTRY QuerySecurityPackageInfoW(SEC_WCHAR *pszPackageName,
659  PSecPkgInfoW *ppPackageInfo)
660 {
661     SECURITY_STATUS ret;
662     SecurePackage *package = SECUR32_findPackageW(pszPackageName);
663
664     TRACE("%s %p\n", debugstr_w(pszPackageName), ppPackageInfo);
665     if (package)
666     {
667         size_t bytesNeeded = sizeof(SecPkgInfoW);
668         int nameLen = 0, commentLen = 0;
669
670         if (package->infoW.Name)
671         {
672             nameLen = lstrlenW(package->infoW.Name) + 1;
673             bytesNeeded += nameLen * sizeof(WCHAR);
674         }
675         if (package->infoW.Comment)
676         {
677             commentLen = lstrlenW(package->infoW.Comment) + 1;
678             bytesNeeded += commentLen * sizeof(WCHAR);
679         }
680         *ppPackageInfo = (PSecPkgInfoW)SECUR32_ALLOC(bytesNeeded);
681         if (*ppPackageInfo)
682         {
683             PWSTR nextString = (PWSTR)((PBYTE)*ppPackageInfo +
684              sizeof(SecPkgInfoW));
685
686             memcpy(*ppPackageInfo, &package->infoW, sizeof(package->infoW));
687             if (package->infoW.Name)
688             {
689                 (*ppPackageInfo)->Name = nextString;
690                 lstrcpynW(nextString, package->infoW.Name, nameLen);
691                 nextString += nameLen;
692             }
693             else
694                 (*ppPackageInfo)->Name = NULL;
695             if (package->infoW.Comment)
696             {
697                 (*ppPackageInfo)->Comment = nextString;
698                 lstrcpynW(nextString, package->infoW.Comment, commentLen);
699                 nextString += commentLen;
700             }
701             else
702                 (*ppPackageInfo)->Comment = NULL;
703             ret = SEC_E_OK;
704         }
705         else
706             ret = SEC_E_INSUFFICIENT_MEMORY;
707     }
708     else
709         ret = SEC_E_SECPKG_NOT_FOUND;
710     return ret;
711 }
712
713 SECURITY_STATUS SEC_ENTRY ExportSecurityContext(PCtxtHandle phContext,
714  ULONG fFlags, PSecBuffer pPackedContext, void **pToken)
715 {
716     SECURITY_STATUS ret;
717
718     TRACE("%p %ld %p %p\n", phContext, fFlags, pPackedContext, pToken);
719     if (phContext)
720     {
721         SecurePackage *package = (SecurePackage *)phContext->dwUpper;
722         PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
723
724         if (package && package->provider)
725         {
726             if (package->provider->fnTableW.ExportSecurityContext)
727                 ret = package->provider->fnTableW.ExportSecurityContext(
728                  ctxt, fFlags, pPackedContext, pToken);
729             else
730                 ret = SEC_E_UNSUPPORTED_FUNCTION;
731         }
732         else
733             ret = SEC_E_INVALID_HANDLE;
734     }
735     else
736         ret = SEC_E_INVALID_HANDLE;
737     return ret;
738 }
739
740 SECURITY_STATUS SEC_ENTRY ImportSecurityContextA(SEC_CHAR *pszPackage,
741  PSecBuffer pPackedContext, void *Token, PCtxtHandle phContext)
742 {
743     SECURITY_STATUS ret;
744     SecurePackage *package = SECUR32_findPackageA(pszPackage);
745  
746     TRACE("%s %p %p %p\n", debugstr_a(pszPackage), pPackedContext, Token,
747      phContext);
748     if (package && package->provider)
749     {
750         if (package->provider->fnTableA.ImportSecurityContextA)
751         {
752             CtxtHandle myCtxt;
753
754             ret = package->provider->fnTableA.ImportSecurityContextA(
755              pszPackage, pPackedContext, Token, &myCtxt);
756             if (ret == SEC_E_OK)
757             {
758                 ret = SECUR32_makeSecHandle(phContext, package, &myCtxt);
759                 if (ret != SEC_E_OK)
760                     package->provider->fnTableW.DeleteSecurityContext(&myCtxt);
761             }
762         }
763         else
764             ret = SEC_E_UNSUPPORTED_FUNCTION;
765     }
766     else
767         ret = SEC_E_SECPKG_NOT_FOUND;
768     return ret;
769
770 }
771
772 SECURITY_STATUS SEC_ENTRY ImportSecurityContextW(SEC_WCHAR *pszPackage,
773  PSecBuffer pPackedContext, void *Token, PCtxtHandle phContext)
774 {
775     SECURITY_STATUS ret;
776     SecurePackage *package = SECUR32_findPackageW(pszPackage);
777
778     TRACE("%s %p %p %p\n", debugstr_w(pszPackage), pPackedContext, Token,
779      phContext);
780     if (package && package->provider)
781     {
782         if (package->provider->fnTableW.ImportSecurityContextW)
783         {
784             CtxtHandle myCtxt;
785
786             ret = package->provider->fnTableW.ImportSecurityContextW(
787              pszPackage, pPackedContext, Token, &myCtxt);
788             if (ret == SEC_E_OK)
789             {
790                 ret = SECUR32_makeSecHandle(phContext, package, &myCtxt);
791                 if (ret != SEC_E_OK)
792                     package->provider->fnTableW.DeleteSecurityContext(&myCtxt);
793             }
794         }
795         else
796             ret = SEC_E_UNSUPPORTED_FUNCTION;
797     }
798     else
799         ret = SEC_E_SECPKG_NOT_FOUND;
800     return ret;
801 }
802
803 SECURITY_STATUS SEC_ENTRY AddCredentialsA(PCredHandle hCredentials,
804  SEC_CHAR *pszPrincipal, SEC_CHAR *pszPackage, unsigned long fCredentialUse,
805  void *pAuthData, SEC_GET_KEY_FN pGetKeyFn, void *pvGetKeyArgument,
806  PTimeStamp ptsExpiry)
807 {
808     SECURITY_STATUS ret;
809
810     TRACE("%p %s %s %ld %p %p %p %p\n", hCredentials, debugstr_a(pszPrincipal),
811      debugstr_a(pszPackage), fCredentialUse, pAuthData, pGetKeyFn,
812      pvGetKeyArgument, ptsExpiry);
813     if (hCredentials)
814     {
815         SecurePackage *package = (SecurePackage *)hCredentials->dwUpper;
816         PCredHandle cred = (PCtxtHandle)hCredentials->dwLower;
817
818         if (package && package->provider)
819         {
820             if (package->provider->fnTableA.AddCredentialsA)
821                 ret = package->provider->fnTableA.AddCredentialsA(
822                  cred, pszPrincipal, pszPackage, fCredentialUse, pAuthData,
823                  pGetKeyFn, pvGetKeyArgument, ptsExpiry);
824             else
825                 ret = SEC_E_UNSUPPORTED_FUNCTION;
826         }
827         else
828             ret = SEC_E_INVALID_HANDLE;
829     }
830     else
831         ret = SEC_E_INVALID_HANDLE;
832     return ret;
833 }
834
835 SECURITY_STATUS SEC_ENTRY AddCredentialsW(PCredHandle hCredentials,
836  SEC_WCHAR *pszPrincipal, SEC_WCHAR *pszPackage, unsigned long fCredentialUse,
837  void *pAuthData, SEC_GET_KEY_FN pGetKeyFn, void *pvGetKeyArgument,
838  PTimeStamp ptsExpiry)
839 {
840     SECURITY_STATUS ret;
841
842     TRACE("%p %s %s %ld %p %p %p %p\n", hCredentials, debugstr_w(pszPrincipal),
843      debugstr_w(pszPackage), fCredentialUse, pAuthData, pGetKeyFn,
844      pvGetKeyArgument, ptsExpiry);
845     if (hCredentials)
846     {
847         SecurePackage *package = (SecurePackage *)hCredentials->dwUpper;
848         PCredHandle cred = (PCtxtHandle)hCredentials->dwLower;
849
850         if (package && package->provider)
851         {
852             if (package->provider->fnTableW.AddCredentialsW)
853                 ret = package->provider->fnTableW.AddCredentialsW(
854                  cred, pszPrincipal, pszPackage, fCredentialUse, pAuthData,
855                  pGetKeyFn, pvGetKeyArgument, ptsExpiry);
856             else
857                 ret = SEC_E_UNSUPPORTED_FUNCTION;
858         }
859         else
860             ret = SEC_E_INVALID_HANDLE;
861     }
862     else
863         ret = SEC_E_INVALID_HANDLE;
864     return ret;
865 }
866
867 SECURITY_STATUS SEC_ENTRY QuerySecurityContextToken(PCtxtHandle phContext,
868  HANDLE *phToken)
869 {
870     SECURITY_STATUS ret;
871
872     TRACE("%p %p\n", phContext, phToken);
873     if (phContext)
874     {
875         SecurePackage *package = (SecurePackage *)phContext->dwUpper;
876         PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
877
878         if (package && package->provider)
879         {
880             if (package->provider->fnTableW.QuerySecurityContextToken)
881                 ret = package->provider->fnTableW.QuerySecurityContextToken(
882                  ctxt, phToken);
883             else
884                 ret = SEC_E_UNSUPPORTED_FUNCTION;
885         }
886         else
887             ret = SEC_E_INVALID_HANDLE;
888     }
889     else
890         ret = SEC_E_INVALID_HANDLE;
891     return ret;
892 }
893
894 SECURITY_STATUS SEC_ENTRY EncryptMessage(PCtxtHandle phContext, ULONG fQOP,
895  PSecBufferDesc pMessage, ULONG MessageSeqNo)
896 {
897     SECURITY_STATUS ret;
898
899     TRACE("%p %ld %p %ld\n", phContext, fQOP, pMessage, MessageSeqNo);
900     if (phContext)
901     {
902         SecurePackage *package = (SecurePackage *)phContext->dwUpper;
903         PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
904
905         if (package && package->provider)
906         {
907             if (package->provider->fnTableW.EncryptMessage)
908                 ret = package->provider->fnTableW.EncryptMessage(
909                  ctxt, fQOP, pMessage, MessageSeqNo);
910             else
911                 ret = SEC_E_UNSUPPORTED_FUNCTION;
912         }
913         else
914             ret = SEC_E_INVALID_HANDLE;
915     }
916     else
917         ret = SEC_E_INVALID_HANDLE;
918     return ret;
919 }
920
921 SECURITY_STATUS SEC_ENTRY DecryptMessage(PCtxtHandle phContext,
922  PSecBufferDesc pMessage, ULONG MessageSeqNo, PULONG pfQOP)
923 {
924     SECURITY_STATUS ret;
925
926     TRACE("%p %p %ld %p\n", phContext, pMessage, MessageSeqNo, pfQOP);
927     if (phContext)
928     {
929         SecurePackage *package = (SecurePackage *)phContext->dwUpper;
930         PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
931
932         if (package && package->provider)
933         {
934             if (package->provider->fnTableW.DecryptMessage)
935                 ret = package->provider->fnTableW.DecryptMessage(
936                  ctxt, pMessage, MessageSeqNo, pfQOP);
937             else
938                 ret = SEC_E_UNSUPPORTED_FUNCTION;
939         }
940         else
941             ret = SEC_E_INVALID_HANDLE;
942     }
943     else
944         ret = SEC_E_INVALID_HANDLE;
945     return ret;
946 }
947
948 SECURITY_STATUS SEC_ENTRY SetContextAttributesA(PCtxtHandle phContext,
949  unsigned long ulAttribute, void *pBuffer, unsigned long cbBuffer)
950 {
951     SECURITY_STATUS ret;
952
953     TRACE("%p %ld %p %ld\n", phContext, ulAttribute, pBuffer, cbBuffer);
954     if (phContext)
955     {
956         SecurePackage *package = (SecurePackage *)phContext->dwUpper;
957         PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
958
959         if (package && package->provider)
960         {
961             if (package->provider->fnTableA.SetContextAttributesA)
962                 ret = package->provider->fnTableA.SetContextAttributesA(
963                  ctxt, ulAttribute, pBuffer, cbBuffer);
964             else
965                 ret = SEC_E_UNSUPPORTED_FUNCTION;
966         }
967         else
968             ret = SEC_E_INVALID_HANDLE;
969     }
970     else
971         ret = SEC_E_INVALID_HANDLE;
972     return ret;
973 }
974
975 SECURITY_STATUS SEC_ENTRY SetContextAttributesW(PCtxtHandle phContext,
976  unsigned long ulAttribute, void *pBuffer, unsigned long cbBuffer)
977 {
978     SECURITY_STATUS ret;
979
980     TRACE("%p %ld %p %ld\n", phContext, ulAttribute, pBuffer, cbBuffer);
981     if (phContext)
982     {
983         SecurePackage *package = (SecurePackage *)phContext->dwUpper;
984         PCtxtHandle ctxt = (PCtxtHandle)phContext->dwLower;
985
986         if (package && package->provider)
987         {
988             if (package->provider->fnTableW.SetContextAttributesW)
989                 ret = package->provider->fnTableW.SetContextAttributesW(
990                  ctxt, ulAttribute, pBuffer, cbBuffer);
991             else
992                 ret = SEC_E_UNSUPPORTED_FUNCTION;
993         }
994         else
995             ret = SEC_E_INVALID_HANDLE;
996     }
997     else
998         ret = SEC_E_INVALID_HANDLE;
999     return ret;
1000 }