diff -Nuar oldwine/configure.ac wine/configure.ac --- oldwine/configure.ac 2005-03-05 03:19:14.000000000 -0800 +++ wine/configure.ac 2005-03-16 02:09:50.750000000 -0800 @@ -1519,6 +1519,7 @@ dlls/avicap32/Makefile dlls/avifil32/Makefile dlls/cabinet/Makefile +dlls/cabinet/tests/Makefile dlls/capi2032/Makefile dlls/cards/Makefile dlls/cfgmgr32/Makefile diff -Nuar oldwine/dlls/cabinet/Makefile.in wine/dlls/cabinet/Makefile.in --- oldwine/dlls/cabinet/Makefile.in 2003-12-31 10:56:07.000000000 -0800 +++ wine/dlls/cabinet/Makefile.in 2005-03-16 02:10:47.718750000 -0800 @@ -12,7 +12,7 @@ fdi.c RC_SRCS = cabinet.rc - +SUBDIRS = tests @MAKE_DLL_RULES@ ### Dependencies: diff -Naur oldwine/dlls/cabinet/tests/Makefile.in wine/dlls/cabinet/tests/Makefile.in --- oldwine/dlls/cabinet/tests/Makefile.in Wed Dec 31 16:00:00 1969 +++ wine/dlls/cabinet/tests/Makefile.in Wed May 11 10:28:31 2005 @@ -0,0 +1,16 @@ +TOPSRCDIR = @top_srcdir@ +TOPOBJDIR = ../../.. +SRCDIR = @srcdir@ +VPATH = @srcdir@ +TESTDLL = cabinet.dll +IMPORTS = kernel32 cabinet + +RC_SRCS = cabinet.rc + +CTESTS = \ + tvfs.c \ + cabinet_fdi.c + +@MAKE_TEST_RULES@ + +### Dependencies: diff -Naur oldwine/dlls/cabinet/tests/cabinet_fdi.c wine/dlls/cabinet/tests/cabinet_fdi.c --- oldwine/dlls/cabinet/tests/cabinet_fdi.c Wed Dec 31 16:00:00 1969 +++ wine/dlls/cabinet/tests/cabinet_fdi.c Wed May 11 14:20:35 2005 @@ -0,0 +1,321 @@ +/* + * Unit test suite for cabinet.dll - FDI functions + * + * Copyright 2005 Rizwan Kassim, Dan Kegel, Alexander Liber, Thomas Kho + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* posix includes */ +#include +#include +#include +#include +#include +#include + +/* windows includes */ +#include +#include +#include +#include + +/* our own private includes */ +#include "tvfs.h" +#include "simplecab.h" + +/* To build outside Wine tree, compile with + cl -DSTANDALONE -D_X86_ cabinet_fdi.c tvfs.c FDI.lib +*/ +#ifdef STANDALONE +#include "standalone.h" +#else +#include +/* wine/test.h defines a varadic function ok(), but + * standalone.h defines one version of ok() for each number of parameters. + * Define ok2, etc. so we can compile with either wine/test.h or standalone.h. + */ +#define ok2 ok /* ok(condition, format, arg) */ +#define ok3 ok /* ok(condition, format, arg1, arg2) */ +#endif + +/* We'd like to build with either cl or winegcc, so let's use the unix + * names for open flags, and provide a dummy definition of flags + * unix doesn't support + */ +#ifndef O_BINARY +#define O_BINARY 0 +#endif +#ifndef O_CREAT +#define O_CREAT _O_CREAT +#define O_WRONLY _O_WRONLY +#endif +/* ditto for stat */ +#ifndef S_IREAD +#define S_IREAD _S_IREAD +#define S_IWRITE _S_IWRITE +#endif + +/* what kind of failure to inject, if any */ +enum TestType { TT_NORMAL, TT_FULL_DISK, TT_NO_FILE }; + +/* Define callback functions to pass as arguments to FDICreate. + * Use the whacky macros FNALLOC() etc. from to make sure we get + * parameter types right. + * Wrap malloc and free solely to avoid compiler warnings. + */ +FNALLOC(my_malloc) { + return malloc(cb); +} + +FNFREE(my_free) { + free(pv); +} + +FNFDINOTIFY(notification_function) +{ + switch (fdint) + { + case fdintCOPY_FILE: + { + /* Called by FDICopy to open output file */ + return tvfs_open (pfdin->psz1, + O_BINARY | O_CREAT | O_WRONLY, + S_IREAD | S_IWRITE ); + } + case fdintCLOSE_FILE_INFO: + { + tvfs_close(pfdin->hf); + return TRUE; + } + } + return 0; +} + +static TestConstant() +{ + trace("TestConstant\n"); + ok(FDIERROR_CABINET_NOT_FOUND==1,"FDIERROR_CABINET_NOT_FOUND is incorrect!\n"); + ok(FDIERROR_NOT_A_CABINET==2,"FDIERROR_NOT_A_CABINET is incorrect!\n"); + ok(FDIERROR_CORRUPT_CABINET==4,"FDIERROR_CORRUPT_CABINET is incorrect!\n"); + ok(FDIERROR_TARGET_FILE==8,"FDIERROR_TARGET_FILE is incorrect!\n"); + ok(fdintCABINET_INFO==0,"fdintCABINET_INFO is incorrect!\n"); + ok(fdintPARTIAL_FILE==1,"fdintPARTIAL_FILE is incorrect!\n"); + ok(fdintCOPY_FILE==2,"fdintCOPY_FILE is incorrect!\n"); + ok(fdintCLOSE_FILE_INFO==3,"fdintCLOSE_FILE_INFO is incorrect!\n"); + ok(fdintNEXT_CABINET==4,"fdintNEXT_CABINET is incorrect!\n"); + ok(fdintENUMERATE==5,"fdintENUMERATE is incorrect!\n"); +} + + +/* Copy TestSimple into a seperate block of code for each new cabinet being tested, possibly removing modes 1,2*/ +/* mode=0 - standard work. mode=1 simulates write fail. mode=2 simulates missing cabinet. */ +static void TestSimple(enum TestType mode) +{ + int result, fd; + FDICABINETINFO fdi_cabinfo_simple; + static HFDI hfdi_simple; + ERF error_structure; + + trace("TestSimple: * mode %d\n",mode); + + switch (mode) { + case TT_NORMAL: + hfdi_simple = FDICreate( + my_malloc, my_free, tvfs_open, tvfs_read, tvfs_write, tvfs_close, tvfs_lseek, cpuUNKNOWN, &error_structure); + break; + case TT_FULL_DISK: + hfdi_simple = FDICreate( + my_malloc, my_free, tvfs_open, tvfs_read, tvfs_write_full, tvfs_close, tvfs_lseek, cpuUNKNOWN, &error_structure); + break; + case TT_NO_FILE: + hfdi_simple = FDICreate( + my_malloc, my_free, tvfs_open_missing, tvfs_read, tvfs_write, tvfs_close, tvfs_lseek, cpuUNKNOWN, &error_structure); + break; + } + + ok2(hfdi_simple != NULL,"FDICreate failed! erfOper=%d\n",error_structure.erfOper); + + tvfs_create( name_simple_cab, file_simple_cab, size_simple_cab); + fd = tvfs_open( name_simple_cab, O_RDONLY|O_BINARY, 0 ); + /* Create virtual cabinet and open it - Modes 0,1,2 */ + + ok( FDIIsCabinet( hfdi_simple, fd, &fdi_cabinfo_simple) == TRUE, + "FDIIsCabinet failed!\n"); + /* Check that is is recognized as a cabinet file - Modes 0,1,2 */ + + ok3( fdi_cabinfo_simple.cbCabinet == size_simple_cab, + "cbCabinet is wrong, is %d, should be %d.\n", + fdi_cabinfo_simple.cbCabinet, size_simple_cab); + ok2( fdi_cabinfo_simple.cFolders == 1, "cFolders is wrong, is %d, should be 1.\n", fdi_cabinfo_simple.cFolders ); + ok2( fdi_cabinfo_simple.cFiles == 1, "cFiles is wrong, is %d, should be 1.\n", fdi_cabinfo_simple.cFiles ); + ok2( fdi_cabinfo_simple.setID == 0, "setID is wrong, is %d, should be 0.\n", fdi_cabinfo_simple.setID ); + ok2( fdi_cabinfo_simple.iCabinet == 0, "iCabinet is wrong, is %d, should be 0.\n", fdi_cabinfo_simple.iCabinet ); + ok2( fdi_cabinfo_simple.fReserve == 0, "fReserve is wrong, is %d, should be 0.\n", fdi_cabinfo_simple.fReserve ); + ok2( fdi_cabinfo_simple.hasprev == 0, "hasprev is wrong, is %d, should be 0.\n", fdi_cabinfo_simple.hasprev ); + ok2( fdi_cabinfo_simple.hasnext == 0, "hasnext is wrong, is %d, should be 0.\n", fdi_cabinfo_simple.hasnext ); + /* Check all the fields of the Cabinet Info struct for validity - Modes 0,1,2 */ + + tvfs_close(fd); + /* close the file handler - Modes 0,1,2 */ + + FDICopy(hfdi_simple, "simple.cab", "", 0, notification_function, NULL,NULL); + switch (mode) { + case TT_NORMAL: + result = tvfs_compare(name_simple_txt, file_simple_txt, size_simple_txt); + ok2( result == 0, "File %s compare failed!\n",name_simple_txt); + break; + case TT_FULL_DISK: + ok3( error_structure.erfOper == FDIERROR_TARGET_FILE, + "erfOper is wrong, is %d, should be %d.\n", + error_structure.erfOper, FDIERROR_TARGET_FILE); + break; + case TT_NO_FILE: + ok3( error_structure.erfOper == FDIERROR_CABINET_NOT_FOUND, + "erfOper is wrong, is %d, should be %d.\n", + error_structure.erfOper, FDIERROR_CABINET_NOT_FOUND); + break; + } + /* Check that file(s) were extracted correctly - Mode 0 */ + /* Check that it was recognized as 'no space to write' - Mode 1 */ + /* Check that it was recognized as 'cabinet not found' - Mode 2 */ + + ok(FDIDestroy(hfdi_simple), "FDIDestroy failed!\n"); + + tvfs_free(); +} + +static void TestCorrupt(void) +{ + int result, fd; + FDICABINETINFO fdi_cabinfo_corrupt; + static HFDI hfdi_corrupt; + ERF error_structure; + const char *name_corrupt_cab = "corrupt.cab"; + static char file_corrupt_cab[65536]; + int size_corrupt_cab = sizeof(file_simple_cab); + +/* This cabinet is a copy of simple.cab, with a few bytes modified to make it an invalid cabinet file. + The copy is created dynamically to avoid code bloat. The memcpy call and 'corruption' occurs in cabinet_fdi.c + This cabinet is _specifically designed_ to pass FDIIsCabinet but fail on extraction */ + trace("TestCorrupt\n"); + + /* SPECIAL TO CORRUPT.CAB -- copies simple.cab and corrupts it */ + memcpy(file_corrupt_cab,file_simple_cab,size_simple_cab); + file_corrupt_cab[50]=0xFF; + file_corrupt_cab[100]=0xFF; + + hfdi_corrupt = FDICreate( + my_malloc, + my_free, + tvfs_open, tvfs_read, tvfs_write, tvfs_close, tvfs_lseek, + cpuUNKNOWN, + &error_structure + ); + + ok2(hfdi_corrupt != NULL,"FDICreate failed! erfOper=%d\n",error_structure.erfOper); + + tvfs_create( name_corrupt_cab, file_corrupt_cab, size_corrupt_cab); + fd = tvfs_open( (char *) name_corrupt_cab, O_RDONLY|O_BINARY, 0 ); + /* Create virtual cabinet and open it */ + + ok( FDIIsCabinet( hfdi_corrupt, fd, &fdi_cabinfo_corrupt) == TRUE, + "FDIIsCabinet failed!\n"); + /* Check that is is recognized as a cabinet file */ + + ok3( fdi_cabinfo_corrupt.cbCabinet == size_corrupt_cab, + "cbCabinet is wrong, is %d, should be %d.\n", + fdi_cabinfo_corrupt.cbCabinet, size_corrupt_cab); + ok2( fdi_cabinfo_corrupt.cFolders == 1, "cFolders is wrong, is %d, should be 1.\n", fdi_cabinfo_corrupt.cFolders ); + ok2( fdi_cabinfo_corrupt.cFiles == 1, "cFiles is wrong, is %d, should be 1.\n", fdi_cabinfo_corrupt.cFiles ); + ok2( fdi_cabinfo_corrupt.setID == 0, "setID is wrong, is %d, should be 0.\n", fdi_cabinfo_corrupt.setID ); + ok2( fdi_cabinfo_corrupt.iCabinet == 0, "iCabinet is wrong, is %d, should be 0.\n", fdi_cabinfo_corrupt.iCabinet ); + ok2( fdi_cabinfo_corrupt.fReserve == 0, "fReserve is wrong, is %d, should be 0.\n", fdi_cabinfo_corrupt.fReserve ); + ok2( fdi_cabinfo_corrupt.hasprev == 0, "hasprev is wrong, is %d, should be 0.\n", fdi_cabinfo_corrupt.hasprev ); + ok2( fdi_cabinfo_corrupt.hasnext == 0, "hasnext is wrong, is %d, should be 0.\n", fdi_cabinfo_corrupt.hasnext ); + /* Check all the fields of the Cabinet Info struct for validity */ + + tvfs_close(fd); + /* close the file handler */ + + FDICopy(hfdi_corrupt, + "corrupt.cab", + "", + 0, + notification_function, + NULL, + NULL); + ok2( error_structure.erfOper == FDIERROR_CORRUPT_CABINET, "erfOper is wrong, is %d, should be 4.\n", error_structure.erfOper); + + result = tvfs_compare(name_simple_txt, file_simple_txt, size_simple_txt); + ok2( result, "Wrote %s from a corrupt cabinet - incorrect behavior!\n",name_simple_txt); + + ok(FDIDestroy(hfdi_corrupt), "FDIDestroy failed!\n"); + + tvfs_free(); +} + +static void TestNotACab(void) +{ + int result, fd; + FDICABINETINFO fdi_cabinfo_notacab; + static HFDI hfdi_notacab; + ERF error_structure; + + trace("TestNotACab\n"); + + hfdi_notacab = FDICreate( + my_malloc, + my_free, + tvfs_open, tvfs_read, tvfs_write, tvfs_close, tvfs_lseek, + cpuUNKNOWN, + &error_structure + ); + + ok2(hfdi_notacab != NULL,"FDICreate failed! erfOper=%d\n",error_structure.erfOper); + + tvfs_create( name_simple_txt, file_simple_txt, size_simple_txt); + fd = tvfs_open( name_simple_txt, O_RDONLY|O_BINARY, 0 ); + /* Create virtual cabinet and open it */ + + ok( FDIIsCabinet( hfdi_notacab, fd, &fdi_cabinfo_notacab) == FALSE, + "FDIIsCabinet failed!\n"); + /* Check that is is recognized as a FALSE cabinet file */ + + FDICopy(hfdi_notacab, + "simple.txt", + "", + 0, + notification_function, + NULL, + NULL); + ok3( error_structure.erfOper == FDIERROR_NOT_A_CABINET, + "erfOper is wrong, is %d, should be %d.\n", + error_structure.erfOper, FDIERROR_NOT_A_CABINET); + + ok(FDIDestroy(hfdi_notacab), "FDIDestroy failed!\n"); + + tvfs_free(); +} + +START_TEST(cabinet_fdi) +{ + TestConstant(); + TestSimple(TT_NORMAL); + TestSimple(TT_FULL_DISK); + TestSimple(TT_NO_FILE); + TestCorrupt(); + TestNotACab(); +} diff -Naur oldwine/dlls/cabinet/tests/genfiles.sh wine/dlls/cabinet/tests/genfiles.sh --- oldwine/dlls/cabinet/tests/genfiles.sh Wed Dec 31 16:00:00 1969 +++ wine/dlls/cabinet/tests/genfiles.sh Wed May 11 10:28:31 2005 @@ -0,0 +1,33 @@ +#!/bin/sh +# Generate test archives using cabarc.exe (Windows Cabinet SDK/bin) +# This is run just once, and generates the file cabinet_files.h, +# which is then checked into CVS forever. +# It is here just in case we want to add more test files later. +# Copyright 2005 Dan Kegel, Rizwan Kassim; LGPL + +# remove "wine" before command calls if you're running on Windows + +set -ex + +# First, get cabinet SDK +# You might need to download it by hand from ttp://support.microsoft.com/?id=310618 +test -f cabsdk.exe || wget -c http://download.microsoft.com/download/platformsdk/cab/2.0/w98nt42kmexp/en-us/cabsdk.exe + +# unpack it (handily, it's a zip file) +mkdir cabsdk +cd cabsdk +unzip ../cabsdk.exe +cd .. +chmod 744 cabsdk/BIN/CABARC.EXE + +# Simple archive, just one 42 byte file +echo 'So long, and thanks for all the fish.....' > simple.txt +wine cabsdk/BIN/CABARC.EXE N simple.cab simple.txt + +# Blow away cabinet SDK +rm -rf cabsdk + +# Pack source files and archives into hex arrays +perl ../../../tools/chexify.pl simple.txt txt simple.cab > simplecab.h + +rm -fr simple.cab diff -Naur oldwine/dlls/cabinet/tests/simplecab.h wine/dlls/cabinet/tests/simplecab.h --- oldwine/dlls/cabinet/tests/simplecab.h Wed Dec 31 16:00:00 1969 +++ wine/dlls/cabinet/tests/simplecab.h Wed May 11 10:28:31 2005 @@ -0,0 +1,21 @@ +static char name_simple_txt[] = "simple.txt"; +static char file_simple_txt[] = { + 0x53, 0x6f, 0x20, 0x6c, 0x6f, 0x6e, 0x67, 0x2c, 0x20, 0x61, 0x6e, 0x64, 0x20, 0x74, 0x68, 0x61, + 0x6e, 0x6b, 0x73, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x61, 0x6c, 0x6c, 0x20, 0x74, 0x68, 0x65, 0x20, + 0x66, 0x69, 0x73, 0x68, 0x2e, 0x2e, 0x2e, 0x2e, 0x2e, 0x0a +}; +static int size_simple_txt = sizeof(file_simple_txt); + + +static char name_simple_cab[] = "simple.cab"; +static char file_simple_cab[] = { + 0x4d, 0x53, 0x43, 0x46, 0x00, 0x00, 0x00, 0x00, 0x79, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x47, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x2a, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5b, 0x32, 0x0c, 0x0c, 0x20, 0x00, 0x73, 0x69, 0x6d, 0x70, + 0x6c, 0x65, 0x2e, 0x74, 0x78, 0x74, 0x00, 0x9e, 0x7f, 0x24, 0xf5, 0x2a, 0x00, 0x2a, 0x00, 0x43, + 0x4b, 0x0b, 0xce, 0x57, 0xc8, 0xc9, 0xcf, 0x4b, 0xd7, 0x51, 0x48, 0xcc, 0x4b, 0x51, 0x28, 0xc9, + 0x48, 0xcc, 0xcb, 0x2e, 0x56, 0x48, 0xcb, 0x2f, 0x52, 0x48, 0xcc, 0xc9, 0x01, 0x72, 0x53, 0x15, + 0xd2, 0x32, 0x8b, 0x33, 0xf4, 0x40, 0x80, 0x0b, 0x00 +}; +static int size_simple_cab = sizeof(file_simple_cab); diff -Naur oldwine/dlls/cabinet/tests/standalone.h wine/dlls/cabinet/tests/standalone.h --- oldwine/dlls/cabinet/tests/standalone.h Wed Dec 31 16:00:00 1969 +++ wine/dlls/cabinet/tests/standalone.h Wed May 11 13:31:24 2005 @@ -0,0 +1,49 @@ +/* Lightweight version of wine/test.h for use when compiling tests + * outside the wine source tree + * + * Implements ok(condition, fmt, ...) in a hacky way, by + * defining one version per possible number of parameters. + * Implements a no-op version of todo_wine. + * Implements a hacky version of START_TEST(). + * Implements trace() properly. + */ + +#include +#include +#include + +#define START_TEST(name) main(int argc, char **argv) + +/* If you haven't seen the do ... while (0) idiom before, + * it's the only way in C to do a multi-statement macro + * that acts like a single statement. This is important + * for when the macro is invoked inside an if without braces. + */ + +#define ok(condition, msg) \ + do { if(!(condition)) { \ + fprintf(stderr,"failed at %d, msg:" msg "\n",__LINE__); \ + exit(1); \ + } } while(0) + +#define ok2(condition, msg, arg) \ + do { if(!(condition)) { \ + fprintf(stderr,"failed at %d, msg:" msg "\n",__LINE__, arg); \ + exit(1); \ + } } while(0) + +#define ok3(condition, msg, arg1, arg2) \ + do { if(!(condition)) { \ + fprintf(stderr,"failed at %d, msg:" msg "\n",__LINE__, arg1, arg2); \ + exit(1); \ + } } while(0) + +#define todo_wine + +static void trace(const char *s, ...) +{ + va_list ellipsis; + va_start (ellipsis, s); + vprintf(s, ellipsis); + va_end(ellipsis); +} diff -Naur oldwine/dlls/cabinet/tests/tvfs.c wine/dlls/cabinet/tests/tvfs.c --- oldwine/dlls/cabinet/tests/tvfs.c Wed Dec 31 16:00:00 1969 +++ wine/dlls/cabinet/tests/tvfs.c Wed May 11 13:05:04 2005 @@ -0,0 +1,336 @@ +/*-------------------------------------------------------------------------- +Trivial virtual file system for cabinet conformance test. +(C) 2005 Dan Kegel and Rizwan Kassim +LGPL License +--------------------------------------------------------------------------*/ + +#include "tvfs.h" +#include + +#define MAXFILES 20 +#define MAXHANDLES 20 +#define MAXFNAME 255 +#define MAXFLEN 65536*2 + +#include +#include +#include +#include +#include +#include + +#ifndef _O_BINARY +#define _O_BINARY 0 +#endif + +/* +#define TVFS_MAIN +*/ +#include + +#ifndef STANDALONE +#include "wine/test.h" +#define ok2 ok +#else +#include "standalone.h" +#undef START_TEST +#endif + +struct tvfs_file { + char fname[MAXFNAME]; + int bytes_used; + char buf[MAXFLEN]; +}; +static struct tvfs_file *files[MAXFILES]; + +struct tvfs_fcb { + int pos; + int inode; +}; +static struct tvfs_fcb *handles[MAXHANDLES]; + +int nhandles = 0; +int nfiles = 0; + +/* tvfs_create does NOT correspond to _creat - it is an internal function +use to put a file directly into our virtual file system. */ + +int tvfs_create(const char *fname, const char *buf, int len) +{ + int inode; + struct tvfs_file *f; + +/* trace("tvfs_create called with %s, %d, %d\n", fname, buf, len); */ + + if (nfiles >= MAXFILES) + return -1; + inode = nfiles++; + + f = malloc(sizeof(struct tvfs_file)); + strcpy(f->fname, fname); + f->bytes_used = len; + + if (buf) + memcpy(f->buf, buf, len); + + files[inode] = f; + return inode; +} + +int tvfs_open(char *fname, int flags, int mode) +{ + /* mode and flags are not handled */ + int h; + int inode; + struct tvfs_fcb *handler; + +/* trace("tvfs_open called with %s, %d, %d\n", fname, flags, mode); */ + + /* Existing file? */ + for (inode=0; inodefname, fname)) + break; + } + + if (inode == nfiles) { + /* File did not exist */ + if ((flags & O_CREAT) == 0) { + /* ENOENT */ + trace("tvfs_open returning -1\n"); + return -1; + } + + inode = tvfs_create(fname, 0, 0); + } + + handler = malloc(sizeof(struct tvfs_fcb)); + handler->inode = inode; + handler->pos=0; + h = nhandles++; + handles[h] = handler; + +/* trace("tvfs_open returning with %d\n", h); */ + + return h; +} + +int tvfs_open_missing(char *fname, int flags, int mode) +{ + /* fake, 'file not found' */ + errno = ENOENT; + return -1; +} + +unsigned int tvfs_read(int h, void *buf, unsigned int len) +{ + int inode = handles[h]->inode; + int pos = handles[h]->pos; + int size = files[inode]->bytes_used; + +/* trace("tvfs_read called with %d, %d, %d\n", h, buf, len); */ + + /* Edge Case 1 : Request beyond boundary of file */ + if (pos + len > size) { + len = size-pos; + } + + memcpy(buf, files[inode]->buf+pos, len); + handles[h]->pos += len; + + return len; +} + +void tvfs_free() +{ + int inode; + int handle; + +/* trace("tvfs_free\n"); */ + + nfiles=0; + nhandles=0; + + for (inode=0; inodefname, fname)) + break; + } + + if (inode == nfiles) { + /* File did not exist */ + return -1; + } + + return (memcmp(files[inode]->buf,buf,len)); + /* does not check for out of bound */ +} + +long tvfs_lseek(int h, long whence, int whither ) +{ + int inode = handles[h]->inode; + int size = files[inode]->bytes_used; +/* trace("tvfs_lseek called with %d, %d, %d\n", h, whither, whence); */ + +/* if (whence > size) + whence = size;*/ +/* Legit lseek does NOT do boundary checking */ + + switch(whither) { + case SEEK_SET: { + handles[h]->pos = whence; + break; + } + case SEEK_CUR: { + handles[h]->pos += whence; + break; + } + case SEEK_END: { + handles[h]->pos = size+whence; + break; + } + case 5: { + handles[h]->pos = size+whence; + break; + } + default: + { + trace("lseek was called with an invalid whither %d\n",whither); + return -1; + } + } + return handles[h]->pos; + } + +int tvfs_close(int h) +{ + int inode = handles[h]->inode; +/* trace("tvfs_close called with %d\n", h); */ + if (!files[inode]) { + return -1; + } + free(handles[h]); + /* Currently does NOT enabled open to reuse this handle */ + return 0; +} + +unsigned int tvfs_write(int h, void *buf, unsigned int len) +{ + int inode = handles[h]->inode; + int pos = handles[h]->pos; +/* trace("tvfs_write called with %d, %d, %d\n", h, buf, len); */ + memcpy(files[inode]->buf+pos, buf, len); + files[inode]->bytes_used += len; + handles[h]->pos += len; + + return len; + /* return -1 to simulate diskfull or some other error */ +} + +unsigned int tvfs_write_full(int h, void *buf, unsigned int len) +{ + errno = ENOSPC; + return -1; +} + + +START_TEST(tvfs){ + printf("dummy!"); +} + + +#ifdef TVFS_MAIN + +const static char name_test_txt[] = "test.txt"; +const static char file_test_txt[] = "This is a test. Don't Panic!"; +const static int size_test_txt = sizeof(file_test_txt); + +/* If TVFSMain is defined, this compiles a test of the TVFS suite */ +main() +{ + int result; + int active_handler; + + char *filebuf; + + char dummy_filename[] = "dummy.txt"; + char bad_filename[] = "chicken.txt"; + + filebuf = malloc(MAXFLEN); + + trace("Testing TVFS implementation, creating %s\n",name_test_txt); + result = tvfs_create( dummy_filename, file_test_txt, size_test_txt); + result = tvfs_create( name_test_txt, file_test_txt,size_test_txt); + trace("Created virtual file with inode %d\n",result); + + trace("Attempting to open non-existent file\n"); + result = tvfs_open(bad_filename, _O_BINARY, 0 ); + trace("Result code %d\n",result); + trace("Attempting to open existent file\n"); + result = tvfs_open(name_test_txt, _O_BINARY, 0 ); + trace("Result code %d\n",result); + + active_handler = result; + + memset (filebuf,0,MAXFLEN); + + trace("Testing reading from file %s\n",name_test_txt); + result = tvfs_read(active_handler, filebuf, 9); + trace("Read _%s_\n", filebuf); + if ( strcmp(filebuf,"This is a")) + trace("File read check failed!\n"); + + trace("Testing sequential reading from file %s\n",name_test_txt); + result = tvfs_read(active_handler, filebuf, 12); + trace("Read _%s_\n", filebuf); + if ( strcmp(filebuf," test. Don't")) + trace("File read check failed!\n"); + + trace("Testing edge reading from file %s\n",name_test_txt); + result = tvfs_read(active_handler, filebuf, 42); + trace("Read %d bytes - _%s_\n", result, filebuf); + if ( result != 8 ) + trace("File read check failed!\n"); + + trace("Testing direct file compare and lseek of %s\n", name_test_txt); + trace("Seeking to 0 (not needed) - "); + tvfs_lseek( active_handler, SEEK_SET, 0); + trace("Comparing file\n"); + result = tvfs_compare( name_test_txt , file_test_txt, size_test_txt); + if (result) + trace ("File compare failed!\n"); + + /* Does not test writing */ + + trace("Closing %s\n",name_test_txt); + tvfs_close(active_handler); + if (result) + trace ("File close failed!\n"); + + tvfs_free(); + free(filebuf); + +} + +#endif diff -Naur oldwine/dlls/cabinet/tests/tvfs.h wine/dlls/cabinet/tests/tvfs.h --- oldwine/dlls/cabinet/tests/tvfs.h Wed Dec 31 16:00:00 1969 +++ wine/dlls/cabinet/tests/tvfs.h Wed May 11 11:57:15 2005 @@ -0,0 +1,36 @@ +/*-------------------------------------------------------------------------- +Trivial virtual file system for cabinet conformance test. + +Provides versions of the filesystem calls needed by cabinet: +open, read, write, lseek, close. Each returns the same +return values as the corresponding _open, _read, _write, _lseek, _close +calls in Win32, i.e. on error, they return -1, +and on success, open returns a file handle, +read and write return # of bytes transferred, +seek returns the position, +and close returns 0. + +Also provides functions for creating whole files from binary arrays, +and comparing whole files to binary arrays. + +--------------------------------------------------------------------------*/ + +#ifndef tvfs_h +#define tvfs_h + +int tvfs_open(char *fname, int flags, int mode); +unsigned int tvfs_read(int h, void *buf, unsigned int len); +unsigned int tvfs_write(int h, void *buf, unsigned int len); +int tvfs_close(int h); +long tvfs_lseek(int h, long whence, int whither); + +/* Create given file with given contents, return inode number or -1 on fail */ +int tvfs_create(const char *fname, const char *buf, int len); + +/* Compare given file with given contents, return 0 on equal, else nonzero */ +int tvfs_compare(const char *fname, const char *buf, int len); + +void tvfs_free(); +int tvfs_open_missing(char *fname, int flags, int mode); +unsigned int tvfs_write_full(int h, void *buf, unsigned int len); +#endif