From f99a46f3697d10d3db1d92db1e450f9be34fed55 Mon Sep 17 00:00:00 2001
From: Nakarin Khankham <garuda2550@gmail.com>
Date: Sat, 9 Mar 2019 21:40:48 +0700
Subject: [PATCH 2/5] opencl: Use function pointer instead of call the function
 directly.

Signed-off-by: Nakarin Khankham <garuda2550@gmail.com>
---
 dlls/opencl/opencl.c | 241 +++++++++++++++++++++++++++++++++++++--------------
 1 file changed, 177 insertions(+), 64 deletions(-)

diff --git a/dlls/opencl/opencl.c b/dlls/opencl/opencl.c
index 7d292c0..221cf1a 100644
--- a/dlls/opencl/opencl.c
+++ b/dlls/opencl/opencl.c
@@ -371,7 +371,8 @@ cl_int WINAPI wine_clGetPlatformIDs(cl_uint num_entries, cl_platform_id *platfor
 {
     cl_int ret;
     TRACE("(%d, %p, %p)\n", num_entries, platforms, num_platforms);
-    ret = clGetPlatformIDs(num_entries, platforms, num_platforms);
+    if (!pclGetPlatformIDs) return CL_INVALID_VALUE;
+    ret = pclGetPlatformIDs(num_entries, platforms, num_platforms);
     TRACE("(%d, %p, %p)=%d\n", num_entries, platforms, num_platforms, ret);
     return ret;
 }
@@ -382,6 +383,8 @@ cl_int WINAPI wine_clGetPlatformInfo(cl_platform_id platform, cl_platform_info p
     cl_int ret;
     TRACE("(%p, 0x%x, %ld, %p, %p)\n", platform, param_name, param_value_size, param_value, param_value_size_ret);
 
+    if (!pclGetPlatformInfo) return CL_INVALID_VALUE;
+
     /* Hide all extensions.
      * TODO: Add individual extension support as needed.
      */
@@ -404,7 +407,7 @@ cl_int WINAPI wine_clGetPlatformInfo(cl_platform_id platform, cl_platform_info p
     }
     else
     {
-        ret = clGetPlatformInfo(platform, param_name, param_value_size, param_value, param_value_size_ret);
+        ret = pclGetPlatformInfo(platform, param_name, param_value_size, param_value, param_value_size_ret);
     }
 
     TRACE("(%p, 0x%x, %ld, %p, %p)=%d\n", platform, param_name, param_value_size, param_value, param_value_size_ret, ret);
@@ -420,7 +423,8 @@ cl_int WINAPI wine_clGetDeviceIDs(cl_platform_id platform, cl_device_type device
 {
     cl_int ret;
     TRACE("(%p, 0x%lx, %d, %p, %p)\n", platform, (long unsigned int)device_type, num_entries, devices, num_devices);
-    ret = clGetDeviceIDs(platform, device_type, num_entries, devices, num_devices);
+    if (!pclGetDeviceIDs) return CL_INVALID_VALUE;
+    ret = pclGetDeviceIDs(platform, device_type, num_entries, devices, num_devices);
     TRACE("(%p, 0x%lx, %d, %p, %p)=%d\n", platform, (long unsigned int)device_type, num_entries, devices, num_devices, ret);
     return ret;
 }
@@ -431,6 +435,8 @@ cl_int WINAPI wine_clGetDeviceInfo(cl_device_id device, cl_device_info param_nam
     cl_int ret;
     TRACE("(%p, 0x%x, %ld, %p, %p)\n",device, param_name, param_value_size, param_value, param_value_size_ret);
 
+    if (!pclGetDeviceInfo) return CL_INVALID_VALUE;
+
     /* Hide all extensions.
      * TODO: Add individual extension support as needed.
      */
@@ -453,7 +459,7 @@ cl_int WINAPI wine_clGetDeviceInfo(cl_device_id device, cl_device_info param_nam
     }
     else
     {
-        ret = clGetDeviceInfo(device, param_name, param_value_size, param_value, param_value_size_ret);
+        ret = pclGetDeviceInfo(device, param_name, param_value_size, param_value, param_value_size_ret);
     }
 
     /* Filter out the CL_EXEC_NATIVE_KERNEL flag */
@@ -493,6 +499,11 @@ cl_context WINAPI wine_clCreateContext(const cl_context_properties * properties,
     cl_context ret;
     CONTEXT_CALLBACK *ccb;
     TRACE("(%p, %d, %p, %p, %p, %p)\n", properties, num_devices, devices, pfn_notify, user_data, errcode_ret);
+    if (!pclCreateContext)
+    {
+        *errcode_ret = CL_INVALID_VALUE;
+        return NULL;
+    }
     /* FIXME: The CONTEXT_CALLBACK structure is currently leaked.
      * Pointers to callback redirectors should be remembered and free()d when the context is destroyed.
      * The problem is determining when a context is being destroyed. clReleaseContext only decrements
@@ -502,7 +513,7 @@ cl_context WINAPI wine_clCreateContext(const cl_context_properties * properties,
     ccb = HeapAlloc(GetProcessHeap(), 0, sizeof(CONTEXT_CALLBACK));
     ccb->pfn_notify = pfn_notify;
     ccb->user_data = user_data;
-    ret = clCreateContext(properties, num_devices, devices, context_fn_notify, ccb, errcode_ret);
+    ret = pclCreateContext(properties, num_devices, devices, context_fn_notify, ccb, errcode_ret);
     TRACE("(%p, %d, %p, %p, %p, %p (%d)))=%p\n", properties, num_devices, devices, &pfn_notify, user_data, errcode_ret, errcode_ret ? *errcode_ret : 0, ret);
     return ret;
 }
@@ -514,6 +525,11 @@ cl_context WINAPI wine_clCreateContextFromType(const cl_context_properties * pro
     cl_context ret;
     CONTEXT_CALLBACK *ccb;
     TRACE("(%p, 0x%lx, %p, %p, %p)\n", properties, (long unsigned int)device_type, pfn_notify, user_data, errcode_ret);
+    if (!pclCreateContextFromType)
+    {
+        *errcode_ret = CL_INVALID_VALUE;
+        return NULL;
+    }
     /* FIXME: The CONTEXT_CALLBACK structure is currently leaked.
      * Pointers to callback redirectors should be remembered and free()d when the context is destroyed.
      * The problem is determining when a context is being destroyed. clReleaseContext only decrements
@@ -523,7 +539,7 @@ cl_context WINAPI wine_clCreateContextFromType(const cl_context_properties * pro
     ccb = HeapAlloc(GetProcessHeap(), 0, sizeof(CONTEXT_CALLBACK));
     ccb->pfn_notify = pfn_notify;
     ccb->user_data = user_data;
-    ret = clCreateContextFromType(properties, device_type, context_fn_notify, ccb, errcode_ret);
+    ret = pclCreateContextFromType(properties, device_type, context_fn_notify, ccb, errcode_ret);
     TRACE("(%p, 0x%lx, %p, %p, %p (%d)))=%p\n", properties, (long unsigned int)device_type, pfn_notify, user_data, errcode_ret, errcode_ret ? *errcode_ret : 0, ret);
     return ret;
 }
@@ -532,7 +548,8 @@ cl_int WINAPI wine_clRetainContext(cl_context context)
 {
     cl_int ret;
     TRACE("(%p)\n", context);
-    ret = clRetainContext(context);
+    if (!pclRetainContext) return CL_INVALID_VALUE;
+    ret = pclRetainContext(context);
     TRACE("(%p)=%d\n", context, ret);
     return ret;
 }
@@ -541,7 +558,8 @@ cl_int WINAPI wine_clReleaseContext(cl_context context)
 {
     cl_int ret;
     TRACE("(%p)\n", context);
-    ret = clReleaseContext(context);
+    if (!pclReleaseContext) return CL_INVALID_VALUE;
+    ret = pclReleaseContext(context);
     TRACE("(%p)=%d\n", context, ret);
     return ret;
 }
@@ -551,7 +569,8 @@ cl_int WINAPI wine_clGetContextInfo(cl_context context, cl_context_info param_na
 {
     cl_int ret;
     TRACE("(%p, 0x%x, %ld, %p, %p)\n", context, param_name, param_value_size, param_value, param_value_size_ret);
-    ret = clGetContextInfo(context, param_name, param_value_size, param_value, param_value_size_ret);
+    if (!pclGetContextInfo) return CL_INVALID_VALUE;
+    ret = pclGetContextInfo(context, param_name, param_value_size, param_value, param_value_size_ret);
     TRACE("(%p, 0x%x, %ld, %p, %p)=%d\n", context, param_name, param_value_size, param_value, param_value_size_ret, ret);
     return ret;
 }
@@ -565,7 +584,12 @@ cl_command_queue WINAPI wine_clCreateCommandQueue(cl_context context, cl_device_
 {
     cl_command_queue ret;
     TRACE("(%p, %p, 0x%lx, %p)\n", context, device, (long unsigned int)properties, errcode_ret);
-    ret = clCreateCommandQueue(context, device, properties, errcode_ret);
+    if (!pclCreateCommandQueue)
+    {
+        *errcode_ret = CL_INVALID_VALUE;
+        return NULL;
+    }
+    ret = pclCreateCommandQueue(context, device, properties, errcode_ret);
     TRACE("(%p, %p, 0x%lx, %p)=%p\n", context, device, (long unsigned int)properties, errcode_ret, ret);
     return ret;
 }
@@ -574,7 +598,8 @@ cl_int WINAPI wine_clRetainCommandQueue(cl_command_queue command_queue)
 {
     cl_int ret;
     TRACE("(%p)\n", command_queue);
-    ret = clRetainCommandQueue(command_queue);
+    if (!pclRetainCommandQueue) return CL_INVALID_VALUE;
+    ret = pclRetainCommandQueue(command_queue);
     TRACE("(%p)=%d\n", command_queue, ret);
     return ret;
 }
@@ -583,7 +608,8 @@ cl_int WINAPI wine_clReleaseCommandQueue(cl_command_queue command_queue)
 {
     cl_int ret;
     TRACE("(%p)\n", command_queue);
-    ret = clReleaseCommandQueue(command_queue);
+    if (!pclReleaseCommandQueue) return CL_INVALID_VALUE;
+    ret = pclReleaseCommandQueue(command_queue);
     TRACE("(%p)=%d\n", command_queue, ret);
     return ret;
 }
@@ -593,7 +619,8 @@ cl_int WINAPI wine_clGetCommandQueueInfo(cl_command_queue command_queue, cl_comm
 {
     cl_int ret;
     TRACE("%p, %d, %ld, %p, %p\n", command_queue, param_name, param_value_size, param_value, param_value_size_ret);
-    ret = clGetCommandQueueInfo(command_queue, param_name, param_value_size, param_value, param_value_size_ret);
+    if (!pclGetCommandQueueInfo) return CL_INVALID_VALUE;
+    ret = pclGetCommandQueueInfo(command_queue, param_name, param_value_size, param_value, param_value_size_ret);
     return ret;
 }
 
@@ -612,7 +639,12 @@ cl_mem WINAPI wine_clCreateBuffer(cl_context context, cl_mem_flags flags, size_t
 {
     cl_mem ret;
     TRACE("\n");
-    ret = clCreateBuffer(context, flags, size, host_ptr, errcode_ret);
+    if (!pclCreateBuffer)
+    {
+        *errcode_ret = CL_INVALID_VALUE;
+        return NULL;
+    }
+    ret = pclCreateBuffer(context, flags, size, host_ptr, errcode_ret);
     return ret;
 }
 
@@ -621,7 +653,12 @@ cl_mem WINAPI wine_clCreateImage2D(cl_context context, cl_mem_flags flags, cl_im
 {
     cl_mem ret;
     TRACE("\n");
-    ret = clCreateImage2D(context, flags, image_format, image_width, image_height, image_row_pitch, host_ptr, errcode_ret);
+    if (!pclCreateImage2D)
+    {
+        *errcode_ret = CL_INVALID_VALUE;
+        return NULL;
+    }
+    ret = pclCreateImage2D(context, flags, image_format, image_width, image_height, image_row_pitch, host_ptr, errcode_ret);
     return ret;
 }
 
@@ -631,7 +668,12 @@ cl_mem WINAPI wine_clCreateImage3D(cl_context context, cl_mem_flags flags, cl_im
 {
     cl_mem ret;
     TRACE("\n");
-    ret = clCreateImage3D(context, flags, image_format, image_width, image_height, image_depth, image_row_pitch, image_slice_pitch, host_ptr, errcode_ret);
+    if (!pclCreateImage3D)
+    {
+        *errcode_ret = CL_INVALID_VALUE;
+        return NULL;
+    }
+    ret = pclCreateImage3D(context, flags, image_format, image_width, image_height, image_depth, image_row_pitch, image_slice_pitch, host_ptr, errcode_ret);
     return ret;
 }
 
@@ -639,7 +681,8 @@ cl_int WINAPI wine_clRetainMemObject(cl_mem memobj)
 {
     cl_int ret;
     TRACE("(%p)\n", memobj);
-    ret = clRetainMemObject(memobj);
+    if (!pclRetainMemObject) return CL_INVALID_VALUE;
+    ret = pclRetainMemObject(memobj);
     TRACE("(%p)=%d\n", memobj, ret);
     return ret;
 }
@@ -648,7 +691,8 @@ cl_int WINAPI wine_clReleaseMemObject(cl_mem memobj)
 {
     cl_int ret;
     TRACE("(%p)\n", memobj);
-    ret = clReleaseMemObject(memobj);
+    if (!pclReleaseMemObject) return CL_INVALID_VALUE;
+    ret = pclReleaseMemObject(memobj);
     TRACE("(%p)=%d\n", memobj, ret);
     return ret;
 }
@@ -658,7 +702,8 @@ cl_int WINAPI wine_clGetSupportedImageFormats(cl_context context, cl_mem_flags f
 {
     cl_int ret;
     TRACE("\n");
-    ret = clGetSupportedImageFormats(context, flags, image_type, num_entries, image_formats, num_image_formats);
+    if (!pclGetSupportedImageFormats) return CL_INVALID_VALUE;
+    ret = pclGetSupportedImageFormats(context, flags, image_type, num_entries, image_formats, num_image_formats);
     return ret;
 }
 
@@ -666,7 +711,8 @@ cl_int WINAPI wine_clGetMemObjectInfo(cl_mem memobj, cl_mem_info param_name, siz
 {
     cl_int ret;
     TRACE("\n");
-    ret = clGetMemObjectInfo(memobj, param_name, param_value_size, param_value, param_value_size_ret);
+    if (!pclGetMemObjectInfo) return CL_INVALID_VALUE;
+    ret = pclGetMemObjectInfo(memobj, param_name, param_value_size, param_value, param_value_size_ret);
     return ret;
 }
 
@@ -674,7 +720,8 @@ cl_int WINAPI wine_clGetImageInfo(cl_mem image, cl_image_info param_name, size_t
 {
     cl_int ret;
     TRACE("\n");
-    ret = clGetImageInfo(image, param_name, param_value_size, param_value, param_value_size_ret);
+    if (!pclGetImageInfo) return CL_INVALID_VALUE;
+    ret = pclGetImageInfo(image, param_name, param_value_size, param_value, param_value_size_ret);
     return ret;
 }
 
@@ -687,7 +734,12 @@ cl_sampler WINAPI wine_clCreateSampler(cl_context context, cl_bool normalized_co
 {
     cl_sampler ret;
     TRACE("\n");
-    ret = clCreateSampler(context, normalized_coords, addressing_mode, filter_mode, errcode_ret);
+    if (!pclCreateSampler)
+    {
+        *errcode_ret = CL_INVALID_VALUE;
+        return NULL;
+    }
+    ret = pclCreateSampler(context, normalized_coords, addressing_mode, filter_mode, errcode_ret);
     return ret;
 }
 
@@ -695,7 +747,8 @@ cl_int WINAPI wine_clRetainSampler(cl_sampler sampler)
 {
     cl_int ret;
     TRACE("\n");
-    ret = clRetainSampler(sampler);
+    if (!pclRetainSampler) return CL_INVALID_VALUE;
+    ret = pclRetainSampler(sampler);
     return ret;
 }
 
@@ -703,7 +756,8 @@ cl_int WINAPI wine_clReleaseSampler(cl_sampler sampler)
 {
     cl_int ret;
     TRACE("\n");
-    ret = clReleaseSampler(sampler);
+    if (!pclReleaseSampler) return CL_INVALID_VALUE;
+    ret = pclReleaseSampler(sampler);
     return ret;
 }
 
@@ -712,7 +766,8 @@ cl_int WINAPI wine_clGetSamplerInfo(cl_sampler sampler, cl_sampler_info param_na
 {
     cl_int ret;
     TRACE("\n");
-    ret = clGetSamplerInfo(sampler, param_name, param_value_size, param_value, param_value_size_ret);
+    if (!pclGetSamplerInfo) return CL_INVALID_VALUE;
+    ret = pclGetSamplerInfo(sampler, param_name, param_value_size, param_value, param_value_size_ret);
     return ret;
 }
 
@@ -725,7 +780,12 @@ cl_program WINAPI wine_clCreateProgramWithSource(cl_context context, cl_uint cou
 {
     cl_program ret;
     TRACE("\n");
-    ret = clCreateProgramWithSource(context, count, strings, lengths, errcode_ret);
+    if (!pclCreateProgramWithSource)
+    {
+        *errcode_ret = CL_INVALID_VALUE;
+        return NULL;
+    }
+    ret = pclCreateProgramWithSource(context, count, strings, lengths, errcode_ret);
     return ret;
 }
 
@@ -735,7 +795,12 @@ cl_program WINAPI wine_clCreateProgramWithBinary(cl_context context, cl_uint num
 {
     cl_program ret;
     TRACE("\n");
-    ret = clCreateProgramWithBinary(context, num_devices, device_list, lengths, binaries, binary_status, errcode_ret);
+    if (!pclCreateProgramWithBinary)
+    {
+        *errcode_ret = CL_INVALID_VALUE;
+        return NULL;
+    }
+    ret = pclCreateProgramWithBinary(context, num_devices, device_list, lengths, binaries, binary_status, errcode_ret);
     return ret;
 }
 
@@ -743,7 +808,8 @@ cl_int WINAPI wine_clRetainProgram(cl_program program)
 {
     cl_int ret;
     TRACE("\n");
-    ret = clRetainProgram(program);
+    if (!pclRetainProgram) return CL_INVALID_PROGRAM;
+    ret = pclRetainProgram(program);
     return ret;
 }
 
@@ -751,7 +817,8 @@ cl_int WINAPI wine_clReleaseProgram(cl_program program)
 {
     cl_int ret;
     TRACE("\n");
-    ret = clReleaseProgram(program);
+    if (!pclReleaseProgram) return CL_INVALID_PROGRAM;
+    ret = pclReleaseProgram(program);
     return ret;
 }
 
@@ -777,6 +844,7 @@ cl_int WINAPI wine_clBuildProgram(cl_program program, cl_uint num_devices, const
 {
     cl_int ret;
     TRACE("\n");
+    if (!pclBuildProgram) return CL_INVALID_VALUE;
     if(pfn_notify)
     {
         /* When pfn_notify is provided, clBuildProgram is asynchronous */
@@ -784,12 +852,12 @@ cl_int WINAPI wine_clBuildProgram(cl_program program, cl_uint num_devices, const
         pcb = HeapAlloc(GetProcessHeap(), 0, sizeof(PROGRAM_CALLBACK));
         pcb->pfn_notify = pfn_notify;
         pcb->user_data = user_data;
-        ret = clBuildProgram(program, num_devices, device_list, options, program_fn_notify, pcb);
+        ret = pclBuildProgram(program, num_devices, device_list, options, program_fn_notify, pcb);
     }
     else
     {
         /* When pfn_notify is NULL, clBuildProgram is synchronous */
-        ret = clBuildProgram(program, num_devices, device_list, options, NULL, user_data);
+        ret = pclBuildProgram(program, num_devices, device_list, options, NULL, user_data);
     }
     return ret;
 }
@@ -798,7 +866,8 @@ cl_int WINAPI wine_clUnloadCompiler(void)
 {
     cl_int ret;
     TRACE("()\n");
-    ret = clUnloadCompiler();
+    if (!pclUnloadCompiler) return CL_SUCCESS;
+    ret = pclUnloadCompiler();
     TRACE("()=%d\n", ret);
     return ret;
 }
@@ -808,7 +877,8 @@ cl_int WINAPI wine_clGetProgramInfo(cl_program program, cl_program_info param_na
 {
     cl_int ret;
     TRACE("\n");
-    ret = clGetProgramInfo(program, param_name, param_value_size, param_value, param_value_size_ret);
+    if (!pclGetProgramInfo) return CL_INVALID_VALUE;
+    ret = pclGetProgramInfo(program, param_name, param_value_size, param_value, param_value_size_ret);
     return ret;
 }
 
@@ -818,7 +888,8 @@ cl_int WINAPI wine_clGetProgramBuildInfo(cl_program program, cl_device_id device
 {
     cl_int ret;
     TRACE("\n");
-    ret = clGetProgramBuildInfo(program, device, param_name, param_value_size, param_value, param_value_size_ret);
+    if (!pclGetProgramBuildInfo) return CL_INVALID_VALUE;
+    ret = pclGetProgramBuildInfo(program, device, param_name, param_value_size, param_value, param_value_size_ret);
     return ret;
 }
 
@@ -830,7 +901,12 @@ cl_kernel WINAPI wine_clCreateKernel(cl_program program, char * kernel_name, cl_
 {
     cl_kernel ret;
     TRACE("\n");
-    ret = clCreateKernel(program, kernel_name, errcode_ret);
+    if (!pclCreateKernel)
+    {
+        *errcode_ret = CL_INVALID_VALUE;
+        return NULL;
+    }
+    ret = pclCreateKernel(program, kernel_name, errcode_ret);
     return ret;
 }
 
@@ -839,7 +915,8 @@ cl_int WINAPI wine_clCreateKernelsInProgram(cl_program program, cl_uint num_kern
 {
     cl_int ret;
     TRACE("\n");
-    ret = clCreateKernelsInProgram(program, num_kernels, kernels, num_kernels_ret);
+    if (!pclCreateKernelsInProgram) return CL_INVALID_VALUE;
+    ret = pclCreateKernelsInProgram(program, num_kernels, kernels, num_kernels_ret);
     return ret;
 }
 
@@ -847,7 +924,8 @@ cl_int WINAPI wine_clRetainKernel(cl_kernel kernel)
 {
     cl_int ret;
     TRACE("\n");
-    ret = clRetainKernel(kernel);
+    if (!pclRetainKernel) return CL_INVALID_KERNEL;
+    ret = pclRetainKernel(kernel);
     return ret;
 }
 
@@ -855,7 +933,8 @@ cl_int WINAPI wine_clReleaseKernel(cl_kernel kernel)
 {
     cl_int ret;
     TRACE("\n");
-    ret = clReleaseKernel(kernel);
+    if (!pclReleaseKernel) return CL_INVALID_KERNEL;
+    ret = pclReleaseKernel(kernel);
     return ret;
 }
 
@@ -863,7 +942,8 @@ cl_int WINAPI wine_clSetKernelArg(cl_kernel kernel, cl_uint arg_index, size_t ar
 {
     cl_int ret;
     TRACE("\n");
-    ret = clSetKernelArg(kernel, arg_index, arg_size, arg_value);
+    if (!pclSetKernelArg) return CL_INVALID_KERNEL;
+    ret = pclSetKernelArg(kernel, arg_index, arg_size, arg_value);
     return ret;
 }
 
@@ -872,7 +952,8 @@ cl_int WINAPI wine_clGetKernelInfo(cl_kernel kernel, cl_kernel_info param_name,
 {
     cl_int ret;
     TRACE("\n");
-    ret = clGetKernelInfo(kernel, param_name, param_value_size, param_value, param_value_size_ret);
+    if (!pclGetKernelInfo) return CL_INVALID_VALUE;
+    ret = pclGetKernelInfo(kernel, param_name, param_value_size, param_value, param_value_size_ret);
     return ret;
 }
 
@@ -882,7 +963,8 @@ cl_int WINAPI wine_clGetKernelWorkGroupInfo(cl_kernel kernel, cl_device_id devic
 {
     cl_int ret;
     TRACE("\n");
-    ret = clGetKernelWorkGroupInfo(kernel, device, param_name, param_value_size, param_value, param_value_size_ret);
+    if (!pclGetKernelWorkGroupInfo) return CL_INVALID_VALUE;
+    ret = pclGetKernelWorkGroupInfo(kernel, device, param_name, param_value_size, param_value, param_value_size_ret);
     return ret;
 }
 
@@ -894,7 +976,8 @@ cl_int WINAPI wine_clWaitForEvents(cl_uint num_events, cl_event * event_list)
 {
     cl_int ret;
     TRACE("\n");
-    ret = clWaitForEvents(num_events, event_list);
+    if (!pclWaitForEvents) return CL_INVALID_EVENT;
+    ret = pclWaitForEvents(num_events, event_list);
     return ret;
 }
 
@@ -903,7 +986,8 @@ cl_int WINAPI wine_clGetEventInfo(cl_event event, cl_event_info param_name, size
 {
     cl_int ret;
     TRACE("\n");
-    ret = clGetEventInfo(event, param_name, param_value_size, param_value, param_value_size_ret);
+    if (!pclGetEventInfo) return CL_INVALID_EVENT;
+    ret = pclGetEventInfo(event, param_name, param_value_size, param_value, param_value_size_ret);
     return ret;
 }
 
@@ -911,7 +995,8 @@ cl_int WINAPI wine_clRetainEvent(cl_event event)
 {
     cl_int ret;
     TRACE("\n");
-    ret = clRetainEvent(event);
+    if (!pclRetainEvent) return CL_INVALID_EVENT;
+    ret = pclRetainEvent(event);
     return ret;
 }
 
@@ -919,7 +1004,8 @@ cl_int WINAPI wine_clReleaseEvent(cl_event event)
 {
     cl_int ret;
     TRACE("\n");
-    ret = clReleaseEvent(event);
+    if (!pclReleaseEvent) return CL_INVALID_EVENT;
+    ret = pclReleaseEvent(event);
     return ret;
 }
 
@@ -932,7 +1018,8 @@ cl_int WINAPI wine_clGetEventProfilingInfo(cl_event event, cl_profiling_info par
 {
     cl_int ret;
     TRACE("\n");
-    ret = clGetEventProfilingInfo(event, param_name, param_value_size, param_value, param_value_size_ret);
+    if (!pclGetEventProfilingInfo) return CL_INVALID_EVENT;
+    ret = pclGetEventProfilingInfo(event, param_name, param_value_size, param_value, param_value_size_ret);
     return ret;
 }
 
@@ -944,7 +1031,8 @@ cl_int WINAPI wine_clFlush(cl_command_queue command_queue)
 {
     cl_int ret;
     TRACE("(%p)\n", command_queue);
-    ret = clFlush(command_queue);
+    if (!pclFlush) return CL_INVALID_COMMAND_QUEUE;
+    ret = pclFlush(command_queue);
     TRACE("(%p)=%d\n", command_queue, ret);
     return ret;
 }
@@ -953,7 +1041,8 @@ cl_int WINAPI wine_clFinish(cl_command_queue command_queue)
 {
     cl_int ret;
     TRACE("(%p)\n", command_queue);
-    ret = clFinish(command_queue);
+    if (!pclFinish) return CL_INVALID_COMMAND_QUEUE;
+    ret = pclFinish(command_queue);
     TRACE("(%p)=%d\n", command_queue, ret);
     return ret;
 }
@@ -968,7 +1057,8 @@ cl_int WINAPI wine_clEnqueueReadBuffer(cl_command_queue command_queue, cl_mem bu
 {
     cl_int ret;
     TRACE("\n");
-    ret = clEnqueueReadBuffer(command_queue, buffer, blocking_read, offset, cb, ptr, num_events_in_wait_list, event_wait_list, event);
+    if (!pclEnqueueReadBuffer) return CL_INVALID_VALUE;
+    ret = pclEnqueueReadBuffer(command_queue, buffer, blocking_read, offset, cb, ptr, num_events_in_wait_list, event_wait_list, event);
     return ret;
 }
 
@@ -978,7 +1068,8 @@ cl_int WINAPI wine_clEnqueueWriteBuffer(cl_command_queue command_queue, cl_mem b
 {
     cl_int ret;
     TRACE("\n");
-    ret = clEnqueueWriteBuffer(command_queue, buffer, blocking_write, offset, cb, ptr, num_events_in_wait_list, event_wait_list, event);
+    if (!pclEnqueueWriteBuffer) return CL_INVALID_VALUE;
+    ret = pclEnqueueWriteBuffer(command_queue, buffer, blocking_write, offset, cb, ptr, num_events_in_wait_list, event_wait_list, event);
     return ret;
 }
 
@@ -988,7 +1079,8 @@ cl_int WINAPI wine_clEnqueueCopyBuffer(cl_command_queue command_queue, cl_mem sr
 {
     cl_int ret;
     TRACE("\n");
-    ret = clEnqueueCopyBuffer(command_queue, src_buffer, dst_buffer, src_offset, dst_offset, cb, num_events_in_wait_list, event_wait_list, event);
+    if (!pclEnqueueCopyBuffer) return CL_INVALID_VALUE;
+    ret = pclEnqueueCopyBuffer(command_queue, src_buffer, dst_buffer, src_offset, dst_offset, cb, num_events_in_wait_list, event_wait_list, event);
     return ret;
 }
 
@@ -1000,7 +1092,8 @@ cl_int WINAPI wine_clEnqueueReadImage(cl_command_queue command_queue, cl_mem ima
     cl_int ret;
     TRACE("(%p, %p, %d, %p, %p, %ld, %ld, %p, %d, %p, %p)\n", command_queue, image, blocking_read,
           origin, region, row_pitch, slice_pitch, ptr, num_events_in_wait_list, event_wait_list, event);
-    ret = clEnqueueReadImage(command_queue, image, blocking_read, origin, region, row_pitch, slice_pitch, ptr, num_events_in_wait_list, event_wait_list, event);
+    if (!pclEnqueueReadImage) return CL_INVALID_VALUE;
+    ret = pclEnqueueReadImage(command_queue, image, blocking_read, origin, region, row_pitch, slice_pitch, ptr, num_events_in_wait_list, event_wait_list, event);
     TRACE("(%p, %p, %d, %p, %p, %ld, %ld, %p, %d, %p, %p)=%d\n", command_queue, image, blocking_read,
           origin, region, row_pitch, slice_pitch, ptr, num_events_in_wait_list, event_wait_list, event, ret);
     return ret;
@@ -1013,7 +1106,8 @@ cl_int WINAPI wine_clEnqueueWriteImage(cl_command_queue command_queue, cl_mem im
 {
     cl_int ret;
     TRACE("\n");
-    ret = clEnqueueWriteImage(command_queue, image, blocking_write, origin, region, input_row_pitch, input_slice_pitch, ptr, num_events_in_wait_list, event_wait_list, event);
+    if (!pclEnqueueWriteImage) return CL_INVALID_VALUE;
+    ret = pclEnqueueWriteImage(command_queue, image, blocking_write, origin, region, input_row_pitch, input_slice_pitch, ptr, num_events_in_wait_list, event_wait_list, event);
     return ret;
 }
 
@@ -1023,7 +1117,8 @@ cl_int WINAPI wine_clEnqueueCopyImage(cl_command_queue command_queue, cl_mem src
 {
     cl_int ret;
     TRACE("\n");
-    ret = clEnqueueCopyImage(command_queue, src_image, dst_image, src_origin, dst_origin, region, num_events_in_wait_list, event_wait_list, event);
+    if (!pclEnqueueCopyImage) return CL_INVALID_VALUE;
+    ret = pclEnqueueCopyImage(command_queue, src_image, dst_image, src_origin, dst_origin, region, num_events_in_wait_list, event_wait_list, event);
     return ret;
 }
 
@@ -1033,7 +1128,8 @@ cl_int WINAPI wine_clEnqueueCopyImageToBuffer(cl_command_queue command_queue, cl
 {
     cl_int ret;
     TRACE("\n");
-    ret = clEnqueueCopyImageToBuffer(command_queue, src_image, dst_buffer, src_origin, region, dst_offset, num_events_in_wait_list, event_wait_list, event);
+    if (!pclEnqueueCopyImageToBuffer) return CL_INVALID_VALUE;
+    ret = pclEnqueueCopyImageToBuffer(command_queue, src_image, dst_buffer, src_origin, region, dst_offset, num_events_in_wait_list, event_wait_list, event);
     return ret;
 }
 
@@ -1043,7 +1139,8 @@ cl_int WINAPI wine_clEnqueueCopyBufferToImage(cl_command_queue command_queue, cl
 {
     cl_int ret;
     TRACE("\n");
-    ret = clEnqueueCopyBufferToImage(command_queue, src_buffer, dst_image, src_offset, dst_origin, region, num_events_in_wait_list, event_wait_list, event);
+    if (!pclEnqueueCopyBufferToImage) return CL_INVALID_VALUE;
+    ret = pclEnqueueCopyBufferToImage(command_queue, src_buffer, dst_image, src_offset, dst_origin, region, num_events_in_wait_list, event_wait_list, event);
     return ret;
 }
 
@@ -1053,7 +1150,12 @@ void * WINAPI wine_clEnqueueMapBuffer(cl_command_queue command_queue, cl_mem buf
 {
     void * ret;
     TRACE("\n");
-    ret = clEnqueueMapBuffer(command_queue, buffer, blocking_map, map_flags, offset, cb, num_events_in_wait_list, event_wait_list, event, errcode_ret);
+    if (!pclEnqueueMapBuffer)
+    {
+        *errcode_ret = CL_INVALID_VALUE;
+        return NULL;
+    }
+    ret = pclEnqueueMapBuffer(command_queue, buffer, blocking_map, map_flags, offset, cb, num_events_in_wait_list, event_wait_list, event, errcode_ret);
     return ret;
 }
 
@@ -1064,7 +1166,12 @@ void * WINAPI wine_clEnqueueMapImage(cl_command_queue command_queue, cl_mem imag
 {
     void * ret;
     TRACE("\n");
-    ret = clEnqueueMapImage(command_queue, image, blocking_map, map_flags, origin, region, image_row_pitch, image_slice_pitch, num_events_in_wait_list, event_wait_list, event, errcode_ret);
+    if (!pclEnqueueMapImage)
+    {
+        *errcode_ret = CL_INVALID_VALUE;
+        return NULL;
+    }
+    ret = pclEnqueueMapImage(command_queue, image, blocking_map, map_flags, origin, region, image_row_pitch, image_slice_pitch, num_events_in_wait_list, event_wait_list, event, errcode_ret);
     return ret;
 }
 
@@ -1073,7 +1180,8 @@ cl_int WINAPI wine_clEnqueueUnmapMemObject(cl_command_queue command_queue, cl_me
 {
     cl_int ret;
     TRACE("\n");
-    ret = clEnqueueUnmapMemObject(command_queue, memobj, mapped_ptr, num_events_in_wait_list, event_wait_list, event);
+    if (!pclEnqueueUnmapMemObject) return CL_INVALID_VALUE;
+    ret = pclEnqueueUnmapMemObject(command_queue, memobj, mapped_ptr, num_events_in_wait_list, event_wait_list, event);
     return ret;
 }
 
@@ -1083,7 +1191,8 @@ cl_int WINAPI wine_clEnqueueNDRangeKernel(cl_command_queue command_queue, cl_ker
 {
     cl_int ret;
     TRACE("\n");
-    ret = clEnqueueNDRangeKernel(command_queue, kernel, work_dim, global_work_offset, global_work_size, local_work_size, num_events_in_wait_list, event_wait_list, event);
+    if (!pclEnqueueNDRangeKernel) return CL_INVALID_VALUE;
+    ret = pclEnqueueNDRangeKernel(command_queue, kernel, work_dim, global_work_offset, global_work_size, local_work_size, num_events_in_wait_list, event_wait_list, event);
     return ret;
 }
 
@@ -1092,7 +1201,8 @@ cl_int WINAPI wine_clEnqueueTask(cl_command_queue command_queue, cl_kernel kerne
 {
     cl_int ret;
     TRACE("\n");
-    ret = clEnqueueTask(command_queue, kernel, num_events_in_wait_list, event_wait_list, event);
+    if (!pclEnqueueTask) return CL_INVALID_VALUE;
+    ret = pclEnqueueTask(command_queue, kernel, num_events_in_wait_list, event_wait_list, event);
     return ret;
 }
 
@@ -1121,7 +1231,8 @@ cl_int WINAPI wine_clEnqueueMarker(cl_command_queue command_queue, cl_event * ev
 {
     cl_int ret;
     TRACE("\n");
-    ret = clEnqueueMarker(command_queue, event);
+    if (!pclEnqueueMarker) return CL_INVALID_VALUE;
+    ret = pclEnqueueMarker(command_queue, event);
     return ret;
 }
 
@@ -1129,7 +1240,8 @@ cl_int WINAPI wine_clEnqueueWaitForEvents(cl_command_queue command_queue, cl_uin
 {
     cl_int ret;
     TRACE("\n");
-    ret = clEnqueueWaitForEvents(command_queue, num_events, event_list);
+    if (!pclEnqueueWaitForEvents) return CL_INVALID_VALUE;
+    ret = pclEnqueueWaitForEvents(command_queue, num_events, event_list);
     return ret;
 }
 
@@ -1137,7 +1249,8 @@ cl_int WINAPI wine_clEnqueueBarrier(cl_command_queue command_queue)
 {
     cl_int ret;
     TRACE("\n");
-    ret = clEnqueueBarrier(command_queue);
+    if (!pclEnqueueBarrier) return CL_INVALID_VALUE;
+    ret = pclEnqueueBarrier(command_queue);
     return ret;
 }
 
-- 
1.9.1

