cabinet.extract (2)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello

this patch is the summary about my investigations about the cabinet extract 
function.

ChangeLog
--------------
	make use of/handle the first parameter of the function extract
diff -uwr ../wine/dlls/cabinet/cabextract.c dlls/cabinet/cabextract.c
--- ../wine/dlls/cabinet/cabextract.c	2003-10-07 20:44:46.000000000 +0200
+++ dlls/cabinet/cabextract.c	2003-12-29 20:34:01.000000000 +0100
@@ -2553,12 +2553,13 @@
  *   dir     [I] directory to extract to
  *   fix     [I] attempt to process broken cabinets
  *   lower   [I] ? (lower case something or other?)
+ *   dest    [O] 
  *
  * RETURNS
  *   Success: TRUE
  *   Failure: FALSE
  */
-BOOL process_cabinet(LPCSTR cabname, LPCSTR dir, BOOL fix, BOOL lower)
+BOOL process_cabinet(LPCSTR cabname, LPCSTR dir, BOOL fix, BOOL lower, EXTRACTdest *dest)
 {
   struct cabinet *basecab, *cab, *cab1, *cab2;
   struct cab_file *filelist, *fi;
@@ -2618,12 +2619,18 @@
       TRACE("----------+---------------------+-------------\n");
       viewhdr = 1;
     }
-    for (fi = filelist; fi; fi = fi->next)
+    for (fi = filelist; fi; fi = fi->next) {
 	print_fileinfo(fi);
+        dest->filecount++;
+    }
     TRACE("Beginning Extraction...\n");
     for (fi = filelist; fi; fi = fi->next) {
 	TRACE("  extracting: %s\n", debugstr_a(fi->filename));
 	extract_file(fi, lower, fix, dir, decomp_state);
+        sprintf(dest->lastfile, "%s%s%s",
+                strlen(dest->directory) ? dest->directory : "",
+                strlen(dest->directory) ? "\\": "",
+                fi->filename);
     }
   }
 
diff -uwr ../wine/dlls/cabinet/cabinet.h dlls/cabinet/cabinet.h
--- ../wine/dlls/cabinet/cabinet.h	2003-09-11 00:14:05.000000000 +0200
+++ dlls/cabinet/cabinet.h	2003-12-29 20:34:01.000000000 +0100
@@ -553,8 +553,20 @@
  0x01ff, 0x03ff, 0x07ff, 0x0fff, 0x1fff, 0x3fff, 0x7fff, 0xffff                    \
 }
 
+/* the first parameter of the function extract */
+typedef struct {
+        long  result1;          // 0x000
+        long  unknown1[3];      // 0x004
+        long  result2;          // 0x010
+        long  filecount;        // 0x014
+        long  unknown2;         // 0x018
+        char  directory[0x104]; // 0x01c
+        char  lastfile[0x20c];  // 0x120
+} EXTRACTdest;
+
+
 /* from cabextract.c */
-BOOL process_cabinet(LPCSTR cabname, LPCSTR dir, BOOL fix, BOOL lower);
+BOOL process_cabinet(LPCSTR cabname, LPCSTR dir, BOOL fix, BOOL lower, EXTRACTdest *dest);
 void QTMupdatemodel(struct QTMmodel *model, int sym);
 int make_decode_table(cab_ULONG nsyms, cab_ULONG nbits, cab_UBYTE *length, cab_UWORD *table);
 cab_ULONG checksum(cab_UBYTE *data, cab_UWORD bytes, cab_ULONG csum);
diff -uwr ../wine/dlls/cabinet/cabinet_main.c dlls/cabinet/cabinet_main.c
--- ../wine/dlls/cabinet/cabinet_main.c	2003-09-11 00:14:05.000000000 +0200
+++ dlls/cabinet/cabinet_main.c	2003-12-29 20:50:08.000000000 +0100
@@ -73,60 +73,66 @@
  * to somewhere...
  *
  * PARAMS
- *   unknown [IO] unknown pointer
+ *   dest         pointer to a buffer of 0x32c bytes containing
+ *           [I]  - number with value 1 at index 0x18
+ *                - the dest path starting at index 0x1c
+ *           [O]  - the number of files inside the CAB file at index 0x14
+ *                - the name of the last file with dest path at idx 0x12
  *   what    [I]  char* describing what to uncompress, I guess.
  *
  * RETURNS
  *     Success: S_OK
  *     Failure: E_OUTOFMEMORY (?)
  */
