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; }