- fixme when unexpected children found
[wine] / dlls / cabinet / cabinet_main.c
1 /*
2  * cabinet.dll main
3  *
4  * Copyright 2002 Patrik Stridvall
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 "config.h"
22
23 #include <assert.h>
24 #include <stdarg.h>
25 #include <string.h>
26
27 #include "windef.h"
28 #include "winbase.h"
29 #include "winerror.h"
30 #define NO_SHLWAPI_REG
31 #include "shlwapi.h"
32 #undef NO_SHLWAPI_REG
33
34 #include "cabinet.h"
35
36 #include "wine/debug.h"
37
38 WINE_DEFAULT_DEBUG_CHANNEL(cabinet);
39
40 /***********************************************************************
41  * DllGetVersion (CABINET.2)
42  *
43  * Retrieves version information of the 'CABINET.DLL'
44  *
45  * PARAMS
46  *     pdvi [O] pointer to version information structure.
47  *
48  * RETURNS
49  *     Success: S_OK
50  *     Failure: E_INVALIDARG
51  *
52  * NOTES
53  *     Supposedly returns version from IE6SP1RP1
54  */
55 HRESULT WINAPI CABINET_DllGetVersion (DLLVERSIONINFO *pdvi)
56 {
57   WARN("hmmm... not right version number \"5.1.1106.1\"?\n");
58
59   if (pdvi->cbSize != sizeof(DLLVERSIONINFO)) return E_INVALIDARG;
60
61   pdvi->dwMajorVersion = 5;
62   pdvi->dwMinorVersion = 1;
63   pdvi->dwBuildNumber = 1106;
64   pdvi->dwPlatformID = 1;
65
66   return S_OK;
67 }
68
69 /***********************************************************************
70  * Extract (CABINET.3)
71  *
72  * Apparently an undocumented function, presumably to extract a CAB file
73  * to somewhere...
74  *
75  * PARAMS
76  *   dest         pointer to a buffer of 0x32c bytes containing
77  *           [I]  - number with value 1 at index 0x18
78  *                - the dest path starting at index 0x1c
79  *           [O]  - a linked list with the filename existing inside the
80  *                  CAB file at idx 0x10
81  *                - the number of files inside the CAB file at index 0x14
82  *                - the name of the last file with dest path at idx 0x120
83  *   what    [I]  char* describing what to uncompress, I guess.
84  *
85  * RETURNS
86  *     Success: S_OK
87  *     Failure: E_OUTOFMEMORY (?)
88  */
89 HRESULT WINAPI Extract(EXTRACTdest *dest, LPCSTR what)
90 {
91 #define DUMPC(idx)      idx >= sizeof(EXTRACTdest) ? ' ' : \
92                         ptr[idx] >= 0x20 ? ptr[idx] : '.'
93
94 #define DUMPH(idx)      idx >= sizeof(EXTRACTdest) ? 0x55 : ptr[idx]
95
96   LPSTR dir;
97   unsigned char *ptr = (unsigned char*) dest;
98   unsigned int i;
99
100   TRACE("(dest == %0lx, what == %s)\n", (long) dest, debugstr_a(what));
101
102   if (!dest) {
103     /* win2k will crash here */
104     FIXME("called without valid parameter dest!\n");
105     return E_OUTOFMEMORY;
106   }
107   for (i=0; i < sizeof(EXTRACTdest); i+=8)
108     TRACE( "dest[%04x]:%02x %02x %02x %02x %02x %02x %02x %02x %c%c%c%c%c%c%c%c\n",
109            i,
110            DUMPH(i+0), DUMPH(i+1), DUMPH(i+2), DUMPH(i+3),
111            DUMPH(i+4), DUMPH(i+5), DUMPH(i+6), DUMPH(i+7),
112            DUMPC(i+0), DUMPC(i+1), DUMPC(i+2), DUMPC(i+3),
113            DUMPC(i+4), DUMPC(i+5), DUMPC(i+6), DUMPC(i+7));
114
115   dir = LocalAlloc(LPTR, strlen(dest->directory)+1); 
116   if (!dir) return E_OUTOFMEMORY;
117   lstrcpyA(dir, dest->directory);
118   dest->filecount=0;
119   dest->filelist = NULL;
120
121   TRACE("extracting to dir: %s\n", debugstr_a(dir));
122
123   /* FIXME: what to do on failure? */
124   if (!process_cabinet(what, dir, FALSE, FALSE, dest)) {
125     LocalFree(dir);
126     return E_OUTOFMEMORY;
127   }
128
129   LocalFree(dir);
130
131   TRACE("filecount %08lx,lastfile %s\n",
132          dest->filecount, debugstr_a(dest->lastfile));
133
134   return S_OK;
135 }