winefile: Add the Romanian translation.
[wine] / programs / extrac32 / extrac32.c
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
27 #include "wine/unicode.h"
28 #include "wine/debug.h"
29
30 WINE_DEFAULT_DEBUG_CHANNEL(extrac32);
31
32 static BOOL force_mode;
33
34 static UINT WINAPI ExtCabCallback(PVOID Context, UINT Notification, UINT_PTR Param1, UINT_PTR Param2)
35 {
36     FILE_IN_CABINET_INFO_W *pInfo;
37     FILEPATHS_W *pFilePaths;
38
39     switch(Notification)
40     {
41         case SPFILENOTIFY_FILEINCABINET:
42             pInfo = (FILE_IN_CABINET_INFO_W*)Param1;
43             lstrcpyW(pInfo->FullTargetName, (LPCWSTR)Context);
44             lstrcatW(pInfo->FullTargetName, pInfo->NameInCabinet);
45             return FILEOP_DOIT;
46         case SPFILENOTIFY_FILEEXTRACTED:
47             pFilePaths = (FILEPATHS_W*)Param1;
48             WINE_TRACE("Extracted %s\n", wine_dbgstr_w(pFilePaths->Target));
49             return NO_ERROR;
50     }
51     return NO_ERROR;
52 }
53
54 static void extract(LPCWSTR cabfile, LPWSTR destdir)
55 {
56     if (!SetupIterateCabinetW(cabfile, 0, ExtCabCallback, destdir))
57         WINE_ERR("Could not extract cab file %s\n", wine_dbgstr_w(cabfile));
58 }
59
60 static void copy_file(LPCWSTR source, LPCWSTR destination)
61 {
62     WCHAR destfile[MAX_PATH];
63
64     /* append source filename if destination is a directory */
65     if (PathIsDirectoryW(destination))
66     {
67         PathCombineW(destfile, destination, PathFindFileNameW(source));
68         destination = destfile;
69     }
70
71     if (PathFileExistsW(destination) && !force_mode)
72     {
73         static const WCHAR overwriteMsg[] = {'O','v','e','r','w','r','i','t','e',' ','"','%','s','"','?',0};
74         static const WCHAR titleMsg[] = {'E','x','t','r','a','c','t',0};
75         WCHAR msg[MAX_PATH+100];
76         snprintfW(msg, sizeof(msg)/sizeof(msg[0]), overwriteMsg, destination);
77         if (MessageBoxW(NULL, msg, titleMsg, MB_YESNO | MB_ICONWARNING) != IDYES)
78             return;
79     }
80
81     WINE_TRACE("copying %s to %s\n", wine_dbgstr_w(source), wine_dbgstr_w(destination));
82     CopyFileW(source, destination, FALSE);
83 }
84
85 int PASCAL wWinMain(HINSTANCE hInstance, HINSTANCE prev, LPWSTR cmdline, int show)
86 {
87     LPWSTR *argv;
88     int argc;
89     int i;
90     WCHAR check, cmd = 0;
91     WCHAR path[MAX_PATH];
92     WCHAR backslash[] = {'\\',0};
93     LPCWSTR cabfile = NULL;
94
95     path[0] = 0;
96     argv = CommandLineToArgvW(cmdline, &argc);
97
98     if(!argv)
99     {
100         WINE_ERR("Bad command line arguments\n");
101         return 0;
102     }
103
104     /* Parse arguments */
105     for(i = 0; i < argc; i++)
106     {
107         /* Get cabfile */
108         if (argv[i][0] != '/')
109         {
110             if (!cabfile)
111             {
112                 cabfile = argv[i];
113                 continue;
114             } else
115                 break;
116         }
117         /* Get parameters for commands */
118         check = toupperW( argv[i][1] );
119         switch(check)
120         {
121             case 'A':
122                 WINE_FIXME("/A not implemented\n");
123                 break;
124             case 'Y':
125                 force_mode = TRUE;
126                 break;
127             case 'L':
128                 if ((i + 1) >= argc) return 0;
129                 if (!GetFullPathNameW(argv[++i], MAX_PATH, path, NULL))
130                     return 0;
131                 break;
132             case 'C':
133                 if (cmd) return 0;
134                 cmd = check;
135                 break;
136             case 'E':
137             case 'D':
138                 if (cmd) return 0;
139                 cmd = check;
140                 break;
141             default:
142                 return 0;
143         }
144     }
145
146     if (!cabfile)
147         return 0;
148
149     if (cmd == 'C')
150     {
151         if ((i + 1) != argc) return 0;
152         if (!GetFullPathNameW(argv[i], MAX_PATH, path, NULL))
153             return 0;
154     }
155
156     if (!path[0])
157         GetCurrentDirectoryW(MAX_PATH, path);
158
159     lstrcatW(path, backslash);
160
161     /* Execute the specified command */
162     switch(cmd)
163     {
164         case 'C':
165             /* Copy file */
166             copy_file(cabfile, path);
167             break;
168         case 'E':
169             /* Extract CAB archive */
170             extract(cabfile, path);
171             break;
172         case 0:
173         case 'D':
174             /* Display CAB archive */
175             WINE_FIXME("/D not implemented\n");
176             break;
177     }
178     return 0;
179 }