-HRESULT WINAPI Extract(DWORD unknown, LPCSTR what)
+HRESULT WINAPI Extract(EXTRACTdest *dest, LPCSTR what)
 {
-  LPCSTR whatx;
-  LPSTR dir, dirx, lastoption, x;
-  BOOL updatelastoption;
+#define DUMPC(idx)      idx >= sizeof(EXTRACTdest) ? ' ' : \
+                        ptr[idx] >= 0x20 ? ptr[idx] : '.'
 
-  TRACE("(unknown == %0lx, what == %s)\n", unknown, debugstr_a(what));
+#define DUMPH(idx)      idx >= sizeof(EXTRACTdest) ? 0x55 : ptr[idx]
 
-  dir = LocalAlloc(LPTR, strlen(what)); 
-  if (!dir) return E_OUTOFMEMORY;
+  LPSTR dir;
+  unsigned char *ptr = (unsigned char*) dest;
+  int i;
 
-  /* copy the filename up to the last pathsep to construct the dirname */
-  whatx = what;
-  dirx = dir;
-  lastoption = NULL;
-  while (*whatx) {
-    if ((*whatx == '\\') || (*whatx == '/')) {
-      /* unless all chars between *dirx and lastoption are pathsep's, we
-         remember our location in dir as lastoption */
-      if (lastoption) {
-        updatelastoption = FALSE;
-        for (x = lastoption; x < dirx; x++)
-	  if ((*dirx != '\\') && (*dirx != '/')) {
-	    updatelastoption = TRUE;
-	    break;
-	  }
-        if (updatelastoption) lastoption = dirx;
-      } else
-        lastoption = dirx;
-    }
-    *dirx++ = *whatx++;
-  }
+  TRACE("(dest == %0lx, what == %s)\n", (long) dest, debugstr_a(what));
 
-  if (!lastoption) {
-    /* FIXME: I guess use the cwd or something? */
-    assert(FALSE);
-  } else {
-    *lastoption = '\0';
+  if (!dest) {
+    /* win2k will crash here */
+    FIXME("called without valid parameter dest!\n");
+    return E_OUTOFMEMORY;
   }
+  for (i=0; i < sizeof(EXTRACTdest); i+=8)
+    TRACE( "dest[%04x]:%02x %02x %02x %02x %02x %02x %02x %02x %c%c%c%c%c%c%c%c\n",
+           i,
+           DUMPH(i+0), DUMPH(i+1), DUMPH(i+2), DUMPH(i+3),
+           DUMPH(i+4), DUMPH(i+5), DUMPH(i+6), DUMPH(i+7),
+           DUMPC(i+0), DUMPC(i+1), DUMPC(i+2), DUMPC(i+3),
+           DUMPC(i+4), DUMPC(i+5), DUMPC(i+6), DUMPC(i+7));
+
+  dir = LocalAlloc(LPTR, strlen(dest->directory)+1); 
+  if (!dir) return E_OUTOFMEMORY;
+  lstrcpyA(dir, dest->directory);
+  dest->filecount=0;
 
   TRACE("extracting to dir: %s\n", debugstr_a(dir));
 
   /* FIXME: what to do on failure? */
-  if (!process_cabinet(what, dir, FALSE, FALSE))
+  if (!process_cabinet(what, dir, FALSE, FALSE, dest))
     return E_OUTOFMEMORY;
 
+  /* the magic 13 is returned by all cab files tested so far:
+   * DXDDEX.CAB, DXMINI.CAB, SWFLASH.CAB on win2k
+   * but it crashes the ie5.5 installer :-( . The native dll does not return
+   * the four zeros. The value depends on the combination of the cab file and
+   * the destination path
+   */
+  dest->result2=0x130000;
+
   LocalFree(dir);
 
+  TRACE("filecount %08lx,lastfile %s\n",
+         dest->filecount, debugstr_a(dest->lastfile));
+
   return S_OK;
 }

[Index of Archives]     [Gimp for Windows]     [Red Hat]     [Samba]     [Yosemite Camping]     [Graphics Cards]     [Wine Home]

  Powered by Linux