[cabinet]
[reactos.git] / reactos / dll / win32 / cabinet / fdi.c
index a0bb64a..de64f02 100644 (file)
@@ -121,7 +121,7 @@ typedef struct {
 
 typedef struct fdi_cds_fwd {
   void *hfdi;                      /* the hfdi we are using                 */
-  int filehf, cabhf;               /* file handle we are using              */
+  INT_PTR filehf, cabhf;           /* file handle we are using              */
   struct fdi_folder *current;      /* current folder we're extracting from  */
   cab_ULONG offset;                /* uncompressed offset within folder     */
   cab_UBYTE *outpos;               /* (high level) start of data to use up  */
@@ -151,7 +151,7 @@ typedef struct fdi_cds_fwd {
 /****************************************************************
  * QTMupdatemodel (internal)
  */
-void QTMupdatemodel(struct QTMmodel *model, int sym) {
+static void QTMupdatemodel(struct QTMmodel *model, int sym) {
   struct QTMmodelsym temp;
   int i, j;
 
@@ -160,21 +160,21 @@ void QTMupdatemodel(struct QTMmodel *model, int sym) {
   if (model->syms[0].cumfreq > 3800) {
     if (--model->shiftsleft) {
       for (i = model->entries - 1; i >= 0; i--) {
-    /* -1, not -2; the 0 entry saves this */
-    model->syms[i].cumfreq >>= 1;
-    if (model->syms[i].cumfreq <= model->syms[i+1].cumfreq) {
-      model->syms[i].cumfreq = model->syms[i+1].cumfreq + 1;
-    }
+        /* -1, not -2; the 0 entry saves this */
+        model->syms[i].cumfreq >>= 1;
+        if (model->syms[i].cumfreq <= model->syms[i+1].cumfreq) {
+          model->syms[i].cumfreq = model->syms[i+1].cumfreq + 1;
+        }
       }
     }
     else {
       model->shiftsleft = 50;
       for (i = 0; i < model->entries ; i++) {
-    /* no -1, want to include the 0 entry */
-    /* this converts cumfreqs into frequencies, then shifts right */
-    model->syms[i].cumfreq -= model->syms[i+1].cumfreq;
-    model->syms[i].cumfreq++; /* avoid losing things entirely */
-    model->syms[i].cumfreq >>= 1;
+        /* no -1, want to include the 0 entry */
+        /* this converts cumfreqs into frequencies, then shifts right */
+        model->syms[i].cumfreq -= model->syms[i+1].cumfreq;
+        model->syms[i].cumfreq++; /* avoid losing things entirely */
+        model->syms[i].cumfreq >>= 1;
       }
 
       /* now sort by frequencies, decreasing order -- this must be an
@@ -182,22 +182,22 @@ void QTMupdatemodel(struct QTMmodel *model, int sym) {
        * characteristics
        */
       for (i = 0; i < model->entries - 1; i++) {
-    for (j = i + 1; j < model->entries; j++) {
-      if (model->syms[i].cumfreq < model->syms[j].cumfreq) {
-        temp = model->syms[i];
-        model->syms[i] = model->syms[j];
-        model->syms[j] = temp;
-      }
-    }
+        for (j = i + 1; j < model->entries; j++) {
+          if (model->syms[i].cumfreq < model->syms[j].cumfreq) {
+            temp = model->syms[i];
+            model->syms[i] = model->syms[j];
+            model->syms[j] = temp;
+          }
+        }
       }
-    
+
       /* then convert frequencies back to cumfreq */
       for (i = model->entries - 1; i >= 0; i--) {
-    model->syms[i].cumfreq += model->syms[i+1].cumfreq;
+        model->syms[i].cumfreq += model->syms[i+1].cumfreq;
       }
       /* then update the other part of the table */
       for (i = 0; i < model->entries; i++) {
-    model->tabloc[model->syms[i].sym] = i;
+        model->tabloc[model->syms[i].sym] = i;
       }
     }
   }
@@ -220,7 +220,8 @@ void QTMupdatemodel(struct QTMmodel *model, int sym) {
  *   OK:    0
  *   error: 1
  */
-int make_decode_table(cab_ULONG nsyms, cab_ULONG nbits, const cab_UBYTE *length, cab_UWORD *table) {
+static int make_decode_table(cab_ULONG nsyms, cab_ULONG nbits,
+                             const cab_UBYTE *length, cab_UWORD *table) {
   register cab_UWORD sym;
   register cab_ULONG leaf;
   register cab_UBYTE bit_num = 1;
@@ -293,7 +294,7 @@ int make_decode_table(cab_ULONG nsyms, cab_ULONG nbits, const cab_UBYTE *length,
 /*************************************************************************
  * checksum (internal)
  */
-cab_ULONG checksum(const cab_UBYTE *data, cab_UWORD bytes, cab_ULONG csum) {
+static cab_ULONG checksum(const cab_UBYTE *data, cab_UWORD bytes, cab_ULONG csum) {
   int len;
   cab_ULONG ul = 0;
 
@@ -882,7 +883,7 @@ static int LZXfdi_init(int window, fdi_decomp_state *decomp_state) {
   memcpy(CAB(lzx_position_base), base, sizeof(base));
 
   /* calculate required position slots */
-       if (window == 20) posn_slots = 42;
+  if (window == 20) posn_slots = 42;
   else if (window == 21) posn_slots = 50;
   else posn_slots = window << 1;
 
@@ -911,6 +912,7 @@ static int LZXfdi_init(int window, fdi_decomp_state *decomp_state) {
 static int NONEfdi_decomp(int inlen, int outlen, fdi_decomp_state *decomp_state)
 {
   if (inlen != outlen) return DECR_ILLEGALDATA;
+  if (outlen > CAB_BLOCKMAX) return DECR_DATAFORMAT;
   memcpy(CAB(outbuf), CAB(inbuf), (size_t) inlen);
   return DECR_OK;
 }
@@ -924,7 +926,7 @@ static void fdi_Ziphuft_free(HFDI hfdi, struct Ziphuft *t)
 
   /* Go through linked list, freeing from the allocated (t[-1]) address. */
   p = t;
-  while (p != (struct Ziphuft *)NULL)
+  while (p != NULL)
   {
     q = (--p)->v.t;
     PFDI_FREE(hfdi, p);
@@ -969,7 +971,7 @@ struct Ziphuft **t, cab_LONG *m, fdi_decomp_state *decomp_state)
   } while (--i);
   if (ZIP(c)[0] == n)                /* null input--all zero length codes */
   {
-    *t = (struct Ziphuft *)NULL;
+    *t = NULL;
     *m = 0;
     return 0;
   }
@@ -1017,8 +1019,8 @@ struct Ziphuft **t, cab_LONG *m, fdi_decomp_state *decomp_state)
   p = ZIP(v);                        /* grab values in bit order */
   h = -1;                       /* no tables yet--level -1 */
   w = l[-1] = 0;                /* no bits decoded yet */
-  ZIP(u)[0] = (struct Ziphuft *)NULL;   /* just to keep compilers happy */
-  q = (struct Ziphuft *)NULL;      /* ditto */
+  ZIP(u)[0] = NULL;             /* just to keep compilers happy */
+  q = NULL;                     /* ditto */
   z = 0;                        /* ditto */
 
   /* go through the bit lengths (k already is bits in shortest code) */
@@ -1034,7 +1036,8 @@ struct Ziphuft **t, cab_LONG *m, fdi_decomp_state *decomp_state)
         w += l[h++];            /* add bits already decoded */
 
         /* compute minimum size table less than or equal to *m bits */
-        z = (z = g - w) > (cab_ULONG)*m ? *m : z;        /* upper limit */
+        if ((z = g - w) > (cab_ULONG)*m)    /* upper limit */
+          z = *m;
         if ((f = 1 << (j = k - w)) > a + 1)     /* try a k-w bit table */
         {                       /* too few codes for k-w bit table */
           f -= a + 1;           /* deduct codes from patterns left */
@@ -1052,14 +1055,14 @@ struct Ziphuft **t, cab_LONG *m, fdi_decomp_state *decomp_state)
         l[h] = j;               /* set table size in stack */
 
         /* allocate and link in new table */
-        if (!(q = (struct Ziphuft *) PFDI_ALLOC(CAB(hfdi), (z + 1)*sizeof(struct Ziphuft))))
+        if (!(q = PFDI_ALLOC(CAB(hfdi), (z + 1)*sizeof(struct Ziphuft))))
         {
           if(h)
             fdi_Ziphuft_free(CAB(hfdi), ZIP(u)[0]);
           return 3;             /* not enough memory */
         }
         *t = q + 1;             /* link to list for Ziphuft_free() */
-        *(t = &(q->v.t)) = (struct Ziphuft *)NULL;
+        *(t = &(q->v.t)) = NULL;
         ZIP(u)[h] = ++q;             /* table starts after link */
 
         /* connect to last table, if there is one */
@@ -1177,7 +1180,10 @@ static cab_LONG fdi_Zipinflate_codes(const struct Ziphuft *tl, const struct Ziph
       ZIPDUMPBITS(e)
       do
       {
-        n -= (e = (e = ZIPWSIZE - ((d &= ZIPWSIZE-1) > w ? d : w)) > n ?n:e);
+        d &= ZIPWSIZE - 1;
+        e = ZIPWSIZE - max(d, w);
+        e = min(e, n);
+        n -= e;
         do
         {
           CAB(outbuf)[w++] = CAB(outbuf)[d++];
@@ -2047,7 +2053,8 @@ static int fdi_decomp(const struct fdi_file *fi, int savemode, fdi_decomp_state
       /* outlen=0 means this block was the last contiguous part
          of a split block, continued in the next cabinet */
       if (outlen == 0) {
-        int pathlen, filenamelen, idx, i, cabhf;
+        int pathlen, filenamelen, idx, i;
+        INT_PTR cabhf;
         char fullpath[MAX_PATH], userpath[256];
         FDINOTIFICATION fdin;
         FDICABINETINFO fdici;
@@ -2174,8 +2181,8 @@ static int fdi_decomp(const struct fdi_file *fi, int savemode, fdi_decomp_state
 
             if (cab->mii.folder_resv > 0)
               PFDI_SEEK(CAB(hfdi), cab->cabhf, cab->mii.folder_resv, SEEK_CUR);
-        
-            fol = (struct fdi_folder *) PFDI_ALLOC(CAB(hfdi), sizeof(struct fdi_folder));
+
+            fol = PFDI_ALLOC(CAB(hfdi), sizeof(struct fdi_folder));
             if (!fol) {
               ERR("out of memory!\n");
               return DECR_NOMEMORY;
@@ -2196,8 +2203,8 @@ static int fdi_decomp(const struct fdi_file *fi, int savemode, fdi_decomp_state
           for (i = 0; i < fdici.cFiles; i++) {
             if (PFDI_READ(CAB(hfdi), cab->cabhf, buf2, cffile_SIZEOF) != cffile_SIZEOF)
               return DECR_INPUT;
-              
-            file = (struct fdi_file *) PFDI_ALLOC(CAB(hfdi), sizeof(struct fdi_file));
+
+            file = PFDI_ALLOC(CAB(hfdi), sizeof(struct fdi_file));
             if (!file) {
               ERR("out of memory!\n"); 
               return DECR_NOMEMORY;
@@ -2229,7 +2236,7 @@ static int fdi_decomp(const struct fdi_file *fi, int savemode, fdi_decomp_state
         for (file = cab->firstfile; (file); file = file->next) {
           if ((file->index & cffileCONTINUED_FROM_PREV) == cffileCONTINUED_FROM_PREV) {
             /* check to ensure a real match */
-            if (strcasecmp(fi->filename, file->filename) == 0) {
+            if (lstrcmpiA(fi->filename, file->filename) == 0) {
               success = TRUE;
               if (PFDI_SEEK(CAB(hfdi), cab->cabhf, cab->firstfol->offset, SEEK_SET) == -1)
                 return DECR_INPUT;
@@ -2253,6 +2260,57 @@ static int fdi_decomp(const struct fdi_file *fi, int savemode, fdi_decomp_state
   return DECR_OK;
 }
 
+static void free_decompression_temps(HFDI hfdi, const struct fdi_folder *fol,
+  fdi_decomp_state *decomp_state)
+{
+  switch (fol->comp_type & cffoldCOMPTYPE_MASK) {
+  case cffoldCOMPTYPE_LZX:
+    if (LZX(window)) {
+      PFDI_FREE(hfdi, LZX(window));
+      LZX(window) = NULL;
+    }
+    break;
+  case cffoldCOMPTYPE_QUANTUM:
+    if (QTM(window)) {
+      PFDI_FREE(hfdi, QTM(window));
+      QTM(window) = NULL;
+    }
+    break;
+  }
+}
+
+static void free_decompression_mem(HFDI hfdi,
+  fdi_decomp_state *decomp_state, struct fdi_file *file)
+{
+  struct fdi_folder *fol;
+  while (decomp_state) {
+    fdi_decomp_state *prev_fds;
+
+    PFDI_CLOSE(hfdi, CAB(cabhf));
+
+    /* free the storage remembered by mii */
+    if (CAB(mii).nextname) PFDI_FREE(hfdi, CAB(mii).nextname);
+    if (CAB(mii).nextinfo) PFDI_FREE(hfdi, CAB(mii).nextinfo);
+    if (CAB(mii).prevname) PFDI_FREE(hfdi, CAB(mii).prevname);
+    if (CAB(mii).previnfo) PFDI_FREE(hfdi, CAB(mii).previnfo);
+
+    while (CAB(firstfol)) {
+      fol = CAB(firstfol);
+      CAB(firstfol) = CAB(firstfol)->next;
+      PFDI_FREE(hfdi, fol);
+    }
+    while (CAB(firstfile)) {
+      file = CAB(firstfile);
+      if (file->filename) PFDI_FREE(hfdi, (void *)file->filename);
+      CAB(firstfile) = CAB(firstfile)->next;
+      PFDI_FREE(hfdi, file);
+    }
+    prev_fds = decomp_state;
+    decomp_state = CAB(next);
+    PFDI_FREE(hfdi, prev_fds);
+  }
+}
+
 /***********************************************************************
  *             FDICopy (CABINET.22)
  *
@@ -2428,7 +2486,8 @@ BOOL __cdecl FDICopy(
 { 
   FDICABINETINFO    fdici;
   FDINOTIFICATION   fdin;
-  int               cabhf, filehf = 0, idx;
+  INT_PTR           cabhf, filehf = 0;
+  int               idx;
   unsigned int      i;
   char              fullpath[MAX_PATH];
   size_t            pathlen, filenamelen;
@@ -2436,8 +2495,7 @@ BOOL __cdecl FDICopy(
   cab_UBYTE         buf[64];
   struct fdi_folder *fol = NULL, *linkfol = NULL; 
   struct fdi_file   *file = NULL, *linkfile = NULL;
-  fdi_decomp_state _decomp_state;
-  fdi_decomp_state *decomp_state = &_decomp_state;
+  fdi_decomp_state *decomp_state;
 
   TRACE("(hfdi == ^%p, pszCabinet == ^%p, pszCabPath == ^%p, flags == %0d, "
         "pfnfdin == ^%p, pfnfdid == ^%p, pvUser == ^%p)\n",
@@ -2448,6 +2506,11 @@ BOOL __cdecl FDICopy(
     return FALSE;
   }
 
+  if (!(decomp_state = PFDI_ALLOC(hfdi, sizeof(fdi_decomp_state))))
+  {
+      SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+      return FALSE;
+  }
   ZeroMemory(decomp_state, sizeof(fdi_decomp_state));
 
   pathlen = (pszCabPath) ? strlen(pszCabPath) : 0;
@@ -2456,6 +2519,7 @@ BOOL __cdecl FDICopy(
   /* slight overestimation here to save CPU cycles in the developer's brain */
   if ((pathlen + filenamelen + 3) > MAX_PATH) {
     ERR("MAX_PATH exceeded.\n");
+    PFDI_FREE(hfdi, decomp_state);
     PFDI_INT(hfdi)->perf->erfOper = FDIERROR_CABINET_NOT_FOUND;
     PFDI_INT(hfdi)->perf->erfType = ERROR_FILE_NOT_FOUND;
     PFDI_INT(hfdi)->perf->fError = TRUE;
@@ -2477,6 +2541,7 @@ BOOL __cdecl FDICopy(
   /* get a handle to the cabfile */
   cabhf = PFDI_OPEN(hfdi, fullpath, _O_RDONLY|_O_BINARY, _S_IREAD | _S_IWRITE);
   if (cabhf == -1) {
+    PFDI_FREE(hfdi, decomp_state);
     PFDI_INT(hfdi)->perf->erfOper = FDIERROR_CABINET_NOT_FOUND;
     PFDI_INT(hfdi)->perf->fError = TRUE;
     SetLastError(ERROR_FILE_NOT_FOUND);
@@ -2485,6 +2550,7 @@ BOOL __cdecl FDICopy(
 
   if (cabhf == 0) {
     ERR("PFDI_OPEN returned zero for %s.\n", fullpath);
+    PFDI_FREE(hfdi, decomp_state);
     PFDI_INT(hfdi)->perf->erfOper = FDIERROR_CABINET_NOT_FOUND;
     PFDI_INT(hfdi)->perf->erfType = ERROR_FILE_NOT_FOUND;
     PFDI_INT(hfdi)->perf->fError = TRUE;
@@ -2495,6 +2561,7 @@ BOOL __cdecl FDICopy(
   /* check if it's really a cabfile. Note that this doesn't implement the bug */
   if (!FDI_read_entries(hfdi, cabhf, &fdici, &(CAB(mii)))) {
     ERR("FDIIsCabinet failed.\n");
+    PFDI_FREE(hfdi, decomp_state);
     PFDI_CLOSE(hfdi, cabhf);
     return FALSE;
   }
@@ -2531,7 +2598,7 @@ BOOL __cdecl FDICopy(
     if (CAB(mii).folder_resv > 0)
       PFDI_SEEK(hfdi, cabhf, CAB(mii).folder_resv, SEEK_CUR);
 
-    fol = (struct fdi_folder *) PFDI_ALLOC(hfdi, sizeof(struct fdi_folder));
+    fol = PFDI_ALLOC(hfdi, sizeof(struct fdi_folder));
     if (!fol) {
       ERR("out of memory!\n");
       PFDI_INT(hfdi)->perf->erfOper = FDIERROR_ALLOC_FAIL;
@@ -2561,7 +2628,7 @@ BOOL __cdecl FDICopy(
       goto bail_and_fail;
     }
 
-    file = (struct fdi_file *) PFDI_ALLOC(hfdi, sizeof(struct fdi_file));
+    file = PFDI_ALLOC(hfdi, sizeof(struct fdi_file));
     if (!file) { 
       ERR("out of memory!\n"); 
       PFDI_INT(hfdi)->perf->erfOper = FDIERROR_ALLOC_FAIL;
@@ -2771,7 +2838,7 @@ BOOL __cdecl FDICopy(
 
       if (file->offset > CAB(offset)) {
         /* decode bytes and send them to /dev/null */
-        switch ((err = fdi_decomp(file, 0, decomp_state, pszCabPath, pfnfdin, pvUser))) {
+        switch (fdi_decomp(file, 0, decomp_state, pszCabPath, pfnfdin, pvUser)) {
           case DECR_OK:
             break;
           case DECR_USERABORT:
@@ -2833,99 +2900,18 @@ BOOL __cdecl FDICopy(
     }
   }
 
-  /* free decompression temps */
-  switch (fol->comp_type & cffoldCOMPTYPE_MASK) {
-  case cffoldCOMPTYPE_LZX:
-    if (LZX(window)) {
-      PFDI_FREE(hfdi, LZX(window));
-      LZX(window) = NULL;
-    }
-    break;
-  case cffoldCOMPTYPE_QUANTUM:
-    if (QTM(window)) {
-      PFDI_FREE(hfdi, QTM(window));
-      QTM(window) = NULL;
-    }
-    break;
-  }
-
-  while (decomp_state) {
-    fdi_decomp_state *prev_fds;
-
-    PFDI_CLOSE(hfdi, CAB(cabhf));
-
-    /* free the storage remembered by mii */
-    if (CAB(mii).nextname) PFDI_FREE(hfdi, CAB(mii).nextname);
-    if (CAB(mii).nextinfo) PFDI_FREE(hfdi, CAB(mii).nextinfo);
-    if (CAB(mii).prevname) PFDI_FREE(hfdi, CAB(mii).prevname);
-    if (CAB(mii).previnfo) PFDI_FREE(hfdi, CAB(mii).previnfo);
-
-    while (CAB(firstfol)) {
-      fol = CAB(firstfol);
-      CAB(firstfol) = CAB(firstfol)->next;
-      PFDI_FREE(hfdi, fol);
-    }
-    while (CAB(firstfile)) {
-      file = CAB(firstfile);
-      if (file->filename) PFDI_FREE(hfdi, (void *)file->filename);
-      CAB(firstfile) = CAB(firstfile)->next;
-      PFDI_FREE(hfdi, file);
-    }
-    prev_fds = decomp_state;
-    decomp_state = CAB(next);
-    if (prev_fds != &_decomp_state)
-      PFDI_FREE(hfdi, prev_fds);
-  }
+  free_decompression_temps(hfdi, fol, decomp_state);
+  free_decompression_mem(hfdi, decomp_state, file);
  
   return TRUE;
 
   bail_and_fail: /* here we free ram before error returns */
 
-  /* free decompression temps */
-  switch (fol->comp_type & cffoldCOMPTYPE_MASK) {
-  case cffoldCOMPTYPE_LZX:
-    if (LZX(window)) {
-      PFDI_FREE(hfdi, LZX(window));
-      LZX(window) = NULL;
-    }
-    break;
-  case cffoldCOMPTYPE_QUANTUM:
-    if (QTM(window)) {
-      PFDI_FREE(hfdi, QTM(window));
-      QTM(window) = NULL;
-    }
-    break;
-  }
+  if (fol) free_decompression_temps(hfdi, fol, decomp_state);
 
   if (filehf) PFDI_CLOSE(hfdi, filehf);
 
-  while (decomp_state) {
-    fdi_decomp_state *prev_fds;
-
-    PFDI_CLOSE(hfdi, CAB(cabhf));
-
-    /* free the storage remembered by mii */
-    if (CAB(mii).nextname) PFDI_FREE(hfdi, CAB(mii).nextname);
-    if (CAB(mii).nextinfo) PFDI_FREE(hfdi, CAB(mii).nextinfo);
-    if (CAB(mii).prevname) PFDI_FREE(hfdi, CAB(mii).prevname);
-    if (CAB(mii).previnfo) PFDI_FREE(hfdi, CAB(mii).previnfo);
-
-    while (CAB(firstfol)) {
-      fol = CAB(firstfol);
-      CAB(firstfol) = CAB(firstfol)->next;
-      PFDI_FREE(hfdi, fol);
-    }
-    while (CAB(firstfile)) {
-      file = CAB(firstfile);
-      if (file->filename) PFDI_FREE(hfdi, (void *)file->filename);
-      CAB(firstfile) = CAB(firstfile)->next;
-      PFDI_FREE(hfdi, file);
-    }
-    prev_fds = decomp_state;
-    decomp_state = CAB(next);
-    if (prev_fds != &_decomp_state)
-      PFDI_FREE(hfdi, prev_fds);
-  }
+  free_decompression_mem(hfdi, decomp_state, file);
 
   return FALSE;
 }