1 rizwank 1.1 /*
2 * Unit test suite for cabinet.dll - FDI functions
3 *
4 * Copyright 2004 Rizwan Kassim, Dan Kegel
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21 #include <stdlib.h>
22 rizwank 1.1
23 #ifndef STANDALONE
24 #include <wine/test.h>
25 #define ok2 ok
26 #else
27 /* To build outside Wine tree, compile with cl -DSTANDALONE -D_X86_ cabinet_fdi.c FDI.lib
28 These are only called if standalone are used, defining ok and START_TEST, which would normally be declared in winetree */
29 #include <assert.h>
30 #include <stdio.h>
31 #define START_TEST(name) main(int argc, char **argv)
32 #define ok(condition, msg) \
33 do { if(!(condition)) { \
34 fprintf(stderr,"failed at %d, msg:" msg "\n",__LINE__); \
35 exit(1); \
36 } } while(0)
37 #define ok2(condition, msg, arg) \
38 do { if(!(condition)) { \
39 fprintf(stderr,"failed at %d, msg:" msg "\n",__LINE__, arg); \
40 exit(1); \
41 } } while(0)
42 #define todo_wine
43 rizwank 1.1 #endif
44
45 #include <winerror.h>
46 #include <fdi.h>
|
47 rizwank 1.7 #include <fcntl.h>
48
|
49 rizwank 1.8 /* Do malloc and free output debug messages?
50 #define DEBUG_ALLOC
51 */
|
52 rizwank 1.7
|
53 rizwank 1.8 /* What is our "Fake" Filedescriptor? */
54 static int fakeFD = 22881;
|
55 rizwank 1.7
|
56 rizwank 1.8 /*
57 This hex data is the output of compress.exe (Windows Server 2003 Resource Kit)
58
59 The cab file is mirrored in the file system as simple.cab
60
61 The 'test.txt' in the cab file contains the string 'So long, and thanks for all the fish.'
62 */
|
63 rizwank 1.7 static unsigned char compressed_file[] =
64 {0x4D,0x53,0x43,0x46,0x00,0x00,0x00,0x00,0x75,0x00,
65 0x00,0x00,0x00,0x00,0x00,0x00,0x2C,0x00,0x00,0x00,
66 0x00,0x00,0x00,0x00,0x03,0x01,0x01,0x00,0x01,0x00,
67 0x00,0x00,0x39,0x30,0x00,0x00,0x45,0x00,0x00,0x00,
68 0x01,0x00,0x01,0x00,0x26,0x00,0x00,0x00,0x00,0x00,
69 0x00,0x00,0x00,0x00,0x4A,0x32,0xB2,0xBE,0x20,0x00,
70 0x74,0x65,0x73,0x74,0x2E,0x74,0x78,0x74,0x00,0x9C,
71 0x74,0xD0,0x75,0x28,0x00,0x26,0x00,0x43,0x4B,0x0B,
72 0xCE,0x57,0xC8,0xC9,0xCF,0x4B,0xD7,0x51,0x48,0xCC,
73 0x4B,0x51,0x28,0xC9,0x48,0xCC,0xCB,0x2E,0x56,0x48,
74 0xCB,0x2F,0x52,0x48,0xCC,0xC9,0x01,0x72,0x53,0x15,
75 0xD2,0x32,0x8B,0x33,0xF4,0xB8,0x00};
76 static int szcompressed_file = sizeof(compressed_file);
77
|
78 rizwank 1.8
|
79 rizwank 1.7 /*
80 static const char uncompressed_data[] = "This is a test file.";
81 static const DWORD uncompressed_data_size = sizeof(uncompressed_data) - 1;
82
83 static char *buf;
84 */
|
85 rizwank 1.1
|
86 rizwank 1.8 /*
87 To do in FDI: -from wine/include/fdi.h
|
88 rizwank 1.1 FDICreate
89 File Write -FNWRITE(hf, pv, cb)
90 File Seek -FNSEEK(hf,dist,seektype)
91 Error Structure
92 FDICopy
93 Notification function
94 Decryption function
95 FDIDestroy
96 */
97
|
98 rizwank 1.5 /* Currently mostly dummy function pointers */
|
99 rizwank 1.1
|
100 rizwank 1.8 #ifndef DEBUG_ALLOC
101 FNALLOC(final_alloc) {
102 return malloc(cb);
103 }
104 FNFREE(final_free) {
105 free(pv);
106 return;
107 }
108 #else
109 FNALLOC(final_alloc) {
|
110 rizwank 1.5 printf(" FNALLOC just called with %d\n",cb);
111 return malloc(cb);
|
112 rizwank 1.3 }
|
113 rizwank 1.8 FNFREE(final_free) {
|
114 rizwank 1.5 printf(" FNFREE just called with %d\n",pv);
115 free(pv);
|
116 rizwank 1.3 return;
117 }
|
118 rizwank 1.8 #endif
119
|
120 rizwank 1.3
|
121 rizwank 1.5 /*
|
122 rizwank 1.7 It is not necessary for these functions to actually call _open etc.;
123 these functions could instead call fopen, fread, fwrite, fclose, and fseek,
124 or CreateFile, ReadFile, WriteFile, CloseHandle, and SetFilePointer, etc.
125 However, the parameters and return codes will have to be translated
126 appropriately (e.g. the file open mode passed in to pfnopen).
127
128 Match i/o specs of _open, _read, _write, _close, and _lseek.
129
130 */
131
132 /*
|
133 rizwank 1.8 http://msdn.microsoft.com/library/en-us/vclib/html/_crt__open.2c_._wopen.asp
|
134 rizwank 1.7 _open I: const char *filename, int oflag, int pmode O: int (handler), -1 for err.
|
135 rizwank 1.8 DUMMY : FUNCTIONAL FAKE : FUNCTIONAL REAL : FUNCTIONAL
|
136 rizwank 1.5 */
137
|
138 rizwank 1.3 FNOPEN(dummy_open) {
|
139 rizwank 1.8 printf(" FNOPEN (dummy) just called with %d, %d, %d\n",pszFile, oflag, pmode);
|
140 rizwank 1.3 return 0;
141 }
142
|
143 rizwank 1.7 FNOPEN(fake_open) {
|
144 rizwank 1.8 printf(" FNOPEN (fake) just called with %d, %d, %d\n",pszFile, oflag, pmode);
145 printf(" Returning %d as file descriptor\n",fakeFD);
|
146 rizwank 1.7 return 12;
147 }
148
149 FNOPEN(real_open) {
150 int handler = _open(pszFile,oflag,pmode);
151 printf(" FNOPEN (real) just called with %s, %d, %d\n",pszFile, oflag, pmode);
152 printf(" FNOPEN (real) returning handler (%d)\n",handler);
153 return handler;
154 }
155
156 /*
|
157 rizwank 1.8 http://msdn.microsoft.com/library/en-us/vclib/html/_CRT__read.asp
|
158 rizwank 1.7 _read I: int fd, void *buffer, unsigned int count O: int (szBuffer)
|
159 rizwank 1.8 DUMMY : FUNCTIONAL FAKE : FUNCTIONAL, INCOMPLETE REAL : FUNCTIONAL
|
160 rizwank 1.7 */
161
|
162 rizwank 1.3 FNREAD(dummy_read) {
|
163 rizwank 1.8 printf(" FNREAD (dummy) just called with %d, %d, %d\n",hf, pv, cb);
|
164 rizwank 1.5 return 0;
|
165 rizwank 1.3 }
|
166 rizwank 1.7
|
167 rizwank 1.8 /* Doesn't keep virtual file location pointer */
|
168 rizwank 1.7 FNREAD(fake_read) {
|
169 rizwank 1.8 printf(" FNREAD (fake) just called with %d, %d, %d\n",hf, pv, cb);
170 if (hf == fakeFD) {
171 printf (" Called with fake file descriptor, populating buffer and size (%d)\n",cb);
172 memcpy (pv, compressed_file ,cb);
173 }
174 else {
175 printf (" FNREAD (fake) was called with the unknown file handler. Failed!\n",hf);
176 }
177 return cb;
|
178 rizwank 1.7 }
179
180 FNREAD(real_read) {
181 int szBuffer = _read(hf,pv,cb);
182 printf(" FNREAD (read) just called with %d, %d, %d\n",hf, pv, cb);
183 printf(" FNREAD (read) returning size (%d)\n",szBuffer);
184 return szBuffer;
185 }
186
|
187 rizwank 1.8 /*
188 http://msdn.microsoft.com/library/en-us/vclib/html/_CRT__close.asp
189 _close I: int fd O: int (0=success 1=failure)
190 DUMMY : FUNCTIONAL FAKE : FUNCTIONAL REAL : FUNCTIONAL
191 */
|
192 rizwank 1.7
|
193 rizwank 1.8 FNCLOSE(dummy_close) {
194 printf(" FNCLOSE (dummy) just called with %d - returning %d\n",hf,0);
|
195 rizwank 1.5 return 0;
|
196 rizwank 1.3 }
197
|
198 rizwank 1.8 FNCLOSE(fake_close) {
199 printf(" FNCLOSE (fake) just called with %d - returning %d\n",hf,0);
200 return 0;
201 }
|
202 rizwank 1.3
|
203 rizwank 1.8 FNCLOSE(real_close) {
204 int closevalue = _close(hf);
205 printf(" FNCLOSE (real) just called with %d - returning %d\n",hf,closevalue);
206 return closevalue;
207 }
208
209
210 FNWRITE(dummy_write) {
211 printf(" FNWRITE just called with %d, %d, %d\n",hf, pv, cb);
|
212 rizwank 1.5 return 0;
|
213 rizwank 1.3 }
|
214 rizwank 1.1
|
215 rizwank 1.3 FNSEEK(dummy_seek) {
|
216 rizwank 1.8 printf(" FNSEEK just called with %d, %d, %d\n",hf, dist, seektype);
|
217 rizwank 1.5 return 0;
|
218 rizwank 1.3 }
219
|
220 rizwank 1.7 HFDI hfdi_unknown_dummy, hfdi_unknown_fake,hfdi_unknown_real;
|
221 rizwank 1.4 /* yes its global and ugly */
222
|
223 rizwank 1.1
|
224 rizwank 1.4 static void TestCreate(void) {
225
226 ERF error_structure;
227
228 printf("Starting TestCreate()\n");
229
|
230 rizwank 1.7 hfdi_unknown_dummy = FDICreate(
|
231 rizwank 1.8 final_alloc,
232 final_free,
|
233 rizwank 1.5 dummy_open,
234 dummy_read,
235 dummy_write,
236 dummy_close,
237 dummy_seek,
238 cpuUNKNOWN,
239 &error_structure
240 );
|
241 rizwank 1.7 ok(hfdi_unknown_dummy != NULL,"FDICreate (CPU = unknown) (functions=dummy) failed!\n");
242
243 hfdi_unknown_fake = FDICreate(
|
244 rizwank 1.8 final_alloc,
245 final_free,
|
246 rizwank 1.7 fake_open,
247 fake_read,
248 dummy_write,
249 dummy_close,
250 dummy_seek,
251 cpuUNKNOWN,
252 &error_structure
253 );
254 ok(hfdi_unknown_fake != NULL,"FDICreate (CPU = unknown) (functions=fake) failed!\n");
255
256 hfdi_unknown_real = FDICreate(
|
257 rizwank 1.8 final_alloc,
258 final_free,
|
259 rizwank 1.7 real_open,
260 real_read,
261 dummy_write,
|
262 rizwank 1.8 real_close,
|
263 rizwank 1.7 dummy_seek,
264 cpuUNKNOWN,
265 &error_structure
266 );
267 ok(hfdi_unknown_real != NULL,"FDICreate (CPU = unknown) (functions=real) failed!\n");
268
269 printf("Ending TestCreate()\n");
270 }
271
272 static void TestInfo(void) {
|
273 rizwank 1.8 /* Noticed Behavior :
274 FDIIsCabinet does not open the file on its own, it requires a file open/close to be done externally.
275 WHY?
276 The only functions in HFDI that FDIIsCabinet directly accesses is FNREAD
277 Important cases to check :
278 If the filedescriptor == ERR, does it FAIL? (dummy_read)
279 If the filedescriptor == NOTCABINET, does it FAIL? (fake_read, real_read)
280 If the filedescriptor == CABINET, does it SUCCEED? (fake_read, real_read)
281 If the filedescriptor == CABINET, does it populate FDICABINETINFO? (fake_read, real_read)
282 */
283
|
284 rizwank 1.7 int realfd;
285 int sizer;
|
286 rizwank 1.8 FDICABINETINFO fdi_cabinfo_dummy, fdi_cabinfo_simple, fdi_cabinfo_complex;
|
287 rizwank 1.7
288 printf("Starting TestInfo()\n");
|
289 rizwank 1.8
290 /* TEST : ERR filehandle associated, dummy functions should return FALSE */
291 ok ( FDIIsCabinet( hfdi_unknown_dummy, -1, &fdi_cabinfo_dummy) == FALSE,
|
292 rizwank 1.7 "FDIIsCabinet (File = Error) failed!\n");
|
293 rizwank 1.8
294 /* TEST : Fake filehandle associated, memory manually copied, should return TRUE */
295 ok ( FDIIsCabinet( hfdi_unknown_fake, fakeFD, &fdi_cabinfo_simple) == TRUE,
296 "FDIIsCabinet (FakeFile = Cabinet) failed!\n");
297
298 ok ( fdi_cabinfo_simple.cbCabinet == 117, "FDIIsCabinet,cabinfo (FakeFile = Cabinet) data did not match! Failed!\n");
299 ok ( fdi_cabinfo_simple.cFolders == 1, "FDIIsCabinet,cabinfo (FakeFile = Cabinet) data did not match! Failed!\n");
300 ok ( fdi_cabinfo_simple.cFiles == 1, "FDIIsCabinet,cabinfo (FakeFile = Cabinet) data did not match! Failed!\n");
301 ok ( fdi_cabinfo_simple.setID == 12345, "FDIIsCabinet,cabinfo (FakeFile = Cabinet) data did not match! Failed!\n");
302 ok ( fdi_cabinfo_simple.iCabinet == 0, "FDIIsCabinet,cabinfo (FakeFile = Cabinet) data did not match! Failed!\n");
303 ok ( fdi_cabinfo_simple.fReserve == 'b', "FDIIsCabinet,cabinfo (FakeFile = Cabinet) data did not match! Failed!\n");
304 ok ( fdi_cabinfo_simple.hasprev == 117, "FDIIsCabinet,cabinfo (FakeFile = Cabinet) data did not match! Failed!\n");
305 ok ( fdi_cabinfo_simple.hasnext == 117, "FDIIsCabinet,cabinfo (FakeFile = Cabinet) data did not match! Failed!\n");
306
307 realfd = real_open( "working.cab" , _O_BINARY | _O_RDONLY | _O_SEQUENTIAL, 0);
308 ok ( FDIIsCabinet( hfdi_unknown_real, realfd, &fdi_cabinfo_complex) == TRUE,
|
309 rizwank 1.7 "FDIIsCabinet (File = Cabinet) failed!\n");
|
310 rizwank 1.8 real_close(realfd);
|
311 rizwank 1.7
|
312 rizwank 1.8 printf("Cabinet Data : cbC %d cF %d cFi %d si %d iC %d fr %b hp %d hn %d\n,",
313 fdi_cabinfo_complex.cbCabinet,
314 fdi_cabinfo_complex.cFolders ,
315 fdi_cabinfo_complex.cFiles ,
316 fdi_cabinfo_complex.setID,
317 fdi_cabinfo_complex.iCabinet,
318 fdi_cabinfo_complex.fReserve ,
319 fdi_cabinfo_complex.hasprev ,
320 fdi_cabinfo_complex.hasnext );
|
321 rizwank 1.7
322 }
323
324
325 static void TestDestroy(void) {
326 printf("Starting TestDestroy()\n");
327 /* Only two things to check in FDIDestroy
|
328 rizwank 1.8 1=> Does it return T if its passed an hfdi
329 2=> Does it return F if its passed a non hfdi
330 EDIT : Causes GPL if FDIDestroy is called on an invalid pointer.
|
331 rizwank 1.7 ok( 0 == FDIDestroy(0), "Return true incorrectly in TestDestroy()!\n");
332 */
333
334 ok(FDIDestroy(hfdi_unknown_dummy), "FDIDestroy (CPU = unknown) (functions=fake) failed!\n");
335 ok(FDIDestroy(hfdi_unknown_fake), "FDIDestroy (CPU = unknown) (functions=fake) failed!\n");
336 printf("Ending TestDestroy()\n");
|
337 rizwank 1.5
|
338 rizwank 1.4 }
|
339 rizwank 1.1
|
340 rizwank 1.7
|
341 rizwank 1.1 START_TEST(paths)
342 {
|
343 rizwank 1.4
344 TestCreate();
|
345 rizwank 1.7 TestInfo();
|
346 rizwank 1.2 /*
347 TestCopy();
|
348 rizwank 1.3 */
|
349 rizwank 1.2 TestDestroy();
|
350 rizwank 1.3
|
351 rizwank 1.1 }
|