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