ReactOS 0.4.15-dev-7788-g1ad9096
extrac32.c
Go to the documentation of this file.
1/*
2 * Extract - Wine-compatible program for extract *.cab files.
3 *
4 * Copyright 2007 Etersoft (Lyutin Anatoly)
5 * Copyright 2009 Ilya Shpigor
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 */
21
22#include <windows.h>
23#include <shellapi.h>
24#include <setupapi.h>
25#include <shlwapi.h>
26#include <shlobj.h>
27
28#include "wine/unicode.h"
29#include "wine/debug.h"
30
32
35
37{
39 int res;
40
42 *PathFindFileNameW(dir) = 0; /* Truncate file name */
44 {
47 WINE_ERR("Can't create directory: %s\n", wine_dbgstr_w(dir));
48 }
49}
50
52{
54 FILEPATHS_W *pFilePaths;
55
56 switch(Notification)
57 {
59 pInfo = (FILE_IN_CABINET_INFO_W*)Param1;
60 if(show_content)
61 {
62 FILETIME ft;
63 SYSTEMTIME st;
64 CHAR date[12], time[12], buf[2 * MAX_PATH];
65 int count;
67
68 /* DosDate and DosTime already represented at local time */
69 DosDateTimeToFileTime(pInfo->DosDate, pInfo->DosTime, &ft);
70 FileTimeToSystemTime(&ft, &st);
71 GetDateFormatA(0, 0, &st, "MM'-'dd'-'yyyy", date, sizeof date);
72 GetTimeFormatA(0, 0, &st, "HH':'mm':'ss", time, sizeof time);
73 count = wsprintfA(buf, "%s %s %c%c%c%c %15u %S\n", date, time,
74 pInfo->DosAttribs & FILE_ATTRIBUTE_ARCHIVE ? 'A' : '-',
75 pInfo->DosAttribs & FILE_ATTRIBUTE_HIDDEN ? 'H' : '-',
76 pInfo->DosAttribs & FILE_ATTRIBUTE_READONLY ? 'R' : '-',
77 pInfo->DosAttribs & FILE_ATTRIBUTE_SYSTEM ? 'S' : '-',
78 pInfo->FileSize, pInfo->NameInCabinet);
80 return FILEOP_SKIP;
81 }
82 else
83 {
86 /* SetupIterateCabinet() doesn't create full path to target by itself,
87 so we should do it manually */
89 return FILEOP_DOIT;
90 }
92 pFilePaths = (FILEPATHS_W*)Param1;
93 WINE_TRACE("Extracted %s\n", wine_dbgstr_w(pFilePaths->Target));
94 return NO_ERROR;
95 }
96 return NO_ERROR;
97}
98
99static void extract(LPCWSTR cabfile, LPWSTR destdir)
100{
101 if (!SetupIterateCabinetW(cabfile, 0, ExtCabCallback, destdir))
102 WINE_ERR("Could not extract cab file %s\n", wine_dbgstr_w(cabfile));
103}
104
105static void copy_file(LPCWSTR source, LPCWSTR destination)
106{
107 WCHAR destfile[MAX_PATH];
108
109 /* append source filename if destination is a directory */
110 if (PathIsDirectoryW(destination))
111 {
112 PathCombineW(destfile, destination, PathFindFileNameW(source));
113 destination = destfile;
114 }
115
116 if (PathFileExistsW(destination) && !force_mode)
117 {
118 static const WCHAR overwriteMsg[] = {'O','v','e','r','w','r','i','t','e',' ','"','%','s','"','?',0};
119 static const WCHAR titleMsg[] = {'E','x','t','r','a','c','t',0};
120 WCHAR msg[MAX_PATH+100];
121 snprintfW(msg, ARRAY_SIZE(msg), overwriteMsg, destination);
122 if (MessageBoxW(NULL, msg, titleMsg, MB_YESNO | MB_ICONWARNING) != IDYES)
123 return;
124 }
125
126 WINE_TRACE("copying %s to %s\n", wine_dbgstr_w(source), wine_dbgstr_w(destination));
127 CopyFileW(source, destination, FALSE);
128}
129
131{
132 enum {OUTSIDE_ARG, INSIDE_ARG, INSIDE_QUOTED_ARG} state;
133 LPWSTR str;
134 int argc;
135 LPWSTR *argv;
136 int max_argc = 16;
137 BOOL new_arg;
138
139 WINE_TRACE("cmdline: %s\n", wine_dbgstr_w(cmdline));
140 str = HeapAlloc(GetProcessHeap(), 0, (strlenW(cmdline) + 1) * sizeof(WCHAR));
141 if(!str) return NULL;
143 argv = HeapAlloc(GetProcessHeap(), 0, (max_argc + 1) * sizeof(LPWSTR));
144 if(!argv)
145 {
147 return NULL;
148 }
149
150 /* Split command line to separate arg-strings and fill argv */
151 state = OUTSIDE_ARG;
152 argc = 0;
153 while(*str)
154 {
155 new_arg = FALSE;
156 /* Check character */
157 if(isspaceW(*str)) /* white space */
158 {
159 if(state == INSIDE_ARG)
160 {
161 state = OUTSIDE_ARG;
162 *str = 0;
163 }
164 }
165 else if(*str == '"') /* double quote */
166 switch(state)
167 {
168 case INSIDE_QUOTED_ARG:
169 state = OUTSIDE_ARG;
170 *str = 0;
171 break;
172 case INSIDE_ARG:
173 *str = 0;
174 /* Fall through */
175 case OUTSIDE_ARG:
176 if(!*++str) continue;
177 state = INSIDE_QUOTED_ARG;
178 new_arg = TRUE;
179 break;
180 }
181 else /* regular character */
182 if(state == OUTSIDE_ARG)
183 {
184 state = INSIDE_ARG;
185 new_arg = TRUE;
186 }
187
188 /* Add new argv entry, if need */
189 if(new_arg)
190 {
191 if(argc >= max_argc - 1)
192 {
193 /* Realloc argv here because there always should be
194 at least one reserved cell for terminating NULL */
195 max_argc *= 2;
197 (max_argc + 1) * sizeof(LPWSTR));
198 if(!argv)
199 {
201 return NULL;
202 }
203 }
204 argv[argc++] = str;
205 }
206
207 str++;
208 }
209
210 argv[argc] = NULL;
211 *pargc = argc;
212
213 if(TRACE_ON(extrac32))
214 {
215 int i;
216 for(i = 0; i < argc; i++)
217 WINE_TRACE("arg %d: %s\n", i, wine_dbgstr_w(argv[i]));
218 }
219 return argv;
220}
221
223{
224 LPWSTR *argv;
225 int argc;
226 int i;
227 WCHAR check, cmd = 0;
229 LPCWSTR cabfile = NULL;
230
231 path[0] = 0;
232
233 /* Do not use CommandLineToArgvW() or __wgetmainargs() to parse
234 * command line for this program. It should treat each quote as argument
235 * delimiter. This doesn't match with behavior of mentioned functions.
236 * Do not use args provided by wmain() for the same reason.
237 */
239
240 if(!argv)
241 {
242 WINE_ERR("Command line parsing failed\n");
243 return 0;
244 }
245
246 /* Parse arguments */
247 for(i = 0; i < argc; i++)
248 {
249 /* Get cabfile */
250 if (argv[i][0] != '/' && argv[i][0] != '-')
251 {
252 if (!cabfile)
253 {
254 cabfile = argv[i];
255 continue;
256 } else
257 break;
258 }
259 /* Get parameters for commands */
260 check = toupperW( argv[i][1] );
261 switch(check)
262 {
263 case 'A':
264 WINE_FIXME("/A not implemented\n");
265 break;
266 case 'Y':
268 break;
269 case 'L':
270 if ((i + 1) >= argc) return 0;
272 return 0;
273 break;
274 case 'C':
275 case 'E':
276 case 'D':
277 if (cmd) return 0;
278 cmd = check;
279 break;
280 default:
281 return 0;
282 }
283 }
284
285 if (!cabfile)
286 return 0;
287
288 if (cmd == 'C')
289 {
290 if ((i + 1) != argc) return 0;
292 return 0;
293 }
294 else if (!cmd)
295 /* Use extraction by default if names of required files presents */
296 cmd = i < argc ? 'E' : 'D';
297
298 if (cmd == 'E' && !path[0])
300
302
303 /* Execute the specified command */
304 switch(cmd)
305 {
306 case 'C':
307 /* Copy file */
308 copy_file(cabfile, path);
309 break;
310 case 'D':
311 /* Display CAB archive */
313 /* Fall through */
314 case 'E':
315 /* Extract CAB archive */
316 extract(cabfile, path);
317 break;
318 }
319 return 0;
320}
static int argc
Definition: ServiceArgs.c:12
static int state
Definition: maze.c:121
unsigned int dir
Definition: maze.c:112
#define msg(x)
Definition: auth_time.c:54
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define ARRAY_SIZE(A)
Definition: main.h:33
HANDLE WINAPI GetStdHandle(IN DWORD nStdHandle)
Definition: console.c:203
HINSTANCE hInstance
Definition: charmap.c:19
#define NO_ERROR
Definition: dderror.h:5
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define GetProcessHeap()
Definition: compat.h:736
#define GetCurrentDirectoryW(x, y)
Definition: compat.h:756
#define HeapAlloc
Definition: compat.h:733
#define HeapReAlloc
Definition: compat.h:734
#define TRACE_ON(x)
Definition: compat.h:75
#define MAX_PATH
Definition: compat.h:34
#define HeapFree(x, y, z)
Definition: compat.h:735
#define lstrcpyW
Definition: compat.h:749
BOOL WINAPI CopyFileW(IN LPCWSTR lpExistingFileName, IN LPCWSTR lpNewFileName, IN BOOL bFailIfExists)
Definition: copy.c:439
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
DWORD WINAPI GetFullPathNameW(IN LPCWSTR lpFileName, IN DWORD nBufferLength, OUT LPWSTR lpBuffer, OUT LPWSTR *lpFilePart)
Definition: path.c:1106
BOOL WINAPI FileTimeToSystemTime(IN CONST FILETIME *lpFileTime, OUT LPSYSTEMTIME lpSystemTime)
Definition: time.c:188
BOOL WINAPI DosDateTimeToFileTime(IN WORD wFatDate, IN WORD wFatTime, OUT LPFILETIME lpFileTime)
Definition: time.c:75
BOOL WINAPI SetupIterateCabinetW(PCWSTR CabinetFile, DWORD Reserved, PSP_FILE_CALLBACK_W MsgHandler, PVOID Context)
Definition: setupcab.c:575
LPWSTR WINAPI PathFindFileNameW(LPCWSTR lpszPath)
Definition: path.c:394
BOOL WINAPI PathFileExistsW(LPCWSTR lpszPath)
Definition: path.c:1777
BOOL WINAPI PathIsDirectoryW(LPCWSTR lpszPath)
Definition: path.c:1723
#define check(expected, result)
Definition: dplayx.c:32
static UINT WINAPI ExtCabCallback(PVOID Context, UINT Notification, UINT_PTR Param1, UINT_PTR Param2)
Definition: extrac32.c:51
static BOOL force_mode
Definition: extrac32.c:33
static void create_target_directory(LPWSTR Target)
Definition: extrac32.c:36
static void extract(LPCWSTR cabfile, LPWSTR destdir)
Definition: extrac32.c:99
static LPWSTR * get_extrac_args(LPWSTR cmdline, int *pargc)
Definition: extrac32.c:130
int PASCAL wWinMain(HINSTANCE hInstance, HINSTANCE prev, LPWSTR cmdline, int show)
Definition: extrac32.c:222
static BOOL show_content
Definition: extrac32.c:34
static void copy_file(LPCWSTR source, LPCWSTR destination)
Definition: extrac32.c:105
#define FILEOP_SKIP
Definition: fileqsup.h:49
#define FILEOP_DOIT
Definition: fileqsup.h:48
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLuint res
Definition: glext.h:9613
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define wine_dbgstr_w
Definition: kernel32.h:34
INT WINAPI GetTimeFormatA(LCID lcid, DWORD dwFlags, const SYSTEMTIME *lpTime, LPCSTR lpFormat, LPSTR lpTimeStr, INT cchOut)
Definition: lcformat.c:1044
INT WINAPI GetDateFormatA(LCID lcid, DWORD dwFlags, const SYSTEMTIME *lpTime, LPCSTR lpFormat, LPSTR lpDateStr, INT cchOut)
Definition: lcformat.c:936
LPWSTR WINAPI lstrcatW(LPWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:274
__u16 date
Definition: mkdosfs.c:8
__u16 time
Definition: mkdosfs.c:8
#define ERROR_ALREADY_EXISTS
Definition: disk.h:80
#define argv
Definition: mplay32.c:18
unsigned __int3264 UINT_PTR
Definition: mstsclib_h.h:274
unsigned int UINT
Definition: ndis.h:50
#define FILE_ATTRIBUTE_READONLY
Definition: nt_native.h:702
#define FILE_ATTRIBUTE_HIDDEN
Definition: nt_native.h:703
#define FILE_ATTRIBUTE_SYSTEM
Definition: nt_native.h:704
#define FILE_ATTRIBUTE_ARCHIVE
Definition: nt_native.h:706
#define PathCombineW
Definition: pathcch.h:317
#define PathAddBackslashW
Definition: pathcch.h:301
#define toupperW(n)
Definition: unicode.h:45
#define strlenW(s)
Definition: unicode.h:28
#define isspaceW(n)
Definition: unicode.h:52
#define snprintfW
Definition: unicode.h:60
#define strcpyW(d, s)
Definition: unicode.h:29
const WCHAR * str
#define WINE_TRACE
Definition: debug.h:354
#define WINE_FIXME
Definition: debug.h:366
#define WINE_ERR
Definition: debug.h:371
#define SPFILENOTIFY_FILEEXTRACTED
Definition: setupapi.h:564
#define SPFILENOTIFY_FILEINCABINET
Definition: setupapi.h:562
int WINAPI SHCreateDirectoryExW(HWND hWnd, LPCWSTR path, LPSECURITY_ATTRIBUTES sec)
Definition: shlfileop.cpp:905
TCHAR * cmdline
Definition: stretchblt.cpp:32
PCWSTR Target
Definition: fileqsup.h:60
WCHAR FullTargetName[MAX_PATH]
Definition: setupapi.h:804
Definition: ftp_var.h:139
_In_ PWDFDEVICE_INIT _In_ PFN_WDF_DEVICE_SHUTDOWN_NOTIFICATION Notification
Definition: wdfcontrol.h:115
_In_ WDFIOTARGET Target
Definition: wdfrequest.h:306
#define STD_OUTPUT_HANDLE
Definition: winbase.h:268
#define PASCAL
Definition: windef.h:133
#define WINAPI
Definition: msvc.h:6
#define MB_YESNO
Definition: winuser.h:817
int WINAPI MessageBoxW(_In_opt_ HWND hWnd, _In_opt_ LPCWSTR lpText, _In_opt_ LPCWSTR lpCaption, _In_ UINT uType)
int WINAPIV wsprintfA(_Out_ LPSTR, _In_ _Printf_format_string_ LPCSTR,...)
#define MB_ICONWARNING
Definition: winuser.h:786
#define IDYES
Definition: winuser.h:835
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
char CHAR
Definition: xmlstorage.h:175