From: Ariel Darshan abdaandroid@gmail.com
Signed-off-by: Ariel Darshan abdaandroid@gmail.com --- dlls/ncrypt/main.c | 108 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 106 insertions(+), 2 deletions(-)
diff --git a/dlls/ncrypt/main.c b/dlls/ncrypt/main.c index c7546cce897..27313438279 100644 --- a/dlls/ncrypt/main.c +++ b/dlls/ncrypt/main.c @@ -242,8 +242,25 @@ SECURITY_STATUS WINAPI NCryptFreeBuffer(PVOID buf)
SECURITY_STATUS WINAPI NCryptFreeObject(NCRYPT_HANDLE object) { - FIXME("(0x%lx): stub\n", object); - return NTE_NOT_SUPPORTED; + /* FIXME: implement for secret and hash handles */ + struct ncrypt_base_object *obj; + + TRACE("(0x%lx)\n", object); + + obj = handle2baseObject(object); + + switch(obj->sType) + { + case NCRYPT_OBJ_TYPE_PROVIDER: + return free_provider(object); + + case NCRYPT_OBJ_TYPE_KEY: + return free_key(object); + + default: + FIXME("Object type not implemented: 0x%08x\n", obj->sType); + return NTE_NOT_SUPPORTED; + } }
SECURITY_STATUS WINAPI NCryptGetProperty(NCRYPT_HANDLE object, const WCHAR *property, PBYTE output, @@ -457,3 +474,90 @@ static NCRYPT_PROV_HANDLE ref_provider(NCRYPT_PROV_HANDLE provider)
return provider; } + +static SECURITY_STATUS free_provider(NCRYPT_HANDLE provider) +{ + struct ncrypt_provider_instance *providerInstance; + SECURITY_STATUS ret; + BOOL success; + + if (!provider) + { + return NTE_INVALID_HANDLE; + } + + providerInstance = handle2provider(provider); + + if (providerInstance->refCount) + { + providerInstance->refCount--; + } + + if (!providerInstance->refCount) + { + if (providerInstance->kspHandle) + { + ret = providerInstance->functions.FreeProvider(providerInstance->kspHandle); + if (ret != ERROR_SUCCESS) + { + ERR("FreeProvider failed\n"); + return ret; + } + providerInstance->kspHandle = 0; + } + + if (providerInstance->kspDLL) + { + success = FreeLibrary(providerInstance->kspDLL); + if (!success) + { + ERR("Failed to free dll: 0x%08x\n", GetLastError()); + return NTE_INTERNAL_ERROR; + } + providerInstance->kspDLL = NULL; + } + heap_free(providerInstance); + } + return ERROR_SUCCESS; +} + +static SECURITY_STATUS free_key(NCRYPT_HANDLE key) +{ + struct ncrypt_key_instance *keyInstance; + struct ncrypt_provider_instance *providerInstance; + SECURITY_STATUS ret; + + + if (!key) + { + return NTE_INVALID_HANDLE; + } + + keyInstance = handle2key(key); + providerInstance = handle2provider(keyInstance->provider); + + + if (keyInstance->kspHandle) + { + ret = providerInstance->functions.FreeKey(providerInstance->kspHandle, keyInstance->kspHandle); + if (ret != ERROR_SUCCESS) + { + ERR("FreeKey failed in the key storage provider\n"); + return ret; + } + keyInstance->kspHandle = 0; + } + + if (keyInstance->provider) + { + ret = free_provider(keyInstance->provider); + if (ret != ERROR_SUCCESS) + { + return ret; + } + keyInstance->provider = 0; + } + + heap_free(keyInstance); + return ERROR_SUCCESS; +}