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 ret->moduleName = NULL;
499 _makeFnTableA(&ret->fnTableA, fnTableA, fnTableW);
500 _makeFnTableW(&ret->fnTableW, fnTableA, fnTableW);
505 ret->moduleName = SECUR32_strdupW(moduleName);
511 LeaveCriticalSection(&cs);
515 void SECUR32_addPackages(SecureProvider *provider, ULONG toAdd,
516 const SecPkgInfoA *infoA, const SecPkgInfoW *infoW)
519 assert(infoA || infoW);
521 EnterCriticalSection(&cs);
522 packageTable = _resizePackageTable(packageTable,
523 packageTable ? packageTable->numPackages + toAdd : toAdd);
528 for (i = 0; i < toAdd; i++)
530 SecurePackage *package =
531 &packageTable->table[packageTable->numPackages + i];
533 package->provider = provider;
534 _copyPackageInfo(&package->infoW,
535 infoA ? &infoA[i] : NULL,
536 infoW ? &infoW[i] : NULL);
538 packageTable->numPackages += toAdd;
540 LeaveCriticalSection(&cs);
543 static void _tryLoadProvider(PWSTR moduleName)
545 HMODULE lib = LoadLibraryW(moduleName);
549 INIT_SECURITY_INTERFACE_W pInitSecurityInterfaceW =
550 (INIT_SECURITY_INTERFACE_W)GetProcAddress(lib,
551 SECURITY_ENTRYPOINT_ANSIW);
552 INIT_SECURITY_INTERFACE_A pInitSecurityInterfaceA =
553 (INIT_SECURITY_INTERFACE_A)GetProcAddress(lib,
554 SECURITY_ENTRYPOINT_ANSIA);
556 TRACE("loaded %s, InitSecurityInterfaceA is %p, InitSecurityInterfaceW is %p\n",
557 debugstr_w(moduleName), pInitSecurityInterfaceA,
558 pInitSecurityInterfaceW);
559 if (pInitSecurityInterfaceW || pInitSecurityInterfaceA)
561 PSecurityFunctionTableA fnTableA = NULL;
562 PSecurityFunctionTableW fnTableW = NULL;
564 PSecPkgInfoA infoA = NULL;
565 PSecPkgInfoW infoW = NULL;
566 SECURITY_STATUS ret = SEC_E_OK;
568 if (pInitSecurityInterfaceA)
569 fnTableA = pInitSecurityInterfaceA();
570 if (pInitSecurityInterfaceW)
571 fnTableW = pInitSecurityInterfaceW();
572 if (fnTableW && fnTableW->EnumerateSecurityPackagesW)
573 ret = fnTableW->EnumerateSecurityPackagesW(&toAdd, &infoW);
574 else if (fnTableA && fnTableA->EnumerateSecurityPackagesA)
575 ret = fnTableA->EnumerateSecurityPackagesA(&toAdd, &infoA);
576 if (ret == SEC_E_OK && toAdd > 0 && (infoW || infoA))
578 SecureProvider *provider = SECUR32_addProvider(NULL, NULL,
582 SECUR32_addPackages(provider, toAdd, infoA, infoW);
584 fnTableW->FreeContextBuffer(infoW);
586 fnTableA->FreeContextBuffer(infoA);
592 WARN("failed to load %s\n", debugstr_w(moduleName));
595 static const WCHAR securityProvidersKeyW[] = {
596 'S','Y','S','T','E','M','\\','C','u','r','r','e','n','t','C','o','n','t','r',
597 'o','l','S','e','t','\\','C','o','n','t','r','o','l','\\','S','e','c','u','r',
598 'i','t','y','P','r','o','v','i','d','e','r','s','\0'
600 static const WCHAR securityProvidersW[] = {
601 'S','e','c','u','r','i','t','y','P','r','o','v','i','d','e','r','s',0
604 static void SECUR32_initializeProviders(void)
610 InitializeCriticalSection(&cs);
611 /* First load built-in providers */
612 SECUR32_initSchannelSP();
613 SECUR32_initNegotiateSP();
614 SECUR32_initNTLMSP();
615 /* Now load providers from registry */
616 apiRet = RegOpenKeyExW(HKEY_LOCAL_MACHINE, securityProvidersKeyW, 0,
618 if (apiRet == ERROR_SUCCESS)
620 WCHAR securityPkgNames[MAX_PATH]; /* arbitrary len */
621 DWORD size = sizeof(securityPkgNames) / sizeof(WCHAR), type;
623 apiRet = RegQueryValueExW(key, securityProvidersW, NULL, &type,
624 (PBYTE)securityPkgNames, &size);
625 if (apiRet == ERROR_SUCCESS && type == REG_SZ)
629 for (ptr = securityPkgNames;
630 ptr < (PWSTR)((PBYTE)securityPkgNames + size); )
634 for (comma = ptr; *comma && *comma != ','; comma++)
638 for (; *ptr && isspace(*ptr) && ptr < securityPkgNames + size;
642 _tryLoadProvider(ptr);
643 ptr += lstrlenW(ptr) + 1;
650 SecurePackage *SECUR32_findPackageW(PWSTR packageName)
652 SecurePackage *ret = NULL;
654 if (packageTable && packageName)
658 for (i = 0, ret = NULL; !ret && i < packageTable->numPackages; i++)
659 if (!lstrcmpiW(packageTable->table[i].infoW.Name, packageName))
660 ret = &packageTable->table[i];
661 if (ret && ret->provider && !ret->provider->loaded)
663 ret->provider->lib = LoadLibraryW(ret->provider->moduleName);
664 if (ret->provider->lib)
666 INIT_SECURITY_INTERFACE_W pInitSecurityInterfaceW =
667 (INIT_SECURITY_INTERFACE_W)GetProcAddress(ret->provider->lib,
668 SECURITY_ENTRYPOINT_ANSIW);
669 INIT_SECURITY_INTERFACE_A pInitSecurityInterfaceA =
670 (INIT_SECURITY_INTERFACE_A)GetProcAddress(ret->provider->lib,
671 SECURITY_ENTRYPOINT_ANSIA);
672 PSecurityFunctionTableA fnTableA = NULL;
673 PSecurityFunctionTableW fnTableW = NULL;
675 if (pInitSecurityInterfaceA)
676 fnTableA = pInitSecurityInterfaceA();
677 if (pInitSecurityInterfaceW)
678 fnTableW = pInitSecurityInterfaceW();
679 _makeFnTableA(&ret->provider->fnTableA, fnTableA, fnTableW);
680 _makeFnTableW(&ret->provider->fnTableW, fnTableA, fnTableW);
681 ret->provider->loaded = TRUE;
690 SecurePackage *SECUR32_findPackageA(PSTR packageName)
694 if (packageTable && packageName)
696 UNICODE_STRING package;
698 RtlCreateUnicodeStringFromAsciiz(&package, packageName);
699 ret = SECUR32_findPackageW(package.Buffer);
700 RtlFreeUnicodeString(&package);
707 static void SECUR32_freeProviders(void)
712 EnterCriticalSection(&cs);
715 for (i = 0; i < packageTable->numPackages; i++)
717 SECUR32_FREE(packageTable->table[i].infoW.Name);
718 SECUR32_FREE(packageTable->table[i].infoW.Comment);
720 HeapFree(GetProcessHeap(), 0, packageTable);
725 for (i = 0; i < providerTable->numProviders; i++)
727 if (providerTable->table[i].moduleName)
728 SECUR32_FREE(providerTable->table[i].moduleName);
729 if (providerTable->table[i].lib)
730 FreeLibrary(providerTable->table[i].lib);
732 HeapFree(GetProcessHeap(), 0, providerTable);
733 providerTable = NULL;
735 LeaveCriticalSection(&cs);
736 DeleteCriticalSection(&cs);
739 /***********************************************************************
740 * FreeContextBuffer (SECUR32.@)
742 * Doh--if pv was allocated by a crypto package, this may not be correct.
743 * The sample ssp seems to use LocalAlloc/LocalFee, but there doesn't seem to
744 * be any guarantee, nor is there an alloc function in secur32.
746 SECURITY_STATUS WINAPI FreeContextBuffer(PVOID pv)
750 /* as it turns out, SECURITY_STATUSes are actually HRESULTS */
753 if (SECUR32_FREE(pv) == NULL)
756 ret = HRESULT_FROM_WIN32(GetLastError());
759 ret = HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER);
763 /***********************************************************************
764 * EnumerateSecurityPackagesW (SECUR32.@)
766 SECURITY_STATUS WINAPI EnumerateSecurityPackagesW(PULONG pcPackages,
767 PSecPkgInfoW *ppPackageInfo)
769 SECURITY_STATUS ret = SEC_E_OK;
771 /* windows just crashes if pcPackages or ppPackageInfo is NULL, so will I */
773 EnterCriticalSection(&cs);
779 bytesNeeded = packageTable->numPackages * sizeof(SecPkgInfoW);
780 for (i = 0; i < packageTable->numPackages; i++)
782 if (packageTable->table[i].infoW.Name)
784 (lstrlenW(packageTable->table[i].infoW.Name) + 1) *
786 if (packageTable->table[i].infoW.Comment)
788 (lstrlenW(packageTable->table[i].infoW.Comment) + 1) *
793 *ppPackageInfo = (PSecPkgInfoW)SECUR32_ALLOC(bytesNeeded);
798 *pcPackages = packageTable->numPackages;
799 nextString = (PWSTR)((PBYTE)*ppPackageInfo +
800 packageTable->numPackages * sizeof(SecPkgInfoW));
801 for (i = 0; i < packageTable->numPackages; i++)
803 PSecPkgInfoW pkgInfo = *ppPackageInfo + i;
805 memcpy(pkgInfo, &packageTable->table[i].infoW,
806 sizeof(SecPkgInfoW));
807 if (packageTable->table[i].infoW.Name)
809 pkgInfo->Name = nextString;
810 lstrcpyW(nextString, packageTable->table[i].infoW.Name);
811 nextString += lstrlenW(nextString) + 1;
814 pkgInfo->Name = NULL;
815 if (packageTable->table[i].infoW.Comment)
817 pkgInfo->Comment = nextString;
819 packageTable->table[i].infoW.Comment);
820 nextString += lstrlenW(nextString) + 1;
823 pkgInfo->Comment = NULL;
827 ret = SEC_E_INSUFFICIENT_MEMORY;
830 LeaveCriticalSection(&cs);
834 /* Converts info (which is assumed to be an array of cPackages SecPkgInfoW
835 * structures) into an array of SecPkgInfoA structures, which it returns.
837 static PSecPkgInfoA thunk_PSecPkgInfoWToA(ULONG cPackages,
838 const PSecPkgInfoW info)
844 size_t bytesNeeded = cPackages * sizeof(SecPkgInfoA);
847 for (i = 0; i < cPackages; i++)
850 bytesNeeded += WideCharToMultiByte(CP_ACP, 0, info[i].Name,
851 -1, NULL, 0, NULL, NULL);
853 bytesNeeded += WideCharToMultiByte(CP_ACP, 0, info[i].Comment,
854 -1, NULL, 0, NULL, NULL);
856 ret = (PSecPkgInfoA)SECUR32_ALLOC(bytesNeeded);
861 nextString = (PSTR)((PBYTE)ret + cPackages * sizeof(SecPkgInfoA));
862 for (i = 0; i < cPackages; i++)
864 PSecPkgInfoA pkgInfo = ret + i;
867 memcpy(pkgInfo, &info[i], sizeof(SecPkgInfoA));
870 pkgInfo->Name = nextString;
871 /* just repeat back to WideCharToMultiByte how many bytes
872 * it requires, since we asked it earlier
874 bytes = WideCharToMultiByte(CP_ACP, 0, info[i].Name, -1,
875 NULL, 0, NULL, NULL);
876 WideCharToMultiByte(CP_ACP, 0, info[i].Name, -1,
877 pkgInfo->Name, bytes, NULL, NULL);
878 nextString += lstrlenA(nextString) + 1;
881 pkgInfo->Name = NULL;
884 pkgInfo->Comment = nextString;
885 /* just repeat back to WideCharToMultiByte how many bytes
886 * it requires, since we asked it earlier
888 bytes = WideCharToMultiByte(CP_ACP, 0, info[i].Comment, -1,
889 NULL, 0, NULL, NULL);
890 WideCharToMultiByte(CP_ACP, 0, info[i].Comment, -1,
891 pkgInfo->Comment, bytes, NULL, NULL);
892 nextString += lstrlenA(nextString) + 1;
895 pkgInfo->Comment = NULL;
904 /***********************************************************************
905 * EnumerateSecurityPackagesA (SECUR32.@)
907 SECURITY_STATUS WINAPI EnumerateSecurityPackagesA(PULONG pcPackages,
908 PSecPkgInfoA *ppPackageInfo)
913 ret = EnumerateSecurityPackagesW(pcPackages, &info);
914 if (ret == SEC_E_OK && *pcPackages && info)
916 *ppPackageInfo = thunk_PSecPkgInfoWToA(*pcPackages, info);
917 if (*pcPackages && !*ppPackageInfo)
920 ret = SEC_E_INSUFFICIENT_MEMORY;
922 FreeContextBuffer(info);
927 /***********************************************************************
928 * GetComputerObjectNameA (SECUR32.@)
930 BOOLEAN WINAPI GetComputerObjectNameA(
931 EXTENDED_NAME_FORMAT NameFormat, LPSTR lpNameBuffer, PULONG nSize)
933 FIXME("%d %p %p\n", NameFormat, lpNameBuffer, nSize);
937 /***********************************************************************
938 * GetComputerObjectNameW (SECUR32.@)
940 BOOLEAN WINAPI GetComputerObjectNameW(
941 EXTENDED_NAME_FORMAT NameFormat, LPWSTR lpNameBuffer, PULONG nSize)
943 FIXME("%d %p %p\n", NameFormat, lpNameBuffer, nSize);
947 BOOLEAN WINAPI GetUserNameExA(
948 EXTENDED_NAME_FORMAT NameFormat, LPSTR lpNameBuffer, PULONG nSize)
950 FIXME("%d %p %p\n", NameFormat, lpNameBuffer, nSize);
954 BOOLEAN WINAPI GetUserNameExW(
955 EXTENDED_NAME_FORMAT NameFormat, LPWSTR lpNameBuffer, PULONG nSize)
957 FIXME("%d %p %p\n", NameFormat, lpNameBuffer, nSize);
961 NTSTATUS WINAPI LsaCallAuthenticationPackage(
962 HANDLE LsaHandle, ULONG AuthenticationPackage, PVOID ProtocolSubmitBuffer,
963 ULONG SubmitBufferLength, PVOID* ProtocolReturnBuffer, PULONG ReturnBufferLength,
964 PNTSTATUS ProtocolStatus)
966 FIXME("%p %ld %p %ld %p %p %p\n", LsaHandle, AuthenticationPackage,
967 ProtocolSubmitBuffer, SubmitBufferLength, ProtocolReturnBuffer,
968 ReturnBufferLength, ProtocolStatus);
972 NTSTATUS WINAPI LsaConnectUntrusted(PHANDLE LsaHandle)
974 FIXME("%p\n", LsaHandle);
978 NTSTATUS WINAPI LsaDeregisterLogonProcess(HANDLE LsaHandle)
980 FIXME("%p\n", LsaHandle);
984 BOOLEAN WINAPI TranslateNameA(
985 LPCSTR lpAccountName, EXTENDED_NAME_FORMAT AccountNameFormat,
986 EXTENDED_NAME_FORMAT DesiredNameFormat, LPSTR lpTranslatedName,
989 FIXME("%p %d %d %p %p\n", lpAccountName, AccountNameFormat,
990 DesiredNameFormat, lpTranslatedName, nSize);
994 BOOLEAN WINAPI TranslateNameW(
995 LPCWSTR lpAccountName, EXTENDED_NAME_FORMAT AccountNameFormat,
996 EXTENDED_NAME_FORMAT DesiredNameFormat, LPWSTR lpTranslatedName,
999 FIXME("%p %d %d %p %p\n", lpAccountName, AccountNameFormat,
1000 DesiredNameFormat, lpTranslatedName, nSize);
1004 /***********************************************************************
1005 * DllMain (SECUR32.0)
1007 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
1009 if (fdwReason == DLL_PROCESS_ATTACH)
1011 DisableThreadLibraryCalls(hinstDLL);
1012 SECUR32_initializeProviders();
1014 else if (fdwReason == DLL_PROCESS_DETACH)
1016 SECUR32_freeProviders();