1 /* Copyright (C) 2004 Juan Lang
3 * This file implements loading of SSP DLLs.
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.
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.
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
28 #include "secur32_priv.h"
33 #include "wine/debug.h"
35 WINE_DEFAULT_DEBUG_CHANNEL(secur32
);
41 typedef struct _SecurePackageTable
45 SecurePackage table
[1];
48 typedef struct _SecureProviderTable
52 SecureProvider table
[1];
53 } SecureProviderTable
;
59 /* Makes sure table has space for at least howBig entries. If table is NULL,
60 * returns a newly allocated table. Otherwise returns the address of the
61 * modified table, which may not be the same was when called.
63 static SecurePackageTable
*_resizePackageTable(SecurePackageTable
*table
,
66 /* Makes sure table has space for at least howBig entries. If table is NULL,
67 * returns a newly allocated table. Otherwise returns the address of the
68 * modified table, which may not be the same was when called.
70 static SecureProviderTable
*_resizeProviderTable(SecureProviderTable
*table
,
73 /* Tries to load moduleName as a provider. If successful, enumerates what
74 * packages it can and adds them to the package and provider tables. Resizes
75 * tables as necessary.
77 static void _tryLoadProvider(PWSTR moduleName
);
79 /* Initialization: read securityproviders value and attempt to open each dll
80 * there. For each DLL, call _tryLoadProvider to see if it's really an SSP.
81 * Two undocumented functions, AddSecurityPackage(A/W) and
82 * DeleteSecurityPackage(A/W), seem suspiciously like they'd register or
83 * unregister a dll, but I'm not sure.
85 static void SECUR32_initializeProviders(void);
87 /* Frees all loaded packages and providers */
88 static void SECUR32_freeProviders(void);
94 static CRITICAL_SECTION cs
;
95 static SecurePackageTable
*packageTable
= NULL
;
96 static SecureProviderTable
*providerTable
= NULL
;
98 static SecurityFunctionTableA securityFunctionTableA
= {
99 SECURITY_SUPPORT_PROVIDER_INTERFACE_VERSION_2
,
100 EnumerateSecurityPackagesA
,
101 QueryCredentialsAttributesA
,
102 AcquireCredentialsHandleA
,
103 FreeCredentialsHandle
,
104 NULL
, /* Reserved2 */
105 InitializeSecurityContextA
,
106 AcceptSecurityContext
,
108 DeleteSecurityContext
,
110 QueryContextAttributesA
,
111 ImpersonateSecurityContext
,
112 RevertSecurityContext
,
116 QuerySecurityPackageInfoA
,
117 NULL
, /* Reserved3 */
118 NULL
, /* Reserved4 */
119 ExportSecurityContext
,
120 ImportSecurityContextA
,
122 NULL
, /* Reserved8 */
123 QuerySecurityContextToken
,
126 SetContextAttributesA
129 static SecurityFunctionTableW securityFunctionTableW
= {
130 SECURITY_SUPPORT_PROVIDER_INTERFACE_VERSION_2
,
131 EnumerateSecurityPackagesW
,
132 QueryCredentialsAttributesW
,
133 AcquireCredentialsHandleW
,
134 FreeCredentialsHandle
,
135 NULL
, /* Reserved2 */
136 InitializeSecurityContextW
,
137 AcceptSecurityContext
,
139 DeleteSecurityContext
,
141 QueryContextAttributesW
,
142 ImpersonateSecurityContext
,
143 RevertSecurityContext
,
147 QuerySecurityPackageInfoW
,
148 NULL
, /* Reserved3 */
149 NULL
, /* Reserved4 */
150 ExportSecurityContext
,
151 ImportSecurityContextW
,
153 NULL
, /* Reserved8 */
154 QuerySecurityContextToken
,
157 SetContextAttributesW
160 /***********************************************************************
161 * InitSecurityInterfaceA (SECUR32.@)
163 PSecurityFunctionTableA WINAPI
InitSecurityInterfaceA(void)
165 return &securityFunctionTableA
;
168 /***********************************************************************
169 * InitSecurityInterfaceW (SECUR32.@)
171 PSecurityFunctionTableW WINAPI
InitSecurityInterfaceW(void)
173 return &securityFunctionTableW
;
176 /* Allocates or resizes table to have space for at least howBig packages.
177 * Uses Heap functions, because needs to be able to reallocate.
179 static SecurePackageTable
*_resizePackageTable(SecurePackageTable
*table
,
182 SecurePackageTable
*ret
;
184 EnterCriticalSection(&cs
);
187 if (table
->numAllocated
< howBig
)
189 ret
= HeapReAlloc(GetProcessHeap(), 0, table
,
190 sizeof(SecurePackageTable
) + (howBig
- 1) * sizeof(SecurePackage
));
193 ret
->numAllocated
= howBig
;
202 DWORD numAllocated
= (howBig
> 1 ? howBig
: 1);
204 ret
= HeapAlloc(GetProcessHeap(), 0,
205 sizeof(SecurePackageTable
) +
206 (numAllocated
- 1) * sizeof(SecurePackage
));
209 ret
->numAllocated
= numAllocated
;
210 ret
->numPackages
= 0;
213 LeaveCriticalSection(&cs
);
217 /* Allocates or resizes table to have space for at least howBig providers.
218 * Uses Heap functions, because needs to be able to reallocate.
220 static SecureProviderTable
*_resizeProviderTable(SecureProviderTable
*table
,
223 SecureProviderTable
*ret
;
225 EnterCriticalSection(&cs
);
228 if (table
->numAllocated
< howBig
)
230 ret
= HeapReAlloc(GetProcessHeap(), 0, table
,
231 sizeof(SecureProviderTable
) +
232 (howBig
- 1) * sizeof(SecureProvider
));
235 ret
->numAllocated
= howBig
;
244 DWORD numAllocated
= (howBig
> 1 ? howBig
: 1);
246 ret
= HeapAlloc(GetProcessHeap(), 0,
247 sizeof(SecureProviderTable
) +
248 (numAllocated
- 1) * sizeof(SecureProvider
));
251 ret
->numAllocated
= numAllocated
;
252 ret
->numProviders
= 0;
255 LeaveCriticalSection(&cs
);
259 PWSTR
SECUR32_strdupW(PCWSTR str
)
265 ret
= (PWSTR
)SECUR32_ALLOC((lstrlenW(str
) + 1) * sizeof(WCHAR
));
274 PWSTR
SECUR32_AllocWideFromMultiByte(PCSTR str
)
280 int charsNeeded
= MultiByteToWideChar(CP_ACP
, 0, str
, -1, NULL
, 0);
284 ret
= (PWSTR
)SECUR32_ALLOC(charsNeeded
* sizeof(WCHAR
));
286 MultiByteToWideChar(CP_ACP
, 0, str
, -1, ret
, charsNeeded
);
296 PSTR
SECUR32_AllocMultiByteFromWide(PCWSTR str
)
302 int charsNeeded
= WideCharToMultiByte(CP_ACP
, 0, str
, -1, NULL
, 0,
307 ret
= (PSTR
)SECUR32_ALLOC(charsNeeded
);
309 WideCharToMultiByte(CP_ACP
, 0, str
, -1, ret
, charsNeeded
,
320 static void _makeFnTableA(PSecurityFunctionTableA fnTableA
,
321 const PSecurityFunctionTableA inFnTableA
,
322 const PSecurityFunctionTableW inFnTableW
)
328 /* The size of the version 1 table is based on platform sdk's
329 * sspi.h, though the sample ssp also provided with platform sdk
330 * implies only functions through QuerySecurityPackageInfoA are
331 * implemented (yikes)
333 size_t tableSize
= inFnTableA
->dwVersion
== 1 ?
334 (LPBYTE
)&inFnTableA
->SetContextAttributesA
-
335 (LPBYTE
)inFnTableA
: sizeof(SecurityFunctionTableA
);
337 memcpy(fnTableA
, inFnTableA
, tableSize
);
338 /* override this, since we can do it internally anyway */
339 fnTableA
->QuerySecurityPackageInfoA
=
340 QuerySecurityPackageInfoA
;
344 /* functions with thunks */
345 if (inFnTableW
->AcquireCredentialsHandleW
)
346 fnTableA
->AcquireCredentialsHandleA
=
347 thunk_AcquireCredentialsHandleA
;
348 if (inFnTableW
->InitializeSecurityContextW
)
349 fnTableA
->InitializeSecurityContextA
=
350 thunk_InitializeSecurityContextA
;
351 if (inFnTableW
->ImportSecurityContextW
)
352 fnTableA
->ImportSecurityContextA
=
353 thunk_ImportSecurityContextA
;
354 if (inFnTableW
->AddCredentialsW
)
355 fnTableA
->AddCredentialsA
=
356 thunk_AddCredentialsA
;
357 if (inFnTableW
->QueryCredentialsAttributesW
)
358 fnTableA
->QueryCredentialsAttributesA
=
359 thunk_QueryCredentialsAttributesA
;
360 if (inFnTableW
->QueryContextAttributesW
)
361 fnTableA
->QueryContextAttributesA
=
362 thunk_QueryContextAttributesA
;
363 if (inFnTableW
->SetContextAttributesW
)
364 fnTableA
->SetContextAttributesA
=
365 thunk_SetContextAttributesA
;
366 /* this can't be thunked, there's no extra param to know which
367 * package to forward to */
368 fnTableA
->EnumerateSecurityPackagesA
= NULL
;
369 /* functions with no thunks needed */
370 fnTableA
->AcceptSecurityContext
= inFnTableW
->AcceptSecurityContext
;
371 fnTableA
->CompleteAuthToken
= inFnTableW
->CompleteAuthToken
;
372 fnTableA
->DeleteSecurityContext
= inFnTableW
->DeleteSecurityContext
;
373 fnTableA
->ImpersonateSecurityContext
=
374 inFnTableW
->ImpersonateSecurityContext
;
375 fnTableA
->RevertSecurityContext
= inFnTableW
->RevertSecurityContext
;
376 fnTableA
->MakeSignature
= inFnTableW
->MakeSignature
;
377 fnTableA
->VerifySignature
= inFnTableW
->VerifySignature
;
378 fnTableA
->FreeContextBuffer
= inFnTableW
->FreeContextBuffer
;
379 fnTableA
->QuerySecurityPackageInfoA
=
380 QuerySecurityPackageInfoA
;
381 fnTableA
->ExportSecurityContext
=
382 inFnTableW
->ExportSecurityContext
;
383 fnTableA
->QuerySecurityContextToken
=
384 inFnTableW
->QuerySecurityContextToken
;
385 fnTableA
->EncryptMessage
= inFnTableW
->EncryptMessage
;
386 fnTableA
->DecryptMessage
= inFnTableW
->DecryptMessage
;
391 static void _makeFnTableW(PSecurityFunctionTableW fnTableW
,
392 const PSecurityFunctionTableA inFnTableA
,
393 const PSecurityFunctionTableW inFnTableW
)
399 /* The size of the version 1 table is based on platform sdk's
400 * sspi.h, though the sample ssp also provided with platform sdk
401 * implies only functions through QuerySecurityPackageInfoA are
402 * implemented (yikes)
404 size_t tableSize
= inFnTableW
->dwVersion
== 1 ?
405 (LPBYTE
)&inFnTableW
->SetContextAttributesW
-
406 (LPBYTE
)inFnTableW
: sizeof(SecurityFunctionTableW
);
408 memcpy(fnTableW
, inFnTableW
, tableSize
);
409 /* override this, since we can do it internally anyway */
410 fnTableW
->QuerySecurityPackageInfoW
=
411 QuerySecurityPackageInfoW
;
415 /* functions with thunks */
416 if (inFnTableA
->AcquireCredentialsHandleA
)
417 fnTableW
->AcquireCredentialsHandleW
=
418 thunk_AcquireCredentialsHandleW
;
419 if (inFnTableA
->InitializeSecurityContextA
)
420 fnTableW
->InitializeSecurityContextW
=
421 thunk_InitializeSecurityContextW
;
422 if (inFnTableA
->ImportSecurityContextA
)
423 fnTableW
->ImportSecurityContextW
=
424 thunk_ImportSecurityContextW
;
425 if (inFnTableA
->AddCredentialsA
)
426 fnTableW
->AddCredentialsW
=
427 thunk_AddCredentialsW
;
428 if (inFnTableA
->QueryCredentialsAttributesA
)
429 fnTableW
->QueryCredentialsAttributesW
=
430 thunk_QueryCredentialsAttributesW
;
431 if (inFnTableA
->QueryContextAttributesA
)
432 fnTableW
->QueryContextAttributesW
=
433 thunk_QueryContextAttributesW
;
434 if (inFnTableA
->SetContextAttributesA
)
435 fnTableW
->SetContextAttributesW
=
436 thunk_SetContextAttributesW
;
437 /* this can't be thunked, there's no extra param to know which
438 * package to forward to */
439 fnTableW
->EnumerateSecurityPackagesW
= NULL
;
440 /* functions with no thunks needed */
441 fnTableW
->AcceptSecurityContext
= inFnTableA
->AcceptSecurityContext
;
442 fnTableW
->CompleteAuthToken
= inFnTableA
->CompleteAuthToken
;
443 fnTableW
->DeleteSecurityContext
= inFnTableA
->DeleteSecurityContext
;
444 fnTableW
->ImpersonateSecurityContext
=
445 inFnTableA
->ImpersonateSecurityContext
;
446 fnTableW
->RevertSecurityContext
= inFnTableA
->RevertSecurityContext
;
447 fnTableW
->MakeSignature
= inFnTableA
->MakeSignature
;
448 fnTableW
->VerifySignature
= inFnTableA
->VerifySignature
;
449 fnTableW
->FreeContextBuffer
= inFnTableA
->FreeContextBuffer
;
450 fnTableW
->QuerySecurityPackageInfoW
=
451 QuerySecurityPackageInfoW
;
452 fnTableW
->ExportSecurityContext
=
453 inFnTableA
->ExportSecurityContext
;
454 fnTableW
->QuerySecurityContextToken
=
455 inFnTableA
->QuerySecurityContextToken
;
456 fnTableW
->EncryptMessage
= inFnTableA
->EncryptMessage
;
457 fnTableW
->DecryptMessage
= inFnTableA
->DecryptMessage
;
462 static void _copyPackageInfo(PSecPkgInfoW info
, const SecPkgInfoA
*inInfoA
,
463 const SecPkgInfoW
*inInfoW
)
465 if (info
&& (inInfoA
|| inInfoW
))
467 /* odd, I know, but up until Name and Comment the structures are
470 memcpy(info
, inInfoW
? inInfoW
: (PSecPkgInfoW
)inInfoA
, sizeof(*info
));
473 info
->Name
= SECUR32_strdupW(inInfoW
->Name
);
474 info
->Comment
= SECUR32_strdupW(inInfoW
->Comment
);
478 info
->Name
= SECUR32_AllocWideFromMultiByte(inInfoA
->Name
);
479 info
->Comment
= SECUR32_AllocWideFromMultiByte(inInfoA
->Comment
);
484 SecureProvider
*SECUR32_addProvider(PSecurityFunctionTableA fnTableA
,
485 PSecurityFunctionTableW fnTableW
, PWSTR moduleName
)
489 EnterCriticalSection(&cs
);
490 providerTable
= _resizeProviderTable(providerTable
,
491 providerTable
? providerTable
->numProviders
+ 1 : 1);
494 ret
= &providerTable
->table
[providerTable
->numProviders
++];
496 if (fnTableA
|| fnTableW
)
498 _makeFnTableA(&ret
->fnTableA
, fnTableA
, fnTableW
);
499 _makeFnTableW(&ret
->fnTableW
, fnTableA
, fnTableW
);
504 ret
->moduleName
= SECUR32_strdupW(moduleName
);
510 LeaveCriticalSection(&cs
);
514 void SECUR32_addPackages(SecureProvider
*provider
, ULONG toAdd
,
515 const SecPkgInfoA
*infoA
, const SecPkgInfoW
*infoW
)
518 assert(infoA
|| infoW
);
520 EnterCriticalSection(&cs
);
521 packageTable
= _resizePackageTable(packageTable
,
522 packageTable
? packageTable
->numPackages
+ toAdd
: toAdd
);
527 for (i
= 0; i
< toAdd
; i
++)
529 SecurePackage
*package
=
530 &packageTable
->table
[packageTable
->numPackages
+ i
];
532 package
->provider
= provider
;
533 _copyPackageInfo(&package
->infoW
,
534 infoA
? &infoA
[i
] : NULL
,
535 infoW
? &infoW
[i
] : NULL
);
537 packageTable
->numPackages
+= toAdd
;
539 LeaveCriticalSection(&cs
);
542 static void _tryLoadProvider(PWSTR moduleName
)
544 HMODULE lib
= LoadLibraryW(moduleName
);
548 INIT_SECURITY_INTERFACE_W pInitSecurityInterfaceW
=
549 (INIT_SECURITY_INTERFACE_W
)GetProcAddress(lib
,
550 SECURITY_ENTRYPOINT_ANSIW
);
551 INIT_SECURITY_INTERFACE_A pInitSecurityInterfaceA
=
552 (INIT_SECURITY_INTERFACE_A
)GetProcAddress(lib
,
553 SECURITY_ENTRYPOINT_ANSIA
);
555 TRACE("loaded %s, InitSecurityInterfaceA is %p, InitSecurityInterfaceW is %p\n",
556 debugstr_w(moduleName
), pInitSecurityInterfaceA
,
557 pInitSecurityInterfaceW
);
558 if (pInitSecurityInterfaceW
|| pInitSecurityInterfaceA
)
560 PSecurityFunctionTableA fnTableA
= NULL
;
561 PSecurityFunctionTableW fnTableW
= NULL
;
563 PSecPkgInfoA infoA
= NULL
;
564 PSecPkgInfoW infoW
= NULL
;
565 SECURITY_STATUS ret
= SEC_E_OK
;
567 if (pInitSecurityInterfaceA
)
568 fnTableA
= pInitSecurityInterfaceA();
569 if (pInitSecurityInterfaceW
)
570 fnTableW
= pInitSecurityInterfaceW();
571 if (fnTableW
&& fnTableW
->EnumerateSecurityPackagesW
)
572 ret
= fnTableW
->EnumerateSecurityPackagesW(&toAdd
, &infoW
);
573 else if (fnTableA
&& fnTableA
->EnumerateSecurityPackagesA
)
574 ret
= fnTableA
->EnumerateSecurityPackagesA(&toAdd
, &infoA
);
575 if (ret
== SEC_E_OK
&& toAdd
> 0 && (infoW
|| infoA
))
577 SecureProvider
*provider
= SECUR32_addProvider(NULL
, NULL
,
581 SECUR32_addPackages(provider
, toAdd
, infoA
, infoW
);
583 fnTableW
->FreeContextBuffer(infoW
);
585 fnTableA
->FreeContextBuffer(infoA
);
591 WARN("failed to load %s\n", debugstr_w(moduleName
));
594 static const WCHAR securityProvidersKeyW
[] = {
595 'S','Y','S','T','E','M','\\','C','u','r','r','e','n','t','C','o','n','t','r',
596 'o','l','S','e','t','\\','C','o','n','t','r','o','l','\\','S','e','c','u','r',
597 'i','t','y','P','r','o','v','i','d','e','r','s','\0'
599 static const WCHAR securityProvidersW
[] = {
600 'S','e','c','u','r','i','t','y','P','r','o','v','i','d','e','r','s',0
603 static void SECUR32_initializeProviders(void)
609 InitializeCriticalSection(&cs
);
610 /* First load built-in providers */
611 SECUR32_initSchannelSP();
612 /* Now load providers from registry */
613 apiRet
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, securityProvidersKeyW
, 0,
615 if (apiRet
== ERROR_SUCCESS
)
617 WCHAR securityPkgNames
[MAX_PATH
]; /* arbitrary len */
618 DWORD size
= sizeof(securityPkgNames
) / sizeof(WCHAR
), type
;
620 apiRet
= RegQueryValueExW(key
, securityProvidersW
, NULL
, &type
,
621 (PBYTE
)securityPkgNames
, &size
);
622 if (apiRet
== ERROR_SUCCESS
&& type
== REG_SZ
)
626 for (ptr
= securityPkgNames
;
627 ptr
< (PWSTR
)((PBYTE
)securityPkgNames
+ size
); )
631 for (comma
= ptr
; *comma
&& *comma
!= ','; comma
++)
635 for (; *ptr
&& isspace(*ptr
) && ptr
< securityPkgNames
+ size
;
639 _tryLoadProvider(ptr
);
640 ptr
+= lstrlenW(ptr
) + 1;
647 SecurePackage
*SECUR32_findPackageW(PWSTR packageName
)
649 SecurePackage
*ret
= NULL
;
651 if (packageTable
&& packageName
)
655 for (i
= 0, ret
= NULL
; !ret
&& i
< packageTable
->numPackages
; i
++)
656 if (!lstrcmpiW(packageTable
->table
[i
].infoW
.Name
, packageName
))
657 ret
= &packageTable
->table
[i
];
658 if (ret
&& ret
->provider
&& !ret
->provider
->loaded
)
660 ret
->provider
->lib
= LoadLibraryW(ret
->provider
->moduleName
);
661 if (ret
->provider
->lib
)
663 INIT_SECURITY_INTERFACE_W pInitSecurityInterfaceW
=
664 (INIT_SECURITY_INTERFACE_W
)GetProcAddress(ret
->provider
->lib
,
665 SECURITY_ENTRYPOINT_ANSIW
);
666 INIT_SECURITY_INTERFACE_A pInitSecurityInterfaceA
=
667 (INIT_SECURITY_INTERFACE_A
)GetProcAddress(ret
->provider
->lib
,
668 SECURITY_ENTRYPOINT_ANSIA
);
669 PSecurityFunctionTableA fnTableA
= NULL
;
670 PSecurityFunctionTableW fnTableW
= NULL
;
672 if (pInitSecurityInterfaceA
)
673 fnTableA
= pInitSecurityInterfaceA();
674 if (pInitSecurityInterfaceW
)
675 fnTableW
= pInitSecurityInterfaceW();
676 _makeFnTableA(&ret
->provider
->fnTableA
, fnTableA
, fnTableW
);
677 _makeFnTableW(&ret
->provider
->fnTableW
, fnTableA
, fnTableW
);
678 ret
->provider
->loaded
= TRUE
;
687 SecurePackage
*SECUR32_findPackageA(PSTR packageName
)
691 if (packageTable
&& packageName
)
693 UNICODE_STRING package
;
695 RtlCreateUnicodeStringFromAsciiz(&package
, packageName
);
696 ret
= SECUR32_findPackageW(package
.Buffer
);
697 RtlFreeUnicodeString(&package
);
704 static void SECUR32_freeProviders(void)
709 EnterCriticalSection(&cs
);
712 for (i
= 0; i
< packageTable
->numPackages
; i
++)
714 SECUR32_FREE(packageTable
->table
[i
].infoW
.Name
);
715 SECUR32_FREE(packageTable
->table
[i
].infoW
.Comment
);
717 HeapFree(GetProcessHeap(), 0, packageTable
);
722 for (i
= 0; i
< providerTable
->numProviders
; i
++)
724 if (providerTable
->table
[i
].moduleName
)
725 SECUR32_FREE(providerTable
->table
[i
].moduleName
);
726 if (providerTable
->table
[i
].lib
)
727 FreeLibrary(providerTable
->table
[i
].lib
);
729 HeapFree(GetProcessHeap(), 0, providerTable
);
730 providerTable
= NULL
;
732 LeaveCriticalSection(&cs
);
733 DeleteCriticalSection(&cs
);
736 /***********************************************************************
737 * FreeContextBuffer (SECUR32.@)
739 * Doh--if pv was allocated by a crypto package, this may not be correct.
740 * The sample ssp seems to use LocalAlloc/LocalFee, but there doesn't seem to
741 * be any guarantee, nor is there an alloc function in secur32.
743 SECURITY_STATUS WINAPI
FreeContextBuffer(PVOID pv
)
747 /* as it turns out, SECURITY_STATUSes are actually HRESULTS */
750 if (SECUR32_FREE(pv
) == NULL
)
753 ret
= HRESULT_FROM_WIN32(GetLastError());
756 ret
= HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER
);
760 /***********************************************************************
761 * EnumerateSecurityPackagesW (SECUR32.@)
763 SECURITY_STATUS WINAPI
EnumerateSecurityPackagesW(PULONG pcPackages
,
764 PSecPkgInfoW
*ppPackageInfo
)
766 SECURITY_STATUS ret
= SEC_E_OK
;
768 /* windows just crashes if pcPackages or ppPackageInfo is NULL, so will I */
770 EnterCriticalSection(&cs
);
776 bytesNeeded
= packageTable
->numPackages
* sizeof(SecPkgInfoW
);
777 for (i
= 0; i
< packageTable
->numPackages
; i
++)
779 if (packageTable
->table
[i
].infoW
.Name
)
781 (lstrlenW(packageTable
->table
[i
].infoW
.Name
) + 1) *
783 if (packageTable
->table
[i
].infoW
.Comment
)
785 (lstrlenW(packageTable
->table
[i
].infoW
.Comment
) + 1) *
790 *ppPackageInfo
= (PSecPkgInfoW
)SECUR32_ALLOC(bytesNeeded
);
795 *pcPackages
= packageTable
->numPackages
;
796 nextString
= (PWSTR
)((PBYTE
)*ppPackageInfo
+
797 packageTable
->numPackages
* sizeof(SecPkgInfoW
));
798 for (i
= 0; i
< packageTable
->numPackages
; i
++)
800 PSecPkgInfoW pkgInfo
= *ppPackageInfo
+ i
;
802 memcpy(pkgInfo
, &packageTable
->table
[i
].infoW
,
803 sizeof(SecPkgInfoW
));
804 if (packageTable
->table
[i
].infoW
.Name
)
806 pkgInfo
->Name
= nextString
;
807 lstrcpyW(nextString
, packageTable
->table
[i
].infoW
.Name
);
808 nextString
+= lstrlenW(nextString
) + 1;
811 pkgInfo
->Name
= NULL
;
812 if (packageTable
->table
[i
].infoW
.Comment
)
814 pkgInfo
->Comment
= nextString
;
816 packageTable
->table
[i
].infoW
.Comment
);
817 nextString
+= lstrlenW(nextString
) + 1;
820 pkgInfo
->Comment
= NULL
;
824 ret
= SEC_E_INSUFFICIENT_MEMORY
;
827 LeaveCriticalSection(&cs
);
831 /* Converts info (which is assumed to be an array of cPackages SecPkgInfoW
832 * structures) into an array of SecPkgInfoA structures, which it returns.
834 static PSecPkgInfoA
thunk_PSecPkgInfoWToA(ULONG cPackages
,
835 const PSecPkgInfoW info
)
841 size_t bytesNeeded
= cPackages
* sizeof(SecPkgInfoA
);
844 for (i
= 0; i
< cPackages
; i
++)
847 bytesNeeded
+= WideCharToMultiByte(CP_ACP
, 0, info
[i
].Name
,
848 -1, NULL
, 0, NULL
, NULL
);
850 bytesNeeded
+= WideCharToMultiByte(CP_ACP
, 0, info
[i
].Comment
,
851 -1, NULL
, 0, NULL
, NULL
);
853 ret
= (PSecPkgInfoA
)SECUR32_ALLOC(bytesNeeded
);
858 nextString
= (PSTR
)((PBYTE
)ret
+ cPackages
* sizeof(SecPkgInfoA
));
859 for (i
= 0; i
< cPackages
; i
++)
861 PSecPkgInfoA pkgInfo
= ret
+ i
;
864 memcpy(pkgInfo
, &info
[i
], sizeof(SecPkgInfoA
));
867 pkgInfo
->Name
= nextString
;
868 /* just repeat back to WideCharToMultiByte how many bytes
869 * it requires, since we asked it earlier
871 bytes
= WideCharToMultiByte(CP_ACP
, 0, info
[i
].Name
, -1,
872 NULL
, 0, NULL
, NULL
);
873 WideCharToMultiByte(CP_ACP
, 0, info
[i
].Name
, -1,
874 pkgInfo
->Name
, bytes
, NULL
, NULL
);
875 nextString
+= lstrlenA(nextString
) + 1;
878 pkgInfo
->Name
= NULL
;
881 pkgInfo
->Comment
= nextString
;
882 /* just repeat back to WideCharToMultiByte how many bytes
883 * it requires, since we asked it earlier
885 bytes
= WideCharToMultiByte(CP_ACP
, 0, info
[i
].Comment
, -1,
886 NULL
, 0, NULL
, NULL
);
887 WideCharToMultiByte(CP_ACP
, 0, info
[i
].Comment
, -1,
888 pkgInfo
->Comment
, bytes
, NULL
, NULL
);
889 nextString
+= lstrlenA(nextString
) + 1;
892 pkgInfo
->Comment
= NULL
;
901 /***********************************************************************
902 * EnumerateSecurityPackagesA (SECUR32.@)
904 SECURITY_STATUS WINAPI
EnumerateSecurityPackagesA(PULONG pcPackages
,
905 PSecPkgInfoA
*ppPackageInfo
)
910 ret
= EnumerateSecurityPackagesW(pcPackages
, &info
);
911 if (ret
== SEC_E_OK
&& *pcPackages
&& info
)
913 *ppPackageInfo
= thunk_PSecPkgInfoWToA(*pcPackages
, info
);
914 if (*pcPackages
&& !*ppPackageInfo
)
917 ret
= SEC_E_INSUFFICIENT_MEMORY
;
919 FreeContextBuffer(info
);
924 /***********************************************************************
925 * GetComputerObjectNameA (SECUR32.@)
927 BOOLEAN WINAPI
GetComputerObjectNameA(
928 EXTENDED_NAME_FORMAT NameFormat
, LPSTR lpNameBuffer
, PULONG nSize
)
930 FIXME("%d %p %p\n", NameFormat
, lpNameBuffer
, nSize
);
934 /***********************************************************************
935 * GetComputerObjectNameW (SECUR32.@)
937 BOOLEAN WINAPI
GetComputerObjectNameW(
938 EXTENDED_NAME_FORMAT NameFormat
, LPWSTR lpNameBuffer
, PULONG nSize
)
940 FIXME("%d %p %p\n", NameFormat
, lpNameBuffer
, nSize
);
944 BOOLEAN WINAPI
GetUserNameExA(
945 EXTENDED_NAME_FORMAT NameFormat
, LPSTR lpNameBuffer
, PULONG nSize
)
947 FIXME("%d %p %p\n", NameFormat
, lpNameBuffer
, nSize
);
951 BOOLEAN WINAPI
GetUserNameExW(
952 EXTENDED_NAME_FORMAT NameFormat
, LPWSTR lpNameBuffer
, PULONG nSize
)
954 FIXME("%d %p %p\n", NameFormat
, lpNameBuffer
, nSize
);
958 NTSTATUS WINAPI
LsaCallAuthenticationPackage(
959 HANDLE LsaHandle
, ULONG AuthenticationPackage
, PVOID ProtocolSubmitBuffer
,
960 ULONG SubmitBufferLength
, PVOID
* ProtocolReturnBuffer
, PULONG ReturnBufferLength
,
961 NTSTATUS
*ProtocolStatus
)
963 FIXME("%p %ld %p %ld %p %p %p\n", LsaHandle
, AuthenticationPackage
,
964 ProtocolSubmitBuffer
, SubmitBufferLength
, ProtocolReturnBuffer
,
965 ReturnBufferLength
, ProtocolStatus
);
969 NTSTATUS WINAPI
LsaConnectUntrusted(PHANDLE LsaHandle
)
971 FIXME("%p\n", LsaHandle
);
975 NTSTATUS WINAPI
LsaDeregisterLogonProcess(HANDLE LsaHandle
)
977 FIXME("%p\n", LsaHandle
);
981 BOOLEAN WINAPI
TranslateNameA(
982 LPCSTR lpAccountName
, EXTENDED_NAME_FORMAT AccountNameFormat
,
983 EXTENDED_NAME_FORMAT DesiredNameFormat
, LPSTR lpTranslatedName
,
986 FIXME("%p %d %d %p %p\n", lpAccountName
, AccountNameFormat
,
987 DesiredNameFormat
, lpTranslatedName
, nSize
);
991 BOOLEAN WINAPI
TranslateNameW(
992 LPCWSTR lpAccountName
, EXTENDED_NAME_FORMAT AccountNameFormat
,
993 EXTENDED_NAME_FORMAT DesiredNameFormat
, LPWSTR lpTranslatedName
,
996 FIXME("%p %d %d %p %p\n", lpAccountName
, AccountNameFormat
,
997 DesiredNameFormat
, lpTranslatedName
, nSize
);
1001 /***********************************************************************
1002 * DllMain (SECUR32.0)
1004 BOOL WINAPI
DllMain(HINSTANCE hinstDLL
, DWORD fdwReason
, LPVOID lpvReserved
)
1006 if (fdwReason
== DLL_PROCESS_ATTACH
)
1008 DisableThreadLibraryCalls(hinstDLL
);
1009 SECUR32_initializeProviders();
1011 else if (fdwReason
== DLL_PROCESS_DETACH
)
1013 SECUR32_freeProviders();