[PATCH 04/16] ncrypt: Implement NCryptFreeObject

abdaandroid at gmail.com abdaandroid at gmail.com
Sun Oct 11 10:45:23 CDT 2020


From: Ariel Darshan <abdaandroid at gmail.com>

Signed-off-by: Ariel Darshan <abdaandroid at 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;
+}
-- 
2.28.0




More information about the wine-devel mailing list