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