extrac32: Implementation of the CAB archive extraction.
[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
26 #include "wine/unicode.h"
27 #include "wine/debug.h"
28
29 WINE_DEFAULT_DEBUG_CHANNEL(extrac32);
30
31 static UINT WINAPI ExtCabCallback(PVOID Context, UINT Notification, UINT_PTR Param1, UINT_PTR Param2)
32 {
33     FILE_IN_CABINET_INFO_W *pInfo;
34     FILEPATHS_W *pFilePaths;
35
36     switch(Notification)
37     {
38         case SPFILENOTIFY_FILEINCABINET:
39             pInfo = (FILE_IN_CABINET_INFO_W*)Param1;
40             lstrcpyW(pInfo->FullTargetName, (LPCWSTR)Context);
41             lstrcatW(pInfo->FullTargetName, pInfo->NameInCabinet);
42             return FILEOP_DOIT;
43         case SPFILENOTIFY_FILEEXTRACTED:
44             pFilePaths = (FILEPATHS_W*)Param1;
45             WINE_TRACE("Extracted %s\n", wine_dbgstr_w(pFilePaths->Target));
46             return NO_ERROR;
47     }
48     return NO_ERROR;
49 }
50
51 static void extract(LPCWSTR cabfile, LPWSTR destdir)
52 {
53     if (!SetupIterateCabinetW(cabfile, 0, ExtCabCallback, destdir))
54         WINE_ERR("Could not extract cab file %s\n", wine_dbgstr_w(cabfile));
55 }
56
57 int PASCAL wWinMain(HINSTANCE hInstance, HINSTANCE prev, LPWSTR cmdline, int show)
58 {
59     LPWSTR *argv;
60     int argc;
61     int i;
62     WCHAR check, cmd = 0;
63     WCHAR path[MAX_PATH];
64     WCHAR backslash[] = {'\\',0};
65     LPCWSTR cabfile = NULL;
66
67     path[0] = 0;
68     argv = CommandLineToArgvW(cmdline, &argc);
69
70     if(!argv)
71     {
72         WINE_ERR("Bad command line arguments\n");
73         return 0;
74     }
75
76     /* Parse arguments */
77     for(i = 0; i < argc; i++)
78     {
79         /* Get cabfile */
80         if ((argv[i][0] != '/') && !cabfile)
81         {
82             cabfile = argv[i];
83             continue;
84         }
85         /* Get parameters for commands */
86         check = toupperW( argv[i][1] );
87         switch(check)
88         {
89             case 'A':
90                 WINE_FIXME("/A not implemented\n");
91                 break;
92             case 'Y':
93                 WINE_FIXME("/Y not implemented\n");
94                 break;
95             case 'L':
96                 if ((i + 1) >= argc) return 0;
97                 if (!GetFullPathNameW(argv[++i], MAX_PATH, path, NULL))
98                     return 0;
99                 break;
100             case 'C':
101                 if (cmd) return 0;
102                 if ((i + 2) >= argc) return 0;
103                 cmd = check;
104                 cabfile = argv[++i];
105                 if (!GetFullPathNameW(argv[++i], MAX_PATH, path, NULL))
106                     return 0;
107                 break;
108             case 'E':
109             case 'D':
110                 if (cmd) return 0;
111                 cmd = check;
112                 break;
113             default:
114                 return 0;
115         }
116     }
117
118     if (!cabfile)
119         return 0;
120
121     if (!path[0])
122         GetCurrentDirectoryW(MAX_PATH, path);
123
124     lstrcatW(path, backslash);
125
126     /* Execute the specified command */
127     switch(cmd)
128     {
129         case 'C':
130             /* Copy file */
131             WINE_FIXME("/C not implemented\n");
132             break;
133         case 'E':
134             /* Extract CAB archive */
135             extract(cabfile, path);
136             break;
137         case 0:
138         case 'D':
139             /* Display CAB archive */
140             WINE_FIXME("/D not implemented\n");
141             break;
142     }
143     return 0;
144 }