* -gmt
*/
-#include <config.h>
+#include "config.h"
-//#include <stdarg.h>
+#include <stdarg.h>
#include <stdio.h>
-//#include "windef.h"
-//#include "winbase.h"
-//#include "winerror.h"
-//#include "fdi.h"
+#include "windef.h"
+#include "winbase.h"
+#include "winerror.h"
+#include "fdi.h"
#include "cabinet.h"
-#include <wine/debug.h>
+#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(cabinet);
break;
}
/* The buffer is too small for the string. Reset the file to the point
- * were we started, free the buffer and increase the size for the next try
+ * where we started, free the buffer and increase the size for the next try
*/
fdi->seek(hf, base, SEEK_SET);
fdi->free(buf);
PMORE_ISCAB_INFO pmii)
{
int num_folders, num_files, header_resv, folder_resv = 0;
- LONG base_offset, cabsize;
+ LONG cabsize;
USHORT setid, cabidx, flags;
cab_UBYTE buf[64], block_resv;
char *prevname = NULL, *previnfo = NULL, *nextname = NULL, *nextinfo = NULL;
TRACE("(fdi == ^%p, hf == %ld, pfdici == ^%p)\n", fdi, hf, pfdici);
- /*
- * FIXME: I just noticed that I am memorizing the initial file pointer
- * offset and restoring it before reading in the rest of the header
- * information in the cabinet. Perhaps that's correct -- that is, perhaps
- * this API is supposed to support "streaming" cabinets which are embedded
- * in other files, or cabinets which begin at file offsets other than zero.
- * Otherwise, I should instead go to the absolute beginning of the file.
- * (Either way, the semantics of wine's FDICopy require me to leave the
- * file pointer where it is afterwards -- If Windows does not do so, we
- * ought to duplicate the native behavior in the FDIIsCabinet API, not here.
- *
- * So, the answer lies in Windows; will native cabinet.dll recognize a
- * cabinet "file" embedded in another file? Note that cabextract.c does
- * support this, which implies that Microsoft's might. I haven't tried it
- * yet so I don't know. ATM, most of wine's FDI cabinet routines (except
- * this one) would not work in this way. To fix it, we could just make the
- * various references to absolute file positions in the code relative to an
- * initial "beginning" offset. Because the FDICopy API doesn't take a
- * file-handle like this one, we would therein need to search through the
- * file for the beginning of the cabinet (as we also do in cabextract.c).
- * Note that this limits us to a maximum of one cabinet per. file: the first.
- *
- * So, in summary: either the code below is wrong, or the rest of fdi.c is
- * wrong... I cannot imagine that both are correct ;) One of these flaws
- * should be fixed after determining the behavior on Windows. We ought
- * to check both FDIIsCabinet and FDICopy for the right behavior.
- *
- * -gmt
- */
-
- /* get basic offset & size info */
- base_offset = FDI_getoffset(fdi, hf);
-
- if (fdi->seek(hf, 0, SEEK_END) == -1) {
- if (pmii) set_error( fdi, FDIERROR_NOT_A_CABINET, 0 );
- return FALSE;
- }
-
- cabsize = FDI_getoffset(fdi, hf);
-
- if ((cabsize == -1) || (base_offset == -1) ||
- ( fdi->seek(hf, base_offset, SEEK_SET) == -1 )) {
- if (pmii) set_error( fdi, FDIERROR_NOT_A_CABINET, 0 );
- return FALSE;
- }
-
/* read in the CFHEADER */
if (fdi->read(hf, buf, cfhead_SIZEOF) != cfhead_SIZEOF) {
if (pmii) set_error( fdi, FDIERROR_NOT_A_CABINET, 0 );
return FALSE;
}
-
+
/* check basic MSCF signature */
if (EndGetI32(buf+cfhead_Signature) != 0x4643534d) {
if (pmii) set_error( fdi, FDIERROR_NOT_A_CABINET, 0 );
return FALSE;
}
+ /* get the cabinet size */
+ cabsize = EndGetI32(buf+cfhead_CabinetSize);
+
/* get the number of folders */
num_folders = EndGetI16(buf+cfhead_NumFolders);
if (!fdi) return FALSE;
- if (!hf) {
- SetLastError(ERROR_INVALID_HANDLE);
- return FALSE;
- }
-
if (!pfdici) {
SetLastError(ERROR_BAD_ARGUMENTS);
return FALSE;
FDICABINETINFO fdici;
char emptystring = '\0';
cab_UBYTE buf2[64];
- int success = FALSE;
+ BOOL success = FALSE;
struct fdi_folder *fol = NULL, *linkfol = NULL;
struct fdi_file *file = NULL, *linkfile = NULL;
fullpath[0] = '\0';
if (pathlen) {
strcpy(fullpath, userpath);
+#ifdef __REACTOS__
+ if (fullpath[pathlen - 1] == '\\')
+ fullpath[pathlen - 1] = '\0';
+#else
if (fullpath[pathlen - 1] != '\\')
strcat(fullpath, "\\");
+#endif
}
+#ifdef __REACTOS__
+ if (filenamelen) {
+ strcat(fullpath, "\\");
+#else
if (filenamelen)
+#endif
strcat(fullpath, cab->mii.nextname);
+#ifdef __REACTOS__
+ }
+#endif
TRACE("full cab path/file name: %s\n", debugstr_a(fullpath));
fdin.psz2 = (CAB(mii).nextinfo) ? CAB(mii).nextinfo : &emptystring;
fdin.psz3 = pszCabPath;
- if (((*pfnfdin)(fdintCABINET_INFO, &fdin))) {
+ if (pfnfdin(fdintCABINET_INFO, &fdin) == -1) {
set_error( fdi, FDIERROR_USER_ABORT, 0 );
goto bail_and_fail;
}
* where all the cabinet files needed for decryption are simultaneously
* available. But presumably, the API is supposed to support cabinets which
* are split across multiple CDROMS; we may need to change our implementation
- * to strictly serialize it's file usage so that it opens only one cabinet
+ * to strictly serialize its file usage so that it opens only one cabinet
* at a time. Some experimentation with Windows is needed to figure out the
* precise semantics required. The relevant code is here and in fdi_decomp().
*/
* if we imagine parallelized access to the FDICopy API.
*
* The current implementation punts -- it just returns the previous cabinet and
- * it's info from the header of this cabinet. This provides the right answer in
- * 95% of the cases; its worth checking if Microsoft cuts the same corner before
+ * its info from the header of this cabinet. This provides the right answer in
+ * 95% of the cases; it's worth checking if Microsoft cuts the same corner before
* we "fix" it.
*/
ZeroMemory(&fdin, sizeof(FDINOTIFICATION));
fdin.psz2 = (CAB(mii).prevname) ? CAB(mii).prevname : &emptystring;
fdin.psz3 = (CAB(mii).previnfo) ? CAB(mii).previnfo : &emptystring;
- if (((*pfnfdin)(fdintPARTIAL_FILE, &fdin))) {
+ if (pfnfdin(fdintPARTIAL_FILE, &fdin) == -1) {
set_error( fdi, FDIERROR_USER_ABORT, 0 );
goto bail_and_fail;
}
fdin.date = file->date;
fdin.time = file->time;
fdin.attribs = file->attribs;
+ fdin.iFolder = file->index;
if ((filehf = ((*pfnfdin)(fdintCOPY_FILE, &fdin))) == -1) {
set_error( fdi, FDIERROR_USER_ABORT, 0 );
filehf = 0;
fdin.date = file->date;
fdin.time = file->time;
fdin.attribs = file->attribs; /* FIXME: filter _A_EXEC? */
+ fdin.iFolder = file->index;
((*pfnfdin)(fdintCLOSE_FILE_INFO, &fdin));
filehf = 0;