(file) Return to TESTFDI.C CVS log (file) (dir) Up to [RizwankCVS] / group3 / wine / dlls / cabinet / tests

  1 rizwank 1.1 /*
  2              * testfdi.c
  3              *
  4              * Demonstrates how to use the FDI library APIs
  5              */
  6             #include <windows.h>
  7             #include <stdio.h>
  8             #include <stdlib.h>
  9             #include <string.h>
 10             #include <io.h>
 11             #include <fcntl.h>
 12             #include <dos.h>
 13             #include <sys/stat.h>
 14             
 15             #include "c:\temp\user\cab\include\fdi.h"
 16             
 17             
 18             /*
 19              * Function prototypes 
 20              */
 21             BOOL	test_fdi(char *cabinet_file);
 22 rizwank 1.1 int		get_percentage(unsigned long a, unsigned long b);
 23             char   *return_fdi_error_string(FDIERROR err);
 24             
 25             
 26             /*
 27              * Destination directory for extracted files
 28              */
 29             char	dest_dir[256];
 30             
 31             
 32             void main(int argc, char **argv)
 33             {
 34             	if (argc != 3)
 35             	{
 36             		printf(
 37             			"TESTFDI - Demonstrates how to use the FDI library API calls\n"
 38             			"\n"
 39             			"Usage: TESTFDI cabinet dest_dir\n"
 40             			"\n"       
 41             			"Where <cabinet> is the name of a cabinet file, and <dest_dir>\n"
 42             			"is the destination for the files extracted\n"
 43 rizwank 1.1 			"\n"
 44             			"  e.g. testfdi c:\\test1.cab c:\\\n"
 45             			"\n"
 46             		);
 47             
 48             		exit(0);
 49             	}
 50             
 51             	strcpy(dest_dir, argv[2]);
 52             
 53             	if (test_fdi(argv[1]) == TRUE)
 54             		printf("TESTFDI was successful\n");
 55             	else
 56             		printf("TESTFDI failed\n");
 57             
 58             	exit(0);
 59             }
 60             
 61             
 62             /*
 63              * Memory allocation function
 64 rizwank 1.1  */
 65             FNALLOC(mem_alloc)
 66             {
 67             	return malloc(cb);
 68             }
 69             
 70             
 71             /*
 72              * Memory free function
 73              */
 74             FNFREE(mem_free)
 75             {
 76             	free(pv);
 77             }
 78             
 79             
 80             FNOPEN(file_open)
 81             {
 82             	return _open(pszFile, oflag, pmode);
 83             }
 84             
 85 rizwank 1.1 
 86             FNREAD(file_read)
 87             {
 88             	return _read(hf, pv, cb);
 89             }
 90             
 91             
 92             FNWRITE(file_write)
 93             {
 94             	return _write(hf, pv, cb);
 95             }
 96             
 97             
 98             FNCLOSE(file_close)
 99             {
100             	return _close(hf);
101             }
102             
103             
104             FNSEEK(file_seek)
105             {
106 rizwank 1.1 	return _lseek(hf, dist, seektype);
107             }
108             
109             
110             FNFDINOTIFY(notification_function)
111             {
112             	switch (fdint)
113             	{
114             		case fdintCABINET_INFO: // general information about the cabinet
115             			printf(
116             				"fdintCABINET_INFO\n"
117             				"  next cabinet     = %s\n"
118             				"  next disk        = %s\n"
119             				"  cabinet path     = %s\n"
120             				"  cabinet set ID   = %d\n"
121             				"  cabinet # in set = %d (zero based)\n"
122             				"\n",
123             				pfdin->psz1,
124             				pfdin->psz2,
125             				pfdin->psz3,
126             				pfdin->setID,
127 rizwank 1.1 				pfdin->iCabinet
128             			);
129             
130             			return 0;
131             
132             		case fdintPARTIAL_FILE: // first file in cabinet is continuation
133             			printf(
134             				"fdintPARTIAL_FILE\n"
135             				"   name of continued file            = %s\n"
136             				"   name of cabinet where file starts = %s\n"
137             				"   name of disk where file starts    = %s\n",
138             				pfdin->psz1,
139             				pfdin->psz2,
140             				pfdin->psz3
141             			);
142             			return 0;
143             
144             		case fdintCOPY_FILE:	// file to be copied
145             		{
146             			int		response;
147             			int		handle;
148 rizwank 1.1 			char	destination[256];
149             
150             			printf(
151             				"fdintCOPY_FILE\n"
152             				"  file name in cabinet = %s\n"
153             				"  uncompressed file size = %d\n"
154             				"  copy this file? (y/n): ",
155             				pfdin->psz1,
156             				pfdin->cb
157             			);
158             
159             			do
160             			{
161             				response = getc(stdin);
162             				response = toupper(response);
163             			} while (response != 'Y' && response != 'N');
164             
165             			printf("\n");
166             
167             			if (response == 'Y')
168             			{
169 rizwank 1.1 				sprintf(
170             					destination, 
171             					"%s%s",
172             					dest_dir,
173             					pfdin->psz1
174             				);
175             
176             				handle = file_open(
177             					destination,
178             					_O_BINARY | _O_CREAT | _O_WRONLY | _O_SEQUENTIAL,
179             					_S_IREAD | _S_IWRITE 
180             				);
181             
182             				return handle;
183             			}
184             			else
185             			{
186             				return 0; /* skip file */
187             			}
188             		}
189             
190 rizwank 1.1 		case fdintCLOSE_FILE_INFO:	// close the file, set relevant info
191                     {
192                         HANDLE  handle;
193                         DWORD   attrs;
194                         char    destination[256];
195             
196              			printf(
197             				"fdintCLOSE_FILE_INFO\n"
198             				"   file name in cabinet = %s\n"
199             				"\n",
200             				pfdin->psz1
201             			);
202             
203                         sprintf(
204                             destination, 
205                             "%s%s",
206                             dest_dir,
207                             pfdin->psz1
208                         );
209             
210             			file_close(pfdin->hf);
211 rizwank 1.1 
212             
213                         /*
214                          * Set date/time
215                          *
216                          * Need Win32 type handle for to set date/time
217                          */
218                         handle = CreateFile(
219                             destination,
220                             GENERIC_READ | GENERIC_WRITE,
221                             FILE_SHARE_READ,
222                             NULL,
223                             OPEN_EXISTING,
224                             FILE_ATTRIBUTE_NORMAL,
225                             NULL
226                         );
227             
228                         if (handle != INVALID_HANDLE_VALUE)
229                         {
230                             FILETIME    datetime;
231             
232 rizwank 1.1                 if (TRUE == DosDateTimeToFileTime(
233                                 pfdin->date,
234                                 pfdin->time,
235                                 &datetime))
236                             {
237                                 FILETIME    local_filetime;
238             
239                                 if (TRUE == LocalFileTimeToFileTime(
240                                     &datetime,
241                                     &local_filetime))
242                                 {
243                                     (void) SetFileTime(
244                                         handle,
245                                         &local_filetime,
246                                         NULL,
247                                         &local_filetime
248                                     );
249                                  }
250                             }
251             
252                             CloseHandle(handle);
253 rizwank 1.1             }
254             
255                         /*
256                          * Mask out attribute bits other than readonly,
257                          * hidden, system, and archive, since the other
258                          * attribute bits are reserved for use by
259                          * the cabinet format.
260                          */
261                         attrs = pfdin->attribs;
262             
263                         attrs &= (_A_RDONLY | _A_HIDDEN | _A_SYSTEM | _A_ARCH);
264             
265                         (void) SetFileAttributes(
266                             destination,
267                             attrs
268                         );
269             
270             			return TRUE;
271                     }
272             
273             		case fdintNEXT_CABINET:	// file continued to next cabinet
274 rizwank 1.1 			printf(
275             				"fdintNEXT_CABINET\n"
276             				"   name of next cabinet where file continued = %s\n"
277                             "   name of next disk where file continued    = %s\n"
278             				"   cabinet path name                         = %s\n"
279             				"\n",
280             				pfdin->psz1,
281             				pfdin->psz2,
282             				pfdin->psz3
283             			);
284             			return 0;
285             	}
286             
287             	return 0;
288             }
289             
290             
291             BOOL test_fdi(char *cabinet_fullpath)
292             {
293             	HFDI			hfdi;
294             	ERF				erf;
295 rizwank 1.1 	FDICABINETINFO	fdici;
296             	int				hf;
297             	char			*p;
298             	char			cabinet_name[256];
299             	char			cabinet_path[256];
300             
301             	hfdi = FDICreate(
302             		mem_alloc,
303             		mem_free,
304             		file_open,
305             		file_read,
306             		file_write,
307             		file_close,
308             		file_seek,
309             		cpu80386,
310             		&erf
311             	);
312             
313             	if (hfdi == NULL)
314             	{
315             		printf("FDICreate() failed: code %d [%s]\n",
316 rizwank 1.1 			erf.erfOper, return_fdi_error_string(erf.erfOper)
317             		);
318             
319             		return FALSE;
320             	}
321             
322             
323             	/*
324             	 * Is this file really a cabinet?
325             	 */
326             	hf = file_open(
327             		cabinet_fullpath,
328             		_O_BINARY | _O_RDONLY | _O_SEQUENTIAL,
329             		0
330             	);
331             
332             	if (hf == -1)
333             	{
334             		(void) FDIDestroy(hfdi);
335             
336             		printf("Unable to open '%s' for input\n", cabinet_fullpath);
337 rizwank 1.1 		return FALSE;
338             	}
339             
340             	if (FALSE == FDIIsCabinet(
341             			hfdi,
342             			hf,
343             			&fdici))
344             	{
345             		/*
346             		 * No, it's not a cabinet!
347             		 */
348             		_close(hf);
349             
350             		printf(
351             			"FDIIsCabinet() failed: '%s' is not a cabinet\n",
352             			cabinet_fullpath
353             		);
354             
355             		(void) FDIDestroy(hfdi);
356             		return FALSE;
357             	}
358 rizwank 1.1 	else
359             	{
360             		_close(hf);
361             
362             		printf(
363             			"Information on cabinet file '%s'\n"
364             			"   Total length of cabinet file : %d\n"
365             			"   Number of folders in cabinet : %d\n"
366             			"   Number of files in cabinet   : %d\n"
367             			"   Cabinet set ID               : %d\n"
368             			"   Cabinet number in set        : %d\n"
369             			"   RESERVE area in cabinet?     : %s\n"
370             			"   Chained to prev cabinet?     : %s\n"
371             			"   Chained to next cabinet?     : %s\n"
372             			"\n",
373             			cabinet_fullpath,
374             			fdici.cbCabinet,
375             			fdici.cFolders,
376             			fdici.cFiles,
377             			fdici.setID,
378             			fdici.iCabinet,
379 rizwank 1.1 			fdici.fReserve == TRUE ? "yes" : "no",
380             			fdici.hasprev == TRUE ? "yes" : "no",
381             			fdici.hasnext == TRUE ? "yes" : "no"
382             		);
383             	}
384             
385             	p = strrchr(cabinet_fullpath, '\\');
386             
387             	if (p == NULL)
388             	{
389             		strcpy(cabinet_name, cabinet_fullpath);
390             		strcpy(cabinet_path, "");
391             	}
392             	else
393             	{
394             		strcpy(cabinet_name, p+1);
395             
396             		strncpy(cabinet_path, cabinet_fullpath, (int) (p-cabinet_fullpath)+1);
397             		cabinet_path[ (int) (p-cabinet_fullpath)+1 ] = 0;
398             	}
399             
400 rizwank 1.1 	if (TRUE != FDICopy(
401             		hfdi,
402             		cabinet_name,
403             		cabinet_path,
404             		0,
405             		notification_function,
406             		NULL,
407             		NULL))
408             	{
409             		printf(
410             			"FDICopy() failed: code %d [%s]\n",
411             			erf.erfOper, return_fdi_error_string(erf.erfOper)
412             		);
413             
414             		(void) FDIDestroy(hfdi);
415             		return FALSE;
416             	}
417             
418             	if (FDIDestroy(hfdi) != TRUE)
419             	{
420             		printf(
421 rizwank 1.1 			"FDIDestroy() failed: code %d [%s]\n",
422             			erf.erfOper, return_fdi_error_string(erf.erfOper)
423             		);
424             
425             		return FALSE;
426             	}
427             
428             	return TRUE;
429             }
430             
431             
432             char *return_fdi_error_string(FDIERROR err)
433             {
434             	switch (err)
435             	{
436             		case FDIERROR_NONE:
437             			return "No error";
438             
439             		case FDIERROR_CABINET_NOT_FOUND:
440             			return "Cabinet not found";
441             			
442 rizwank 1.1 		case FDIERROR_NOT_A_CABINET:
443             			return "Not a cabinet";
444             			
445             		case FDIERROR_UNKNOWN_CABINET_VERSION:
446             			return "Unknown cabinet version";
447             			
448             		case FDIERROR_CORRUPT_CABINET:
449             			return "Corrupt cabinet";
450             			
451             		case FDIERROR_ALLOC_FAIL:
452             			return "Memory allocation failed";
453             			
454             		case FDIERROR_BAD_COMPR_TYPE:
455             			return "Unknown compression type";
456             			
457             		case FDIERROR_MDI_FAIL:
458             			return "Failure decompressing data";
459             			
460             		case FDIERROR_TARGET_FILE:
461             			return "Failure writing to target file";
462             			
463 rizwank 1.1 		case FDIERROR_RESERVE_MISMATCH:
464             			return "Cabinets in set have different RESERVE sizes";
465             			
466             		case FDIERROR_WRONG_CABINET:
467             			return "Cabinet returned on fdintNEXT_CABINET is incorrect";
468             			
469             		case FDIERROR_USER_ABORT:
470             			return "User aborted";
471             			
472             		default:
473             			return "Unknown error";
474             	}
475             }

Rizwan Kassim
Powered by
ViewCVS 0.9.2