Authors: James Hawkins <truiken@gmail.com>, Juan Lang <juan_lang@yahoo.com>

Use a standard wine list for packages and providers.
This commit is contained in:
Alexandre Julliard 2005-08-30 08:55:20 +00:00
parent 28022e8022
commit 63a643e50f
3 changed files with 97 additions and 168 deletions

View file

@ -30,6 +30,7 @@
#include "ntsecapi.h"
#include "thunks.h"
#include "wine/list.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(secur32);
@ -42,34 +43,20 @@ typedef struct _SecurePackageTable
{
DWORD numPackages;
DWORD numAllocated;
SecurePackage table[1];
struct list table;
} SecurePackageTable;
typedef struct _SecureProviderTable
{
DWORD numProviders;
DWORD numAllocated;
SecureProvider table[1];
struct list table;
} SecureProviderTable;
/**
* Prototypes
*/
/* Makes sure table has space for at least howBig entries. If table is NULL,
* returns a newly allocated table. Otherwise returns the address of the
* modified table, which may not be the same was when called.
*/
static SecurePackageTable *_resizePackageTable(SecurePackageTable *table,
DWORD howBig);
/* Makes sure table has space for at least howBig entries. If table is NULL,
* returns a newly allocated table. Otherwise returns the address of the
* modified table, which may not be the same was when called.
*/
static SecureProviderTable *_resizeProviderTable(SecureProviderTable *table,
DWORD howBig);
/* Tries to load moduleName as a provider. If successful, enumerates what
* packages it can and adds them to the package and provider tables. Resizes
* tables as necessary.
@ -173,89 +160,6 @@ PSecurityFunctionTableW WINAPI InitSecurityInterfaceW(void)
return &securityFunctionTableW;
}
/* Allocates or resizes table to have space for at least howBig packages.
* Uses Heap functions, because needs to be able to reallocate.
*/
static SecurePackageTable *_resizePackageTable(SecurePackageTable *table,
DWORD howBig)
{
SecurePackageTable *ret;
EnterCriticalSection(&cs);
if (table)
{
if (table->numAllocated < howBig)
{
ret = HeapReAlloc(GetProcessHeap(), 0, table,
sizeof(SecurePackageTable) + (howBig - 1) * sizeof(SecurePackage));
if (ret)
{
ret->numAllocated = howBig;
table = ret;
}
}
else
ret = table;
}
else
{
DWORD numAllocated = (howBig > 1 ? howBig : 1);
ret = HeapAlloc(GetProcessHeap(), 0,
sizeof(SecurePackageTable) +
(numAllocated - 1) * sizeof(SecurePackage));
if (ret)
{
ret->numAllocated = numAllocated;
ret->numPackages = 0;
}
}
LeaveCriticalSection(&cs);
return ret;
}
/* Allocates or resizes table to have space for at least howBig providers.
* Uses Heap functions, because needs to be able to reallocate.
*/
static SecureProviderTable *_resizeProviderTable(SecureProviderTable *table,
DWORD howBig)
{
SecureProviderTable *ret;
EnterCriticalSection(&cs);
if (table)
{
if (table->numAllocated < howBig)
{
ret = HeapReAlloc(GetProcessHeap(), 0, table,
sizeof(SecureProviderTable) +
(howBig - 1) * sizeof(SecureProvider));
if (ret)
{
ret->numAllocated = howBig;
table = ret;
}
}
else
ret = table;
}
else
{
DWORD numAllocated = (howBig > 1 ? howBig : 1);
ret = HeapAlloc(GetProcessHeap(), 0,
sizeof(SecureProviderTable) +
(numAllocated - 1) * sizeof(SecureProvider));
if (ret)
{
ret->numAllocated = numAllocated;
ret->numProviders = 0;
}
}
LeaveCriticalSection(&cs);
return ret;
}
PWSTR SECUR32_strdupW(PCWSTR str)
{
PWSTR ret;
@ -487,27 +391,36 @@ SecureProvider *SECUR32_addProvider(PSecurityFunctionTableA fnTableA,
SecureProvider *ret;
EnterCriticalSection(&cs);
providerTable = _resizeProviderTable(providerTable,
providerTable ? providerTable->numProviders + 1 : 1);
if (providerTable)
if (!providerTable)
{
ret = &providerTable->table[providerTable->numProviders++];
ret->lib = NULL;
if (fnTableA || fnTableW)
{
ret->moduleName = NULL;
_makeFnTableA(&ret->fnTableA, fnTableA, fnTableW);
_makeFnTableW(&ret->fnTableW, fnTableA, fnTableW);
ret->loaded = TRUE;
}
else
{
ret->moduleName = SECUR32_strdupW(moduleName);
ret->loaded = FALSE;
}
providerTable = HeapAlloc(GetProcessHeap(), 0, sizeof(SecureProviderTable));
if (!providerTable)
return NULL;
list_init(&providerTable->table);
}
ret = HeapAlloc(GetProcessHeap(), 0, sizeof(SecureProvider));
if (!ret)
return NULL;
list_add_tail(&providerTable->table, &ret->entry);
ret->lib = NULL;
if (fnTableA || fnTableW)
{
ret->moduleName = NULL;
_makeFnTableA(&ret->fnTableA, fnTableA, fnTableW);
_makeFnTableW(&ret->fnTableW, fnTableA, fnTableW);
ret->loaded = TRUE;
}
else
ret = NULL;
{
ret->moduleName = SECUR32_strdupW(moduleName);
ret->loaded = FALSE;
}
LeaveCriticalSection(&cs);
return ret;
}
@ -515,28 +428,38 @@ SecureProvider *SECUR32_addProvider(PSecurityFunctionTableA fnTableA,
void SECUR32_addPackages(SecureProvider *provider, ULONG toAdd,
const SecPkgInfoA *infoA, const SecPkgInfoW *infoW)
{
ULONG i;
assert(provider);
assert(infoA || infoW);
EnterCriticalSection(&cs);
packageTable = _resizePackageTable(packageTable,
packageTable ? packageTable->numPackages + toAdd : toAdd);
if (packageTable)
if (!packageTable)
{
ULONG i;
packageTable = HeapAlloc(GetProcessHeap(), 0, sizeof(SecurePackageTable));
if (!packageTable)
return;
for (i = 0; i < toAdd; i++)
{
SecurePackage *package =
&packageTable->table[packageTable->numPackages + i];
package->provider = provider;
_copyPackageInfo(&package->infoW,
infoA ? &infoA[i] : NULL,
infoW ? &infoW[i] : NULL);
}
packageTable->numPackages += toAdd;
packageTable->numPackages = 0;
list_init(&packageTable->table);
}
for (i = 0; i < toAdd; i++)
{
SecurePackage *package = HeapAlloc(GetProcessHeap(), 0, sizeof(SecurePackage));
if (!package)
continue;
list_add_tail(&packageTable->table, &package->entry);
package->provider = provider;
_copyPackageInfo(&package->infoW,
infoA ? &infoA[i] : NULL,
infoW ? &infoW[i] : NULL);
}
packageTable->numPackages += toAdd;
LeaveCriticalSection(&cs);
}
@ -653,11 +576,12 @@ SecurePackage *SECUR32_findPackageW(PWSTR packageName)
if (packageTable && packageName)
{
DWORD i;
for (i = 0, ret = NULL; !ret && i < packageTable->numPackages; i++)
if (!lstrcmpiW(packageTable->table[i].infoW.Name, packageName))
ret = &packageTable->table[i];
LIST_FOR_EACH_ENTRY(ret, &packageTable->table, SecurePackage, entry)
{
if (!lstrcmpiW(ret->infoW.Name, packageName))
break;
}
if (ret && ret->provider && !ret->provider->loaded)
{
ret->provider->lib = LoadLibraryW(ret->provider->moduleName);
@ -706,32 +630,38 @@ SecurePackage *SECUR32_findPackageA(PSTR packageName)
static void SECUR32_freeProviders(void)
{
DWORD i;
SecurePackage *package;
SecureProvider *provider;
TRACE("\n");
EnterCriticalSection(&cs);
if (packageTable)
{
for (i = 0; i < packageTable->numPackages; i++)
LIST_FOR_EACH_ENTRY(package, &packageTable->table, SecurePackage, entry)
{
SECUR32_FREE(packageTable->table[i].infoW.Name);
SECUR32_FREE(packageTable->table[i].infoW.Comment);
SECUR32_FREE(package->infoW.Name);
SECUR32_FREE(package->infoW.Comment);
}
HeapFree(GetProcessHeap(), 0, packageTable);
packageTable = NULL;
}
if (providerTable)
{
for (i = 0; i < providerTable->numProviders; i++)
LIST_FOR_EACH_ENTRY(provider, &providerTable->table, SecureProvider, entry)
{
if (providerTable->table[i].moduleName)
SECUR32_FREE(providerTable->table[i].moduleName);
if (providerTable->table[i].lib)
FreeLibrary(providerTable->table[i].lib);
if (provider->moduleName)
SECUR32_FREE(provider->moduleName);
if (provider->lib)
FreeLibrary(provider->lib);
}
HeapFree(GetProcessHeap(), 0, providerTable);
providerTable = NULL;
}
LeaveCriticalSection(&cs);
DeleteCriticalSection(&cs);
}
@ -773,50 +703,45 @@ SECURITY_STATUS WINAPI EnumerateSecurityPackagesW(PULONG pcPackages,
EnterCriticalSection(&cs);
if (packageTable)
{
ULONG i;
SecurePackage *package;
size_t bytesNeeded;
bytesNeeded = packageTable->numPackages * sizeof(SecPkgInfoW);
for (i = 0; i < packageTable->numPackages; i++)
LIST_FOR_EACH_ENTRY(package, &packageTable->table, SecurePackage, entry)
{
if (packageTable->table[i].infoW.Name)
bytesNeeded +=
(lstrlenW(packageTable->table[i].infoW.Name) + 1) *
sizeof(WCHAR);
if (packageTable->table[i].infoW.Comment)
bytesNeeded +=
(lstrlenW(packageTable->table[i].infoW.Comment) + 1) *
sizeof(WCHAR);
if (package->infoW.Name)
bytesNeeded += (lstrlenW(package->infoW.Name) + 1) * sizeof(WCHAR);
if (package->infoW.Comment)
bytesNeeded += (lstrlenW(package->infoW.Comment) + 1) * sizeof(WCHAR);
}
if (bytesNeeded)
{
*ppPackageInfo = (PSecPkgInfoW)SECUR32_ALLOC(bytesNeeded);
if (*ppPackageInfo)
{
ULONG i = 0;
PWSTR nextString;
*pcPackages = packageTable->numPackages;
nextString = (PWSTR)((PBYTE)*ppPackageInfo +
packageTable->numPackages * sizeof(SecPkgInfoW));
for (i = 0; i < packageTable->numPackages; i++)
LIST_FOR_EACH_ENTRY(package, &packageTable->table, SecurePackage, entry)
{
PSecPkgInfoW pkgInfo = *ppPackageInfo + i;
PSecPkgInfoW pkgInfo = *ppPackageInfo + i++;
memcpy(pkgInfo, &packageTable->table[i].infoW,
sizeof(SecPkgInfoW));
if (packageTable->table[i].infoW.Name)
memcpy(pkgInfo, &package->infoW, sizeof(SecPkgInfoW));
if (package->infoW.Name)
{
pkgInfo->Name = nextString;
lstrcpyW(nextString, packageTable->table[i].infoW.Name);
lstrcpyW(nextString, package->infoW.Name);
nextString += lstrlenW(nextString) + 1;
}
else
pkgInfo->Name = NULL;
if (packageTable->table[i].infoW.Comment)
if (package->infoW.Comment)
{
pkgInfo->Comment = nextString;
lstrcpyW(nextString,
packageTable->table[i].infoW.Comment);
lstrcpyW(nextString, package->infoW.Comment);
nextString += lstrlenW(nextString) + 1;
}
else

View file

@ -21,6 +21,8 @@
#ifndef __SECUR32_PRIV_H__
#define __SECUR32_PRIV_H__
#include "wine/list.h"
/* Memory allocation functions for memory accessible by callers of secur32.
* There is no REALLOC, because LocalReAlloc can only work if used in
* conjunction with LMEM_MOVEABLE and LocalLock, but callers aren't using
@ -34,6 +36,7 @@
typedef struct _SecureProvider
{
struct list entry;
BOOL loaded;
PWSTR moduleName;
HMODULE lib;
@ -43,6 +46,7 @@ typedef struct _SecureProvider
typedef struct _SecurePackage
{
struct list entry;
SecPkgInfoW infoW;
SecureProvider *provider;
} SecurePackage;

View file

@ -218,15 +218,15 @@ static void testEnumerateSecurityPackages(void)
SECURITY_STATUS sec_status;
ULONG num_packages, i;
PSecPkgInfo pkg_info = NULL;
trace("Running testEnumerateSecurityPackages\n");
sec_status = EnumerateSecurityPackages(&num_packages, &pkg_info);
ok(sec_status == SEC_E_OK,
"EnumerateSecurityPackages() should return %ld, not %ld\n",
"EnumerateSecurityPackages() should return %ld, not %08lx\n",
(LONG)SEC_E_OK, (LONG)sec_status);
ok(num_packages > 0, "Number of sec packages should be > 0 ,but is %ld\n",
num_packages);