Sync with trunk revision 63128.
[reactos.git] / dll / win32 / 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 "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 */
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 */
89 HDSKSPC WINAPI SetupCreateDiskSpaceListA(PVOID Reserved1, DWORD Reserved2, UINT Flags)
90 {
91 return SetupCreateDiskSpaceListW( Reserved1, Reserved2, Flags );
92 }
93
94 /***********************************************************************
95 * SetupDuplicateDiskSpaceListW (SETUPAPI.@)
96 */
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 */
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 */
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 */
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 */
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 */
245 BOOL WINAPI SetupDestroyDiskSpaceList(HDSKSPC DiskSpace)
246 {
247 LPDISKSPACELIST list = (LPDISKSPACELIST)DiskSpace;
248 HeapFree(GetProcessHeap(),0,list);
249 return TRUE;
250 }