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/list.h"
34 #include "wine/debug.h"
36 WINE_DEFAULT_DEBUG_CHANNEL(secur32
);
42 typedef struct _SecurePackageTable
49 typedef struct _SecureProviderTable
54 } SecureProviderTable
;
60 /* Tries to load moduleName as a provider. If successful, enumerates what
61 * packages it can and adds them to the package and provider tables. Resizes
62 * tables as necessary.
64 static void _tryLoadProvider(PWSTR moduleName
);
66 /* Initialization: read securityproviders value and attempt to open each dll
67 * there. For each DLL, call _tryLoadProvider to see if it's really an SSP.
68 * Two undocumented functions, AddSecurityPackage(A/W) and
69 * DeleteSecurityPackage(A/W), seem suspiciously like they'd register or
70 * unregister a dll, but I'm not sure.
72 static void SECUR32_initializeProviders(void);
74 /* Frees all loaded packages and providers */
75 static void SECUR32_freeProviders(void);
81 static CRITICAL_SECTION cs
;
82 static SecurePackageTable
*packageTable
= NULL
;
83 static SecureProviderTable
*providerTable
= NULL
;
85 static SecurityFunctionTableA securityFunctionTableA
= {
86 SECURITY_SUPPORT_PROVIDER_INTERFACE_VERSION_2
,
87 EnumerateSecurityPackagesA
,
88 QueryCredentialsAttributesA
,
89 AcquireCredentialsHandleA
,
90 FreeCredentialsHandle
,
92 InitializeSecurityContextA
,
93 AcceptSecurityContext
,
95 DeleteSecurityContext
,
97 QueryContextAttributesA
,
98 ImpersonateSecurityContext
,
99 RevertSecurityContext
,
103 QuerySecurityPackageInfoA
,
104 NULL
, /* Reserved3 */
105 NULL
, /* Reserved4 */
106 ExportSecurityContext
,
107 ImportSecurityContextA
,
109 NULL
, /* Reserved8 */
110 QuerySecurityContextToken
,
113 SetContextAttributesA
116 static SecurityFunctionTableW securityFunctionTableW
= {
117 SECURITY_SUPPORT_PROVIDER_INTERFACE_VERSION_2
,
118 EnumerateSecurityPackagesW
,
119 QueryCredentialsAttributesW
,
120 AcquireCredentialsHandleW
,
121 FreeCredentialsHandle
,
122 NULL
, /* Reserved2 */
123 InitializeSecurityContextW
,
124 AcceptSecurityContext
,
126 DeleteSecurityContext
,
128 QueryContextAttributesW
,
129 ImpersonateSecurityContext
,
130 RevertSecurityContext
,
134 QuerySecurityPackageInfoW
,
135 NULL
, /* Reserved3 */
136 NULL
, /* Reserved4 */
137 ExportSecurityContext
,
138 ImportSecurityContextW
,
140 NULL
, /* Reserved8 */
141 QuerySecurityContextToken
,
144 SetContextAttributesW
147 /***********************************************************************
148 * InitSecurityInterfaceA (SECUR32.@)
150 PSecurityFunctionTableA WINAPI
InitSecurityInterfaceA(void)
152 return &securityFunctionTableA
;
155 /***********************************************************************
156 * InitSecurityInterfaceW (SECUR32.@)
158 PSecurityFunctionTableW WINAPI
InitSecurityInterfaceW(void)
160 return &securityFunctionTableW
;
163 PWSTR
SECUR32_strdupW(PCWSTR str
)
169 ret
= (PWSTR
)SECUR32_ALLOC((lstrlenW(str
) + 1) * sizeof(WCHAR
));
178 PWSTR
SECUR32_AllocWideFromMultiByte(PCSTR str
)
184 int charsNeeded
= MultiByteToWideChar(CP_ACP
, 0, str
, -1, NULL
, 0);
188 ret
= (PWSTR
)SECUR32_ALLOC(charsNeeded
* sizeof(WCHAR
));
190 MultiByteToWideChar(CP_ACP
, 0, str
, -1, ret
, charsNeeded
);
200 PSTR
SECUR32_AllocMultiByteFromWide(PCWSTR str
)
206 int charsNeeded
= WideCharToMultiByte(CP_ACP
, 0, str
, -1, NULL
, 0,
211 ret
= (PSTR
)SECUR32_ALLOC(charsNeeded
);
213 WideCharToMultiByte(CP_ACP
, 0, str
, -1, ret
, charsNeeded
,
224 static void _makeFnTableA(PSecurityFunctionTableA fnTableA
,
225 const PSecurityFunctionTableA inFnTableA
,
226 const PSecurityFunctionTableW inFnTableW
)
232 /* The size of the version 1 table is based on platform sdk's
233 * sspi.h, though the sample ssp also provided with platform sdk
234 * implies only functions through QuerySecurityPackageInfoA are
235 * implemented (yikes)
237 size_t tableSize
= inFnTableA
->dwVersion
== 1 ?
238 (LPBYTE
)&inFnTableA
->SetContextAttributesA
-
239 (LPBYTE
)inFnTableA
: sizeof(SecurityFunctionTableA
);
241 memcpy(fnTableA
, inFnTableA
, tableSize
);
242 /* override this, since we can do it internally anyway */
243 fnTableA
->QuerySecurityPackageInfoA
=
244 QuerySecurityPackageInfoA
;
248 /* functions with thunks */
249 if (inFnTableW
->AcquireCredentialsHandleW
)
250 fnTableA
->AcquireCredentialsHandleA
=
251 thunk_AcquireCredentialsHandleA
;
252 if (inFnTableW
->InitializeSecurityContextW
)
253 fnTableA
->InitializeSecurityContextA
=
254 thunk_InitializeSecurityContextA
;
255 if (inFnTableW
->ImportSecurityContextW
)
256 fnTableA
->ImportSecurityContextA
=
257 thunk_ImportSecurityContextA
;
258 if (inFnTableW
->AddCredentialsW
)
259 fnTableA
->AddCredentialsA
=
260 thunk_AddCredentialsA
;
261 if (inFnTableW
->QueryCredentialsAttributesW
)
262 fnTableA
->QueryCredentialsAttributesA
=
263 thunk_QueryCredentialsAttributesA
;
264 if (inFnTableW
->QueryContextAttributesW
)
265 fnTableA
->QueryContextAttributesA
=
266 thunk_QueryContextAttributesA
;
267 if (inFnTableW
->SetContextAttributesW
)
268 fnTableA
->SetContextAttributesA
=
269 thunk_SetContextAttributesA
;
270 /* this can't be thunked, there's no extra param to know which
271 * package to forward to */
272 fnTableA
->EnumerateSecurityPackagesA
= NULL
;
273 /* functions with no thunks needed */
274 fnTableA
->AcceptSecurityContext
= inFnTableW
->AcceptSecurityContext
;
275 fnTableA
->CompleteAuthToken
= inFnTableW
->CompleteAuthToken
;
276 fnTableA
->DeleteSecurityContext
= inFnTableW
->DeleteSecurityContext
;
277 fnTableA
->ImpersonateSecurityContext
=
278 inFnTableW
->ImpersonateSecurityContext
;
279 fnTableA
->RevertSecurityContext
= inFnTableW
->RevertSecurityContext
;
280 fnTableA
->MakeSignature
= inFnTableW
->MakeSignature
;
281 fnTableA
->VerifySignature
= inFnTableW
->VerifySignature
;
282 fnTableA
->FreeContextBuffer
= inFnTableW
->FreeContextBuffer
;
283 fnTableA
->QuerySecurityPackageInfoA
=
284 QuerySecurityPackageInfoA
;
285 fnTableA
->ExportSecurityContext
=
286 inFnTableW
->ExportSecurityContext
;
287 fnTableA
->QuerySecurityContextToken
=
288 inFnTableW
->QuerySecurityContextToken
;
289 fnTableA
->EncryptMessage
= inFnTableW
->EncryptMessage
;
290 fnTableA
->DecryptMessage
= inFnTableW
->DecryptMessage
;
295 static void _makeFnTableW(PSecurityFunctionTableW fnTableW
,
296 const PSecurityFunctionTableA inFnTableA
,
297 const PSecurityFunctionTableW inFnTableW
)
303 /* The size of the version 1 table is based on platform sdk's
304 * sspi.h, though the sample ssp also provided with platform sdk
305 * implies only functions through QuerySecurityPackageInfoA are
306 * implemented (yikes)
308 size_t tableSize
= inFnTableW
->dwVersion
== 1 ?
309 (LPBYTE
)&inFnTableW
->SetContextAttributesW
-
310 (LPBYTE
)inFnTableW
: sizeof(SecurityFunctionTableW
);
312 memcpy(fnTableW
, inFnTableW
, tableSize
);
313 /* override this, since we can do it internally anyway */
314 fnTableW
->QuerySecurityPackageInfoW
=
315 QuerySecurityPackageInfoW
;
319 /* functions with thunks */
320 if (inFnTableA
->AcquireCredentialsHandleA
)
321 fnTableW
->AcquireCredentialsHandleW
=
322 thunk_AcquireCredentialsHandleW
;
323 if (inFnTableA
->InitializeSecurityContextA
)
324 fnTableW
->InitializeSecurityContextW
=
325 thunk_InitializeSecurityContextW
;
326 if (inFnTableA
->ImportSecurityContextA
)
327 fnTableW
->ImportSecurityContextW
=
328 thunk_ImportSecurityContextW
;
329 if (inFnTableA
->AddCredentialsA
)
330 fnTableW
->AddCredentialsW
=
331 thunk_AddCredentialsW
;
332 if (inFnTableA
->QueryCredentialsAttributesA
)
333 fnTableW
->QueryCredentialsAttributesW
=
334 thunk_QueryCredentialsAttributesW
;
335 if (inFnTableA
->QueryContextAttributesA
)
336 fnTableW
->QueryContextAttributesW
=
337 thunk_QueryContextAttributesW
;
338 if (inFnTableA
->SetContextAttributesA
)
339 fnTableW
->SetContextAttributesW
=
340 thunk_SetContextAttributesW
;
341 /* this can't be thunked, there's no extra param to know which
342 * package to forward to */
343 fnTableW
->EnumerateSecurityPackagesW
= NULL
;
344 /* functions with no thunks needed */
345 fnTableW
->AcceptSecurityContext
= inFnTableA
->AcceptSecurityContext
;
346 fnTableW
->CompleteAuthToken
= inFnTableA
->CompleteAuthToken
;
347 fnTableW
->DeleteSecurityContext
= inFnTableA
->DeleteSecurityContext
;
348 fnTableW
->ImpersonateSecurityContext
=
349 inFnTableA
->ImpersonateSecurityContext
;
350 fnTableW
->RevertSecurityContext
= inFnTableA
->RevertSecurityContext
;
351 fnTableW
->MakeSignature
= inFnTableA
->MakeSignature
;
352 fnTableW
->VerifySignature
= inFnTableA
->VerifySignature
;
353 fnTableW
->FreeContextBuffer
= inFnTableA
->FreeContextBuffer
;
354 fnTableW
->QuerySecurityPackageInfoW
=
355 QuerySecurityPackageInfoW
;
356 fnTableW
->ExportSecurityContext
=
357 inFnTableA
->ExportSecurityContext
;
358 fnTableW
->QuerySecurityContextToken
=
359 inFnTableA
->QuerySecurityContextToken
;
360 fnTableW
->EncryptMessage
= inFnTableA
->EncryptMessage
;
361 fnTableW
->DecryptMessage
= inFnTableA
->DecryptMessage
;
366 static void _copyPackageInfo(PSecPkgInfoW info
, const SecPkgInfoA
*inInfoA
,
367 const SecPkgInfoW
*inInfoW
)
369 if (info
&& (inInfoA
|| inInfoW
))
371 /* odd, I know, but up until Name and Comment the structures are
374 memcpy(info
, inInfoW
? inInfoW
: (PSecPkgInfoW
)inInfoA
, sizeof(*info
));
377 info
->Name
= SECUR32_strdupW(inInfoW
->Name
);
378 info
->Comment
= SECUR32_strdupW(inInfoW
->Comment
);
382 info
->Name
= SECUR32_AllocWideFromMultiByte(inInfoA
->Name
);
383 info
->Comment
= SECUR32_AllocWideFromMultiByte(inInfoA
->Comment
);
388 SecureProvider
*SECUR32_addProvider(PSecurityFunctionTableA fnTableA
,
389 PSecurityFunctionTableW fnTableW
, PWSTR moduleName
)
393 EnterCriticalSection(&cs
);
397 providerTable
= HeapAlloc(GetProcessHeap(), 0, sizeof(SecureProviderTable
));
401 list_init(&providerTable
->table
);
404 ret
= HeapAlloc(GetProcessHeap(), 0, sizeof(SecureProvider
));
408 list_add_tail(&providerTable
->table
, &ret
->entry
);
411 if (fnTableA
|| fnTableW
)
413 ret
->moduleName
= NULL
;
414 _makeFnTableA(&ret
->fnTableA
, fnTableA
, fnTableW
);
415 _makeFnTableW(&ret
->fnTableW
, fnTableA
, fnTableW
);
420 ret
->moduleName
= SECUR32_strdupW(moduleName
);
424 LeaveCriticalSection(&cs
);
428 void SECUR32_addPackages(SecureProvider
*provider
, ULONG toAdd
,
429 const SecPkgInfoA
*infoA
, const SecPkgInfoW
*infoW
)
434 assert(infoA
|| infoW
);
436 EnterCriticalSection(&cs
);
440 packageTable
= HeapAlloc(GetProcessHeap(), 0, sizeof(SecurePackageTable
));
444 packageTable
->numPackages
= 0;
445 list_init(&packageTable
->table
);
448 for (i
= 0; i
< toAdd
; i
++)
450 SecurePackage
*package
= HeapAlloc(GetProcessHeap(), 0, sizeof(SecurePackage
));
454 list_add_tail(&packageTable
->table
, &package
->entry
);
456 package
->provider
= provider
;
457 _copyPackageInfo(&package
->infoW
,
458 infoA
? &infoA
[i
] : NULL
,
459 infoW
? &infoW
[i
] : NULL
);
461 packageTable
->numPackages
+= toAdd
;
463 LeaveCriticalSection(&cs
);
466 static void _tryLoadProvider(PWSTR moduleName
)
468 HMODULE lib
= LoadLibraryW(moduleName
);
472 INIT_SECURITY_INTERFACE_W pInitSecurityInterfaceW
=
473 (INIT_SECURITY_INTERFACE_W
)GetProcAddress(lib
,
474 SECURITY_ENTRYPOINT_ANSIW
);
475 INIT_SECURITY_INTERFACE_A pInitSecurityInterfaceA
=
476 (INIT_SECURITY_INTERFACE_A
)GetProcAddress(lib
,
477 SECURITY_ENTRYPOINT_ANSIA
);
479 TRACE("loaded %s, InitSecurityInterfaceA is %p, InitSecurityInterfaceW is %p\n",
480 debugstr_w(moduleName
), pInitSecurityInterfaceA
,
481 pInitSecurityInterfaceW
);
482 if (pInitSecurityInterfaceW
|| pInitSecurityInterfaceA
)
484 PSecurityFunctionTableA fnTableA
= NULL
;
485 PSecurityFunctionTableW fnTableW
= NULL
;
487 PSecPkgInfoA infoA
= NULL
;
488 PSecPkgInfoW infoW
= NULL
;
489 SECURITY_STATUS ret
= SEC_E_OK
;
491 if (pInitSecurityInterfaceA
)
492 fnTableA
= pInitSecurityInterfaceA();
493 if (pInitSecurityInterfaceW
)
494 fnTableW
= pInitSecurityInterfaceW();
495 if (fnTableW
&& fnTableW
->EnumerateSecurityPackagesW
)
496 ret
= fnTableW
->EnumerateSecurityPackagesW(&toAdd
, &infoW
);
497 else if (fnTableA
&& fnTableA
->EnumerateSecurityPackagesA
)
498 ret
= fnTableA
->EnumerateSecurityPackagesA(&toAdd
, &infoA
);
499 if (ret
== SEC_E_OK
&& toAdd
> 0 && (infoW
|| infoA
))
501 SecureProvider
*provider
= SECUR32_addProvider(NULL
, NULL
,
505 SECUR32_addPackages(provider
, toAdd
, infoA
, infoW
);
507 fnTableW
->FreeContextBuffer(infoW
);
509 fnTableA
->FreeContextBuffer(infoA
);
515 WARN("failed to load %s\n", debugstr_w(moduleName
));
518 static const WCHAR securityProvidersKeyW
[] = {
519 'S','Y','S','T','E','M','\\','C','u','r','r','e','n','t','C','o','n','t','r',
520 'o','l','S','e','t','\\','C','o','n','t','r','o','l','\\','S','e','c','u','r',
521 'i','t','y','P','r','o','v','i','d','e','r','s','\0'
523 static const WCHAR securityProvidersW
[] = {
524 'S','e','c','u','r','i','t','y','P','r','o','v','i','d','e','r','s',0
527 static void SECUR32_initializeProviders(void)
533 InitializeCriticalSection(&cs
);
534 /* First load built-in providers */
535 SECUR32_initSchannelSP();
536 SECUR32_initNegotiateSP();
537 SECUR32_initNTLMSP();
538 /* Now load providers from registry */
539 apiRet
= RegOpenKeyExW(HKEY_LOCAL_MACHINE
, securityProvidersKeyW
, 0,
541 if (apiRet
== ERROR_SUCCESS
)
543 WCHAR securityPkgNames
[MAX_PATH
]; /* arbitrary len */
544 DWORD size
= sizeof(securityPkgNames
) / sizeof(WCHAR
), type
;
546 apiRet
= RegQueryValueExW(key
, securityProvidersW
, NULL
, &type
,
547 (PBYTE
)securityPkgNames
, &size
);
548 if (apiRet
== ERROR_SUCCESS
&& type
== REG_SZ
)
552 for (ptr
= securityPkgNames
;
553 ptr
< (PWSTR
)((PBYTE
)securityPkgNames
+ size
); )
557 for (comma
= ptr
; *comma
&& *comma
!= ','; comma
++)
561 for (; *ptr
&& isspace(*ptr
) && ptr
< securityPkgNames
+ size
;
565 _tryLoadProvider(ptr
);
566 ptr
+= lstrlenW(ptr
) + 1;
573 SecurePackage
*SECUR32_findPackageW(PWSTR packageName
)
575 SecurePackage
*ret
= NULL
;
576 BOOL matched
= FALSE
;
578 if (packageTable
&& packageName
)
580 LIST_FOR_EACH_ENTRY(ret
, &packageTable
->table
, SecurePackage
, entry
)
582 matched
= !lstrcmpiW(ret
->infoW
.Name
, packageName
);
590 if (ret
->provider
&& !ret
->provider
->loaded
)
592 ret
->provider
->lib
= LoadLibraryW(ret
->provider
->moduleName
);
593 if (ret
->provider
->lib
)
595 INIT_SECURITY_INTERFACE_W pInitSecurityInterfaceW
=
596 (INIT_SECURITY_INTERFACE_W
)GetProcAddress(ret
->provider
->lib
,
597 SECURITY_ENTRYPOINT_ANSIW
);
598 INIT_SECURITY_INTERFACE_A pInitSecurityInterfaceA
=
599 (INIT_SECURITY_INTERFACE_A
)GetProcAddress(ret
->provider
->lib
,
600 SECURITY_ENTRYPOINT_ANSIA
);
601 PSecurityFunctionTableA fnTableA
= NULL
;
602 PSecurityFunctionTableW fnTableW
= NULL
;
604 if (pInitSecurityInterfaceA
)
605 fnTableA
= pInitSecurityInterfaceA();
606 if (pInitSecurityInterfaceW
)
607 fnTableW
= pInitSecurityInterfaceW();
608 _makeFnTableA(&ret
->provider
->fnTableA
, fnTableA
, fnTableW
);
609 _makeFnTableW(&ret
->provider
->fnTableW
, fnTableA
, fnTableW
);
610 ret
->provider
->loaded
= TRUE
;
619 SecurePackage
*SECUR32_findPackageA(PSTR packageName
)
623 if (packageTable
&& packageName
)
625 UNICODE_STRING package
;
627 RtlCreateUnicodeStringFromAsciiz(&package
, packageName
);
628 ret
= SECUR32_findPackageW(package
.Buffer
);
629 RtlFreeUnicodeString(&package
);
636 static void SECUR32_freeProviders(void)
638 SecurePackage
*package
;
639 SecureProvider
*provider
;
642 EnterCriticalSection(&cs
);
646 LIST_FOR_EACH_ENTRY(package
, &packageTable
->table
, SecurePackage
, entry
)
648 SECUR32_FREE(package
->infoW
.Name
);
649 SECUR32_FREE(package
->infoW
.Comment
);
652 HeapFree(GetProcessHeap(), 0, packageTable
);
658 LIST_FOR_EACH_ENTRY(provider
, &providerTable
->table
, SecureProvider
, entry
)
660 if (provider
->moduleName
)
661 SECUR32_FREE(provider
->moduleName
);
663 FreeLibrary(provider
->lib
);
666 HeapFree(GetProcessHeap(), 0, providerTable
);
667 providerTable
= NULL
;
670 LeaveCriticalSection(&cs
);
671 DeleteCriticalSection(&cs
);
674 /***********************************************************************
675 * FreeContextBuffer (SECUR32.@)
677 * Doh--if pv was allocated by a crypto package, this may not be correct.
678 * The sample ssp seems to use LocalAlloc/LocalFee, but there doesn't seem to
679 * be any guarantee, nor is there an alloc function in secur32.
681 SECURITY_STATUS WINAPI
FreeContextBuffer(PVOID pv
)
685 /* as it turns out, SECURITY_STATUSes are actually HRESULTS */
688 if (SECUR32_FREE(pv
) == NULL
)
691 ret
= HRESULT_FROM_WIN32(GetLastError());
694 ret
= HRESULT_FROM_WIN32(ERROR_INVALID_PARAMETER
);
698 /***********************************************************************
699 * EnumerateSecurityPackagesW (SECUR32.@)
701 SECURITY_STATUS WINAPI
EnumerateSecurityPackagesW(PULONG pcPackages
,
702 PSecPkgInfoW
*ppPackageInfo
)
704 SECURITY_STATUS ret
= SEC_E_OK
;
706 /* windows just crashes if pcPackages or ppPackageInfo is NULL, so will I */
708 EnterCriticalSection(&cs
);
711 SecurePackage
*package
;
714 bytesNeeded
= packageTable
->numPackages
* sizeof(SecPkgInfoW
);
715 LIST_FOR_EACH_ENTRY(package
, &packageTable
->table
, SecurePackage
, entry
)
717 if (package
->infoW
.Name
)
718 bytesNeeded
+= (lstrlenW(package
->infoW
.Name
) + 1) * sizeof(WCHAR
);
719 if (package
->infoW
.Comment
)
720 bytesNeeded
+= (lstrlenW(package
->infoW
.Comment
) + 1) * sizeof(WCHAR
);
724 *ppPackageInfo
= (PSecPkgInfoW
)SECUR32_ALLOC(bytesNeeded
);
730 *pcPackages
= packageTable
->numPackages
;
731 nextString
= (PWSTR
)((PBYTE
)*ppPackageInfo
+
732 packageTable
->numPackages
* sizeof(SecPkgInfoW
));
733 LIST_FOR_EACH_ENTRY(package
, &packageTable
->table
, SecurePackage
, entry
)
735 PSecPkgInfoW pkgInfo
= *ppPackageInfo
+ i
++;
737 memcpy(pkgInfo
, &package
->infoW
, sizeof(SecPkgInfoW
));
738 if (package
->infoW
.Name
)
740 pkgInfo
->Name
= nextString
;
741 lstrcpyW(nextString
, package
->infoW
.Name
);
742 nextString
+= lstrlenW(nextString
) + 1;
745 pkgInfo
->Name
= NULL
;
746 if (package
->infoW
.Comment
)
748 pkgInfo
->Comment
= nextString
;
749 lstrcpyW(nextString
, package
->infoW
.Comment
);
750 nextString
+= lstrlenW(nextString
) + 1;
753 pkgInfo
->Comment
= NULL
;
757 ret
= SEC_E_INSUFFICIENT_MEMORY
;
760 LeaveCriticalSection(&cs
);
764 /* Converts info (which is assumed to be an array of cPackages SecPkgInfoW
765 * structures) into an array of SecPkgInfoA structures, which it returns.
767 static PSecPkgInfoA
thunk_PSecPkgInfoWToA(ULONG cPackages
,
768 const PSecPkgInfoW info
)
774 size_t bytesNeeded
= cPackages
* sizeof(SecPkgInfoA
);
777 for (i
= 0; i
< cPackages
; i
++)
780 bytesNeeded
+= WideCharToMultiByte(CP_ACP
, 0, info
[i
].Name
,
781 -1, NULL
, 0, NULL
, NULL
);
783 bytesNeeded
+= WideCharToMultiByte(CP_ACP
, 0, info
[i
].Comment
,
784 -1, NULL
, 0, NULL
, NULL
);
786 ret
= (PSecPkgInfoA
)SECUR32_ALLOC(bytesNeeded
);
791 nextString
= (PSTR
)((PBYTE
)ret
+ cPackages
* sizeof(SecPkgInfoA
));
792 for (i
= 0; i
< cPackages
; i
++)
794 PSecPkgInfoA pkgInfo
= ret
+ i
;
797 memcpy(pkgInfo
, &info
[i
], sizeof(SecPkgInfoA
));
800 pkgInfo
->Name
= nextString
;
801 /* just repeat back to WideCharToMultiByte how many bytes
802 * it requires, since we asked it earlier
804 bytes
= WideCharToMultiByte(CP_ACP
, 0, info
[i
].Name
, -1,
805 NULL
, 0, NULL
, NULL
);
806 WideCharToMultiByte(CP_ACP
, 0, info
[i
].Name
, -1,
807 pkgInfo
->Name
, bytes
, NULL
, NULL
);
808 nextString
+= lstrlenA(nextString
) + 1;
811 pkgInfo
->Name
= NULL
;
814 pkgInfo
->Comment
= nextString
;
815 /* just repeat back to WideCharToMultiByte how many bytes
816 * it requires, since we asked it earlier
818 bytes
= WideCharToMultiByte(CP_ACP
, 0, info
[i
].Comment
, -1,
819 NULL
, 0, NULL
, NULL
);
820 WideCharToMultiByte(CP_ACP
, 0, info
[i
].Comment
, -1,
821 pkgInfo
->Comment
, bytes
, NULL
, NULL
);
822 nextString
+= lstrlenA(nextString
) + 1;
825 pkgInfo
->Comment
= NULL
;
834 /***********************************************************************
835 * EnumerateSecurityPackagesA (SECUR32.@)
837 SECURITY_STATUS WINAPI
EnumerateSecurityPackagesA(PULONG pcPackages
,
838 PSecPkgInfoA
*ppPackageInfo
)
843 ret
= EnumerateSecurityPackagesW(pcPackages
, &info
);
844 if (ret
== SEC_E_OK
&& *pcPackages
&& info
)
846 *ppPackageInfo
= thunk_PSecPkgInfoWToA(*pcPackages
, info
);
847 if (*pcPackages
&& !*ppPackageInfo
)
850 ret
= SEC_E_INSUFFICIENT_MEMORY
;
852 FreeContextBuffer(info
);
857 /***********************************************************************
858 * GetComputerObjectNameA (SECUR32.@)
860 BOOLEAN WINAPI
GetComputerObjectNameA(
861 EXTENDED_NAME_FORMAT NameFormat
, LPSTR lpNameBuffer
, PULONG nSize
)
863 FIXME("%d %p %p\n", NameFormat
, lpNameBuffer
, nSize
);
867 /***********************************************************************
868 * GetComputerObjectNameW (SECUR32.@)
870 BOOLEAN WINAPI
GetComputerObjectNameW(
871 EXTENDED_NAME_FORMAT NameFormat
, LPWSTR lpNameBuffer
, PULONG nSize
)
873 FIXME("%d %p %p\n", NameFormat
, lpNameBuffer
, nSize
);
877 BOOLEAN WINAPI
GetUserNameExA(
878 EXTENDED_NAME_FORMAT NameFormat
, LPSTR lpNameBuffer
, PULONG nSize
)
880 FIXME("%d %p %p\n", NameFormat
, lpNameBuffer
, nSize
);
884 BOOLEAN WINAPI
GetUserNameExW(
885 EXTENDED_NAME_FORMAT NameFormat
, LPWSTR lpNameBuffer
, PULONG nSize
)
887 FIXME("%d %p %p\n", NameFormat
, lpNameBuffer
, nSize
);
891 NTSTATUS WINAPI
LsaCallAuthenticationPackage(
892 HANDLE LsaHandle
, ULONG AuthenticationPackage
, PVOID ProtocolSubmitBuffer
,
893 ULONG SubmitBufferLength
, PVOID
* ProtocolReturnBuffer
, PULONG ReturnBufferLength
,
894 PNTSTATUS ProtocolStatus
)
896 FIXME("%p %ld %p %ld %p %p %p\n", LsaHandle
, AuthenticationPackage
,
897 ProtocolSubmitBuffer
, SubmitBufferLength
, ProtocolReturnBuffer
,
898 ReturnBufferLength
, ProtocolStatus
);
902 NTSTATUS WINAPI
LsaConnectUntrusted(PHANDLE LsaHandle
)
904 FIXME("%p\n", LsaHandle
);
908 NTSTATUS WINAPI
LsaDeregisterLogonProcess(HANDLE LsaHandle
)
910 FIXME("%p\n", LsaHandle
);
914 BOOLEAN WINAPI
TranslateNameA(
915 LPCSTR lpAccountName
, EXTENDED_NAME_FORMAT AccountNameFormat
,
916 EXTENDED_NAME_FORMAT DesiredNameFormat
, LPSTR lpTranslatedName
,
919 FIXME("%p %d %d %p %p\n", lpAccountName
, AccountNameFormat
,
920 DesiredNameFormat
, lpTranslatedName
, nSize
);
924 BOOLEAN WINAPI
TranslateNameW(
925 LPCWSTR lpAccountName
, EXTENDED_NAME_FORMAT AccountNameFormat
,
926 EXTENDED_NAME_FORMAT DesiredNameFormat
, LPWSTR lpTranslatedName
,
929 FIXME("%p %d %d %p %p\n", lpAccountName
, AccountNameFormat
,
930 DesiredNameFormat
, lpTranslatedName
, nSize
);
934 /***********************************************************************
935 * DllMain (SECUR32.0)
937 BOOL WINAPI
DllMain(HINSTANCE hinstDLL
, DWORD fdwReason
, LPVOID lpvReserved
)
939 if (fdwReason
== DLL_PROCESS_ATTACH
)
941 DisableThreadLibraryCalls(hinstDLL
);
942 SECUR32_initializeProviders();
944 else if (fdwReason
== DLL_PROCESS_DETACH
)
946 SECUR32_freeProviders();