shell32/tests: Greatly expand the test_argify() tests.
[wine] / dlls / setupapi / diskspace.c
1 /*
2  * SetupAPI DiskSpace functions
3  *
4  * Copyright 2004 CodeWeavers (Aric Stewart)
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 #include <stdarg.h>
22
23 #include "windef.h"
24 #include "winbase.h"
25 #include "wingdi.h"
26 #include "winuser.h"
27 #include "winnls.h"
28 #include "winreg.h"
29 #include "setupapi.h"
30 #include "wine/debug.h"
31
32 WINE_DEFAULT_DEBUG_CHANNEL(setupapi);
33
34 typedef struct {
35     WCHAR   lpzName[20];
36     LONGLONG dwFreeSpace;
37     LONGLONG dwWantedSpace;
38 } DRIVE_ENTRY, *LPDRIVE_ENTRY;
39
40 typedef struct {
41     DWORD   dwDriveCount;
42     DRIVE_ENTRY Drives[26];
43 } DISKSPACELIST, *LPDISKSPACELIST;
44
45
46 /***********************************************************************
47  *              SetupCreateDiskSpaceListW  (SETUPAPI.@)
48  */
49 HDSKSPC WINAPI SetupCreateDiskSpaceListW(PVOID Reserved1, DWORD Reserved2, UINT Flags)
50 {
51     WCHAR drives[255];
52     DWORD rc;
53     WCHAR *ptr;
54     LPDISKSPACELIST list=NULL;
55
56     TRACE("(%p, %u, 0x%08x)\n", Reserved1, Reserved2, Flags);
57
58     if (Reserved1 || Reserved2 || Flags & ~SPDSL_IGNORE_DISK)
59     {
60         SetLastError(ERROR_INVALID_PARAMETER);
61         return NULL;
62     }
63
64     rc = GetLogicalDriveStringsW(255,drives);
65
66     if (rc == 0)
67         return NULL;
68
69     list = HeapAlloc(GetProcessHeap(),0,sizeof(DISKSPACELIST));
70
71     list->dwDriveCount = 0;
72     
73     ptr = drives;
74     
75     while (*ptr)
76     {
77         DWORD type = GetDriveTypeW(ptr);
78         if (type == DRIVE_FIXED)
79         {
80             DWORD clusters;
81             DWORD sectors;
82             DWORD bytes;
83             DWORD total;
84             lstrcpyW(list->Drives[list->dwDriveCount].lpzName,ptr);
85             GetDiskFreeSpaceW(ptr,&sectors,&bytes,&clusters,&total);
86             list->Drives[list->dwDriveCount].dwFreeSpace = clusters * sectors *
87                                                            bytes;
88             list->Drives[list->dwDriveCount].dwWantedSpace = 0;
89             list->dwDriveCount++;
90         }
91        ptr += lstrlenW(ptr) + 1;
92     }
93     return list;
94 }
95
96
97 /***********************************************************************
98  *              SetupCreateDiskSpaceListA  (SETUPAPI.@)
99  */
100 HDSKSPC WINAPI SetupCreateDiskSpaceListA(PVOID Reserved1, DWORD Reserved2, UINT Flags)
101 {
102     return SetupCreateDiskSpaceListW( Reserved1, Reserved2, Flags );
103 }
104
105 /***********************************************************************
106  *              SetupDuplicateDiskSpaceListW  (SETUPAPI.@)
107  */
108 HDSKSPC WINAPI SetupDuplicateDiskSpaceListW(HDSKSPC DiskSpace, PVOID Reserved1, DWORD Reserved2, UINT Flags)
109 {
110     DISKSPACELIST *list_copy, *list_original = DiskSpace;
111
112     if (Reserved1 || Reserved2 || Flags)
113     {
114         SetLastError(ERROR_INVALID_PARAMETER);
115         return NULL;
116     }
117
118     if (!DiskSpace)
119     {
120         SetLastError(ERROR_INVALID_HANDLE);
121         return NULL;
122     }
123
124     list_copy = HeapAlloc(GetProcessHeap(), 0, sizeof(DISKSPACELIST));
125     if (!list_copy)
126     {
127         SetLastError(ERROR_NOT_ENOUGH_MEMORY);
128         return NULL;
129     }
130
131     *list_copy = *list_original;
132
133     return list_copy;
134 }
135
136 /***********************************************************************
137  *              SetupDuplicateDiskSpaceListA  (SETUPAPI.@)
138  */
139 HDSKSPC WINAPI SetupDuplicateDiskSpaceListA(HDSKSPC DiskSpace, PVOID Reserved1, DWORD Reserved2, UINT Flags)
140 {
141     return SetupDuplicateDiskSpaceListW(DiskSpace, Reserved1, Reserved2, Flags);
142 }
143
144 /***********************************************************************
145  *              SetupAddInstallSectionToDiskSpaceListA  (SETUPAPI.@)
146  */
147 BOOL WINAPI SetupAddInstallSectionToDiskSpaceListA(HDSKSPC DiskSpace, 
148                         HINF InfHandle, HINF LayoutInfHandle, 
149                         LPCSTR SectionName, PVOID Reserved1, UINT Reserved2)
150 {
151     FIXME ("Stub\n");
152     return TRUE;
153 }
154
155 /***********************************************************************
156 *               SetupQuerySpaceRequiredOnDriveW  (SETUPAPI.@)
157 */
158 BOOL WINAPI SetupQuerySpaceRequiredOnDriveW(HDSKSPC DiskSpace,
159                         LPCWSTR DriveSpec, LONGLONG *SpaceRequired,
160                         PVOID Reserved1, UINT Reserved2)
161 {
162     WCHAR *driveW;
163     unsigned int i;
164     LPDISKSPACELIST list = DiskSpace;
165     BOOL rc = FALSE;
166     static const WCHAR bkslsh[]= {'\\',0};
167
168     if (!DiskSpace)
169     {
170         SetLastError(ERROR_INVALID_HANDLE);
171         return FALSE;
172     }
173
174     if (!DriveSpec)
175     {
176         SetLastError(ERROR_INVALID_PARAMETER);
177         return FALSE;
178     }
179
180     driveW = HeapAlloc(GetProcessHeap(), 0, (lstrlenW(DriveSpec) + 2) * sizeof(WCHAR));
181     if (!driveW)
182     {
183         SetLastError(ERROR_NOT_ENOUGH_MEMORY);
184         return FALSE;
185     }
186
187     lstrcpyW(driveW,DriveSpec);
188     lstrcatW(driveW,bkslsh);
189
190     TRACE("Looking for drive %s\n",debugstr_w(driveW));
191  
192     for (i = 0; i < list->dwDriveCount; i++)
193     {
194         TRACE("checking drive %s\n",debugstr_w(list->Drives[i].lpzName));
195         if (lstrcmpW(driveW,list->Drives[i].lpzName)==0)
196         {
197             rc = TRUE;
198             *SpaceRequired = list->Drives[i].dwWantedSpace;
199             break;
200         }
201     }
202
203     HeapFree(GetProcessHeap(), 0, driveW);
204
205     if (!rc) SetLastError(ERROR_INVALID_DRIVE);
206     return rc;
207 }
208
209 /***********************************************************************
210 *               SetupQuerySpaceRequiredOnDriveA  (SETUPAPI.@)
211 */
212 BOOL WINAPI SetupQuerySpaceRequiredOnDriveA(HDSKSPC DiskSpace,
213                         LPCSTR DriveSpec, LONGLONG *SpaceRequired,
214                         PVOID Reserved1, UINT Reserved2)
215 {
216     DWORD len;
217     LPWSTR DriveSpecW;
218     BOOL ret;
219
220     /* The parameter validation checks are in a different order from the
221      * Unicode variant of SetupQuerySpaceRequiredOnDrive. */
222     if (!DriveSpec)
223     {
224         SetLastError(ERROR_INVALID_PARAMETER);
225         return FALSE;
226     }
227
228     if (!DiskSpace)
229     {
230         SetLastError(ERROR_INVALID_HANDLE);
231         return FALSE;
232     }
233
234     len = MultiByteToWideChar(CP_ACP, 0, DriveSpec, -1, NULL, 0);
235
236     DriveSpecW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
237     if (!DriveSpecW)
238     {
239         SetLastError(ERROR_NOT_ENOUGH_MEMORY);
240         return FALSE;
241     }
242
243     MultiByteToWideChar(CP_ACP, 0, DriveSpec, -1, DriveSpecW, len);
244
245     ret = SetupQuerySpaceRequiredOnDriveW(DiskSpace, DriveSpecW, SpaceRequired,
246                                           Reserved1, Reserved2);
247
248     HeapFree(GetProcessHeap(), 0, DriveSpecW);
249
250     return ret;
251 }
252
253 /***********************************************************************
254 *               SetupDestroyDiskSpaceList  (SETUPAPI.@)
255 */
256 BOOL WINAPI SetupDestroyDiskSpaceList(HDSKSPC DiskSpace)
257 {
258     LPDISKSPACELIST list = DiskSpace;
259     HeapFree(GetProcessHeap(),0,list);
260     return TRUE; 
261 }
262
263 /***********************************************************************
264 *               SetupAddToDiskSpaceListA  (SETUPAPI.@)
265 */
266 BOOL WINAPI SetupAddToDiskSpaceListA(HDSKSPC diskspace, PCSTR targetfile,
267                                     LONGLONG filesize, UINT operation,
268                                     PVOID reserved1, UINT reserved2)
269 {
270     FIXME(": stub\n");
271     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
272     return FALSE;
273 }
274
275 /***********************************************************************
276 *               SetupAddToDiskSpaceListW  (SETUPAPI.@)
277 */
278 BOOL WINAPI SetupAddToDiskSpaceListW(HDSKSPC diskspace, PCWSTR targetfile,
279                                     LONGLONG filesize, UINT operation,
280                                     PVOID reserved1, UINT reserved2)
281 {
282     FIXME(": stub\n");
283     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
284     return FALSE;
285 }