set svn:eol-style to native
[reactos.git] / reactos / lib / msi / handle.c
index 281a16c..9ecfd05 100644 (file)
-/*\r
- * Implementation of the Microsoft Installer (msi.dll)\r
- *\r
- * Copyright 2002-2004 Mike McCormack for CodeWeavers\r
- *\r
- * This library is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU Lesser General Public\r
- * License as published by the Free Software Foundation; either\r
- * version 2.1 of the License, or (at your option) any later version.\r
- *\r
- * This library is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
- * Lesser General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU Lesser General Public\r
- * License along with this library; if not, write to the Free Software\r
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
- */\r
-\r
-#include <stdarg.h>\r
-\r
-#include "windef.h"\r
-#include "winbase.h"\r
-#include "winreg.h"\r
-#include "shlwapi.h"\r
-#include "wine/debug.h"\r
-#include "msi.h"\r
-#include "msiquery.h"\r
-#include "msipriv.h"\r
-\r
-WINE_DEFAULT_DEBUG_CHANNEL(msi);\r
-\r
-static CRITICAL_SECTION MSI_handle_cs;\r
-static CRITICAL_SECTION_DEBUG MSI_handle_cs_debug =\r
-{\r
-    0, 0, &MSI_handle_cs,\r
-    { &MSI_handle_cs_debug.ProcessLocksList, \r
-      &MSI_handle_cs_debug.ProcessLocksList },\r
-      0, 0, { 0, (DWORD)(__FILE__ ": MSI_handle_cs") }\r
-};\r
-static CRITICAL_SECTION MSI_handle_cs = { &MSI_handle_cs_debug, -1, 0, 0, 0, 0 };\r
-\r
-static CRITICAL_SECTION MSI_object_cs;\r
-static CRITICAL_SECTION_DEBUG MSI_object_cs_debug =\r
-{\r
-    0, 0, &MSI_object_cs,\r
-    { &MSI_object_cs_debug.ProcessLocksList, \r
-      &MSI_object_cs_debug.ProcessLocksList },\r
-      0, 0, { 0, (DWORD)(__FILE__ ": MSI_object_cs") }\r
-};\r
-static CRITICAL_SECTION MSI_object_cs = { &MSI_object_cs_debug, -1, 0, 0, 0, 0 };\r
-\r
-typedef struct msi_handle_info_t\r
-{\r
-    MSIOBJECTHDR *obj;\r
-    DWORD dwThreadId;\r
-} msi_handle_info;\r
-\r
-static msi_handle_info msihandletable[MSIMAXHANDLES];\r
-\r
-MSIHANDLE alloc_msihandle( MSIOBJECTHDR *obj )\r
-{\r
-    MSIHANDLE ret = 0;\r
-    UINT i;\r
-\r
-    EnterCriticalSection( &MSI_handle_cs );\r
-\r
-    /* find a slot */\r
-    for(i=0; i<MSIMAXHANDLES; i++)\r
-        if( !msihandletable[i].obj )\r
-            break;\r
-    if( (i>=MSIMAXHANDLES) || msihandletable[i].obj )\r
-        goto out;\r
-\r
-    msiobj_addref( obj );\r
-    msihandletable[i].obj = obj;\r
-    msihandletable[i].dwThreadId = GetCurrentThreadId();\r
-    ret = (MSIHANDLE) (i+1);\r
-out:\r
-    TRACE("%p -> %ld\n", obj, ret );\r
-\r
-    LeaveCriticalSection( &MSI_handle_cs );\r
-    return ret;\r
-}\r
-\r
-void *msihandle2msiinfo(MSIHANDLE handle, UINT type)\r
-{\r
-    MSIOBJECTHDR *ret = NULL;\r
-\r
-    EnterCriticalSection( &MSI_handle_cs );\r
-    handle--;\r
-    if( handle<0 )\r
-        goto out;\r
-    if( handle>=MSIMAXHANDLES )\r
-        goto out;\r
-    if( !msihandletable[handle].obj )\r
-        goto out;\r
-    if( msihandletable[handle].obj->magic != MSIHANDLE_MAGIC )\r
-        goto out;\r
-    if( type && (msihandletable[handle].obj->type != type) )\r
-        goto out;\r
-    ret = msihandletable[handle].obj;\r
-    msiobj_addref( ret );\r
-    \r
-out:\r
-    LeaveCriticalSection( &MSI_handle_cs );\r
-\r
-    return (void*) ret;\r
-}\r
-\r
-MSIHANDLE msiobj_findhandle( MSIOBJECTHDR *hdr )\r
-{\r
-    MSIHANDLE ret = 0;\r
-    UINT i;\r
-\r
-    TRACE("%p\n", hdr);\r
-\r
-    EnterCriticalSection( &MSI_handle_cs );\r
-    for(i=0; (i<MSIMAXHANDLES) && !ret; i++)\r
-        if( msihandletable[i].obj == hdr )\r
-            ret = i+1;\r
-    LeaveCriticalSection( &MSI_handle_cs );\r
-\r
-    TRACE("%p -> %ld\n", hdr, ret);\r
-\r
-    msiobj_addref( hdr );\r
-    return ret;\r
-}\r
-\r
-void *alloc_msiobject(UINT type, UINT size, msihandledestructor destroy )\r
-{\r
-    MSIOBJECTHDR *info;\r
-\r
-    info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, size );\r
-    if( info )\r
-    {\r
-        info->magic = MSIHANDLE_MAGIC;\r
-        info->type = type;\r
-        info->refcount = 1;\r
-        info->destructor = destroy;\r
-    }\r
-\r
-    return info;\r
-}\r
-\r
-void msiobj_addref( MSIOBJECTHDR *info )\r
-{\r
-    TRACE("%p\n", info);\r
-\r
-    if( !info )\r
-        return;\r
-\r
-    if( info->magic != MSIHANDLE_MAGIC )\r
-    {\r
-        ERR("Invalid handle!\n");\r
-        return;\r
-    }\r
-\r
-    InterlockedIncrement(&info->refcount);\r
-}\r
-\r
-void msiobj_lock( MSIOBJECTHDR *info )\r
-{\r
-    EnterCriticalSection( &MSI_object_cs );\r
-}\r
-\r
-void msiobj_unlock( MSIOBJECTHDR *info )\r
-{\r
-    LeaveCriticalSection( &MSI_object_cs );\r
-}\r
-\r
-int msiobj_release( MSIOBJECTHDR *info )\r
-{\r
-    int ret;\r
-\r
-    TRACE("%p\n",info);\r
-\r
-    if( !info )\r
-        return -1;\r
-\r
-    if( info->magic != MSIHANDLE_MAGIC )\r
-    {\r
-        ERR("Invalid handle!\n");\r
-        return -1;\r
-    }\r
-\r
-    ret = InterlockedDecrement( &info->refcount );\r
-    if( ret==0 )\r
-    {\r
-        if( info->destructor )\r
-            info->destructor( info );\r
-        HeapFree( GetProcessHeap(), 0, info );\r
-        TRACE("object %p destroyed\n", info);\r
-    }\r
-\r
-    return ret;\r
-}\r
-\r
-/***********************************************************\r
- *   MsiCloseHandle   [MSI.@]\r
- */\r
-UINT WINAPI MsiCloseHandle(MSIHANDLE handle)\r
-{\r
-    MSIOBJECTHDR *info;\r
-    UINT ret = ERROR_INVALID_HANDLE;\r
-\r
-    TRACE("%lx\n",handle);\r
-\r
-    EnterCriticalSection( &MSI_handle_cs );\r
-\r
-    info = msihandle2msiinfo(handle, 0);\r
-    if( !info )\r
-        goto out;\r
-\r
-    if( info->magic != MSIHANDLE_MAGIC )\r
-    {\r
-        ERR("Invalid handle!\n");\r
-        goto out;\r
-    }\r
-\r
-    msiobj_release( info );\r
-    msihandletable[handle-1].obj = NULL;\r
-    ret = ERROR_SUCCESS;\r
-\r
-    TRACE("handle %lx Destroyed\n", handle);\r
-out:\r
-    LeaveCriticalSection( &MSI_handle_cs );\r
-    if( info )\r
-        msiobj_release( info );\r
-\r
-    return ret;\r
-}\r
-\r
-/***********************************************************\r
- *   MsiCloseAllHandles   [MSI.@]\r
- *\r
- *  Closes all handles owned by the current thread\r
- *\r
- *  RETURNS:\r
- *   The number of handles closed\r
- */\r
-UINT WINAPI MsiCloseAllHandles(void)\r
-{\r
-    UINT i, n=0;\r
-\r
-    TRACE("\n");\r
-\r
-    for(i=0; i<MSIMAXHANDLES; i++)\r
-    {\r
-        if(msihandletable[i].dwThreadId == GetCurrentThreadId())\r
-        {\r
-            MsiCloseHandle( i+1 );\r
-            n++;\r
-        }\r
-    }\r
-\r
-    return n;\r
-}\r
+/*
+ * Implementation of the Microsoft Installer (msi.dll)
+ *
+ * Copyright 2002-2004 Mike McCormack for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <stdarg.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "winreg.h"
+#include "shlwapi.h"
+#include "wine/debug.h"
+#include "msi.h"
+#include "msiquery.h"
+#include "msipriv.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(msi);
+
+static CRITICAL_SECTION MSI_handle_cs;
+static CRITICAL_SECTION_DEBUG MSI_handle_cs_debug =
+{
+    0, 0, &MSI_handle_cs,
+    { &MSI_handle_cs_debug.ProcessLocksList, 
+      &MSI_handle_cs_debug.ProcessLocksList },
+      0, 0, { 0, (DWORD)(__FILE__ ": MSI_handle_cs") }
+};
+static CRITICAL_SECTION MSI_handle_cs = { &MSI_handle_cs_debug, -1, 0, 0, 0, 0 };
+
+static CRITICAL_SECTION MSI_object_cs;
+static CRITICAL_SECTION_DEBUG MSI_object_cs_debug =
+{
+    0, 0, &MSI_object_cs,
+    { &MSI_object_cs_debug.ProcessLocksList, 
+      &MSI_object_cs_debug.ProcessLocksList },
+      0, 0, { 0, (DWORD)(__FILE__ ": MSI_object_cs") }
+};
+static CRITICAL_SECTION MSI_object_cs = { &MSI_object_cs_debug, -1, 0, 0, 0, 0 };
+
+typedef struct msi_handle_info_t
+{
+    MSIOBJECTHDR *obj;
+    DWORD dwThreadId;
+} msi_handle_info;
+
+static msi_handle_info msihandletable[MSIMAXHANDLES];
+
+MSIHANDLE alloc_msihandle( MSIOBJECTHDR *obj )
+{
+    MSIHANDLE ret = 0;
+    UINT i;
+
+    EnterCriticalSection( &MSI_handle_cs );
+
+    /* find a slot */
+    for(i=0; i<MSIMAXHANDLES; i++)
+        if( !msihandletable[i].obj )
+            break;
+    if( (i>=MSIMAXHANDLES) || msihandletable[i].obj )
+        goto out;
+
+    msiobj_addref( obj );
+    msihandletable[i].obj = obj;
+    msihandletable[i].dwThreadId = GetCurrentThreadId();
+    ret = (MSIHANDLE) (i+1);
+out:
+    TRACE("%p -> %ld\n", obj, ret );
+
+    LeaveCriticalSection( &MSI_handle_cs );
+    return ret;
+}
+
+void *msihandle2msiinfo(MSIHANDLE handle, UINT type)
+{
+    MSIOBJECTHDR *ret = NULL;
+
+    EnterCriticalSection( &MSI_handle_cs );
+    handle--;
+    if( handle<0 )
+        goto out;
+    if( handle>=MSIMAXHANDLES )
+        goto out;
+    if( !msihandletable[handle].obj )
+        goto out;
+    if( msihandletable[handle].obj->magic != MSIHANDLE_MAGIC )
+        goto out;
+    if( type && (msihandletable[handle].obj->type != type) )
+        goto out;
+    ret = msihandletable[handle].obj;
+    msiobj_addref( ret );
+    
+out:
+    LeaveCriticalSection( &MSI_handle_cs );
+
+    return (void*) ret;
+}
+
+MSIHANDLE msiobj_findhandle( MSIOBJECTHDR *hdr )
+{
+    MSIHANDLE ret = 0;
+    UINT i;
+
+    TRACE("%p\n", hdr);
+
+    EnterCriticalSection( &MSI_handle_cs );
+    for(i=0; (i<MSIMAXHANDLES) && !ret; i++)
+        if( msihandletable[i].obj == hdr )
+            ret = i+1;
+    LeaveCriticalSection( &MSI_handle_cs );
+
+    TRACE("%p -> %ld\n", hdr, ret);
+
+    msiobj_addref( hdr );
+    return ret;
+}
+
+void *alloc_msiobject(UINT type, UINT size, msihandledestructor destroy )
+{
+    MSIOBJECTHDR *info;
+
+    info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, size );
+    if( info )
+    {
+        info->magic = MSIHANDLE_MAGIC;
+        info->type = type;
+        info->refcount = 1;
+        info->destructor = destroy;
+    }
+
+    return info;
+}
+
+void msiobj_addref( MSIOBJECTHDR *info )
+{
+    TRACE("%p\n", info);
+
+    if( !info )
+        return;
+
+    if( info->magic != MSIHANDLE_MAGIC )
+    {
+        ERR("Invalid handle!\n");
+        return;
+    }
+
+    InterlockedIncrement(&info->refcount);
+}
+
+void msiobj_lock( MSIOBJECTHDR *info )
+{
+    EnterCriticalSection( &MSI_object_cs );
+}
+
+void msiobj_unlock( MSIOBJECTHDR *info )
+{
+    LeaveCriticalSection( &MSI_object_cs );
+}
+
+int msiobj_release( MSIOBJECTHDR *info )
+{
+    int ret;
+
+    TRACE("%p\n",info);
+
+    if( !info )
+        return -1;
+
+    if( info->magic != MSIHANDLE_MAGIC )
+    {
+        ERR("Invalid handle!\n");
+        return -1;
+    }
+
+    ret = InterlockedDecrement( &info->refcount );
+    if( ret==0 )
+    {
+        if( info->destructor )
+            info->destructor( info );
+        HeapFree( GetProcessHeap(), 0, info );
+        TRACE("object %p destroyed\n", info);
+    }
+
+    return ret;
+}
+
+/***********************************************************
+ *   MsiCloseHandle   [MSI.@]
+ */
+UINT WINAPI MsiCloseHandle(MSIHANDLE handle)
+{
+    MSIOBJECTHDR *info;
+    UINT ret = ERROR_INVALID_HANDLE;
+
+    TRACE("%lx\n",handle);
+
+    EnterCriticalSection( &MSI_handle_cs );
+
+    info = msihandle2msiinfo(handle, 0);
+    if( !info )
+        goto out;
+
+    if( info->magic != MSIHANDLE_MAGIC )
+    {
+        ERR("Invalid handle!\n");
+        goto out;
+    }
+
+    msiobj_release( info );
+    msihandletable[handle-1].obj = NULL;
+    ret = ERROR_SUCCESS;
+
+    TRACE("handle %lx Destroyed\n", handle);
+out:
+    LeaveCriticalSection( &MSI_handle_cs );
+    if( info )
+        msiobj_release( info );
+
+    return ret;
+}
+
+/***********************************************************
+ *   MsiCloseAllHandles   [MSI.@]
+ *
+ *  Closes all handles owned by the current thread
+ *
+ *  RETURNS:
+ *   The number of handles closed
+ */
+UINT WINAPI MsiCloseAllHandles(void)
+{
+    UINT i, n=0;
+
+    TRACE("\n");
+
+    for(i=0; i<MSIMAXHANDLES; i++)
+    {
+        if(msihandletable[i].dwThreadId == GetCurrentThreadId())
+        {
+            MsiCloseHandle( i+1 );
+            n++;
+        }
+    }
+
+    return n;
+}