Sync to Wine-20050524:
[reactos.git] / reactos / lib / cabinet / fci.c
index 4fd9476..88310c2 100644 (file)
@@ -2,6 +2,7 @@
  * File Compression Interface\r
  *\r
  * Copyright 2002 Patrik Stridvall\r
+ * Copyright 2005 Gerold Jens Wucherpfennig\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
@@ -26,6 +27,7 @@
 #include "winbase.h"\r
 #include "winerror.h"\r
 #include "fci.h"\r
+#include "cabinet.h"\r
 \r
 #include "wine/debug.h"\r
 \r
@@ -33,12 +35,55 @@ WINE_DEFAULT_DEBUG_CHANNEL(cabinet);
 \r
 /***********************************************************************\r
  *             FCICreate (CABINET.10)\r
+ *\r
+ * Provided with several callbacks,\r
+ * returns a handle which can be used to perform operations\r
+ * on cabinet files.\r
+ *\r
+ * PARAMS\r
+ *   perf       [IO]  A pointer to an ERF structure.  When FCICreate\r
+ *                    returns an error condition, error information may\r
+ *                    be found here as well as from GetLastError.\r
+ *   pfnfiledest [I]  A pointer to a function which is called when a file\r
+ *                    is placed. Only useful for subsequent cabinet files.\r
+ *   pfnalloc    [I]  A pointer to a function which allocates ram.  Uses\r
+ *                    the same interface as malloc.\r
+ *   pfnfree     [I]  A pointer to a function which frees ram.  Uses the\r
+ *                    same interface as free.\r
+ *   pfnopen     [I]  A pointer to a function which opens a file.  Uses\r
+ *                    the same interface as _open.\r
+ *   pfnread     [I]  A pointer to a function which reads from a file into\r
+ *                    a caller-provided buffer.  Uses the same interface\r
+ *                    as _read\r
+ *   pfnwrite    [I]  A pointer to a function which writes to a file from\r
+ *                    a caller-provided buffer.  Uses the same interface\r
+ *                    as _write.\r
+ *   pfnclose    [I]  A pointer to a function which closes a file handle.\r
+ *                    Uses the same interface as _close.\r
+ *   pfnseek     [I]  A pointer to a function which seeks in a file.\r
+ *                    Uses the same interface as _lseek.\r
+ *   pfndelete   [I]  A pointer to a function which deletes a file.\r
+ *   pfnfcigtf   [I]  A pointer to a function which gets the name of a\r
+ *                    temporary file; ignored in wine\r
+ *   pccab       [I]  A pointer to an initialized CCAB structure\r
+ *   pv          [I]  A pointer to an application-defined notification\r
+ *                    function which will be passed to other FCI functions\r
+ *                    as a parameter.\r
+ *\r
+ * RETURNS\r
+ *   On success, returns an FCI handle of type HFCI.\r
+ *   On failure, the NULL file handle is returned. Error\r
+ *   info can be retrieved from perf.\r
+ *\r
+ * INCLUDES\r
+ *   fci.h\r
+ *\r
  */\r
 HFCI __cdecl FCICreate(\r
        PERF perf,\r
-       PFNFCIFILEPLACED   pfnfcifp,\r
-       PFNFCIALLOC        pfna,\r
-       PFNFCIFREE         pfnf,\r
+       PFNFCIFILEPLACED   pfnfiledest,\r
+       PFNFCIALLOC        pfnalloc,\r
+       PFNFCIFREE         pfnfree,\r
        PFNFCIOPEN         pfnopen,\r
        PFNFCIREAD         pfnread,\r
        PFNFCIWRITE        pfnwrite,\r
@@ -49,17 +94,57 @@ HFCI __cdecl FCICreate(
        PCCAB              pccab,\r
        void *pv)\r
 {\r
-    FIXME("(%p, %p, %p, %p, %p, %p, %p, %p, %p, %p, %p, %p, %p): stub\n",\r
-         perf, pfnfcifp, pfna, pfnf, pfnopen, pfnread, pfnwrite, pfnclose,\r
-         pfnseek, pfndelete, pfnfcigtf, pccab, pv);\r
+  HFCI rv;\r
 \r
+  if ((!pfnalloc) || (!pfnfree)) {\r
     perf->erfOper = FCIERR_NONE;\r
-    perf->erfType = 0;\r
+    perf->erfType = ERROR_BAD_ARGUMENTS;\r
     perf->fError = TRUE;\r
 \r
-    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);\r
+    SetLastError(ERROR_BAD_ARGUMENTS);\r
+    return NULL;\r
+  }\r
+\r
+  if (!(rv = (HFCI) (*pfnalloc)(sizeof(FCI_Int)))) {\r
+    perf->erfOper = FCIERR_ALLOC_FAIL;\r
+    perf->erfType = ERROR_NOT_ENOUGH_MEMORY;\r
+    perf->fError = TRUE;\r
 \r
+    SetLastError(ERROR_NOT_ENOUGH_MEMORY);\r
     return NULL;\r
+  }\r
+\r
+  PFCI_INT(rv)->FCI_Intmagic = FCI_INT_MAGIC;\r
+  PFCI_INT(rv)->perf = perf;\r
+  PFCI_INT(rv)->pfnfiledest = pfnfiledest;\r
+  PFCI_INT(rv)->pfnalloc = pfnalloc;\r
+  PFCI_INT(rv)->pfnfree = pfnfree;\r
+  PFCI_INT(rv)->pfnopen = pfnopen;\r
+  PFCI_INT(rv)->pfnread = pfnread;\r
+  PFCI_INT(rv)->pfnwrite = pfnwrite;\r
+  PFCI_INT(rv)->pfnclose = pfnclose;\r
+  PFCI_INT(rv)->pfnseek = pfnseek;\r
+  PFCI_INT(rv)->pfndelete = pfndelete;\r
+  PFCI_INT(rv)->pfnfcigtf = pfnfcigtf;\r
+  PFCI_INT(rv)->pccab = pccab;\r
+  PFCI_INT(rv)->pv = pv;\r
+\r
+  /* Still mark as incomplete, because of other missing FCI* APIs */\r
+\r
+  PFCI_INT(rv)->FCI_Intmagic = 0;\r
+  PFDI_FREE(rv, rv);\r
+  FIXME("(%p, %p, %p, %p, %p, %p, %p, %p, %p, %p, %p, %p, %p): stub\n",\r
+    perf, pfnfiledest, pfnalloc, pfnfree, pfnopen, pfnread, pfnwrite, pfnclose,\r
+    pfnseek, pfndelete, pfnfcigtf, pccab, pv);\r
+\r
+  perf->erfOper = FCIERR_NONE;\r
+  perf->erfType = 0;\r
+  perf->fError = TRUE;\r
+\r
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);\r
+\r
+  return NULL;\r
+\r
 }\r
 \r
 /***********************************************************************\r
@@ -116,12 +201,30 @@ BOOL __cdecl FCIFlushFolder(
 \r
 /***********************************************************************\r
  *             FCIDestroy (CABINET.14)\r
+ *\r
+ * Frees a handle created by FCICreate.\r
+ * Only reason for failure would be an invalid handle.\r
+ *\r
+ * PARAMS\r
+ *   hfci [I] The HFCI to free\r
+ *\r
+ * RETURNS\r
+ *   TRUE for success\r
+ *   FALSE for failure\r
  */\r
 BOOL __cdecl FCIDestroy(HFCI hfci)\r
 {\r
-    FIXME("(%p): stub\n", hfci);\r
-\r
-    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);\r
-\r
+  if (REALLY_IS_FCI(hfci)) {\r
+    PFCI_INT(hfci)->FCI_Intmagic = 0;\r
+    PFDI_FREE(hfci, hfci);\r
+    /*return TRUE; */\r
+  } else {\r
+    SetLastError(ERROR_INVALID_HANDLE);\r
     return FALSE;\r
+  }\r
+\r
+  /* Still mark as incomplete, because of other missing FCI* APIs */\r
+  FIXME("(%p): stub\n", hfci);\r
+  SetLastError(ERROR_CALL_NOT_IMPLEMENTED);\r
+  return FALSE;\r
 }\r