source: trunk/src/kernel32/disk.cpp@ 4749

Last change on this file since 4749 was 4749, checked in by sandervl, 25 years ago

CW: Fix for GetDiskFreeSpaceA for TVFS & windows media player setup

File size: 14.5 KB
Line 
1/* $Id: disk.cpp,v 1.21 2000-12-03 22:20:31 sandervl Exp $ */
2
3/*
4 * Win32 Disk API functions for OS/2
5 *
6 * Copyright 1998 Sander van Leeuwen
7 *
8 *
9 * Project Odin Software License can be found in LICENSE.TXT
10 *
11 */
12
13
14#include <odin.h>
15#include <odinwrap.h>
16#include <os2sel.h>
17
18#include <os2win.h>
19#include <stdlib.h>
20#include <string.h>
21#include "unicode.h"
22#include "oslibdos.h"
23#include "exceptutil.h"
24
25#define DBG_LOCALLOG DBG_disk
26#include "dbglocal.h"
27
28
29ODINDEBUGCHANNEL(KERNEL32-DISK)
30
31//******************************************************************************
32//******************************************************************************
33BOOL WIN32API SetVolumeLabelA( LPCSTR arg1, LPCSTR arg2)
34{
35 dprintf(("KERNEL32: OS2SetVolumeLabelA\n"));
36 return O32_SetVolumeLabel(arg1, arg2);
37}
38//******************************************************************************
39//******************************************************************************
40BOOL WIN32API SetVolumeLabelW(LPCWSTR lpRootPathName, LPCWSTR lpVolumeName)
41{
42 char *asciiroot, *asciivolname;
43 BOOL rc;
44
45 dprintf(("KERNEL32: OS2SetVolumeLabelW\n"));
46 asciiroot = UnicodeToAsciiString((LPWSTR)lpRootPathName);
47 asciivolname = UnicodeToAsciiString((LPWSTR)lpVolumeName);
48 rc = O32_SetVolumeLabel(asciiroot, asciivolname);
49 FreeAsciiString(asciivolname);
50 FreeAsciiString(asciiroot);
51 return(rc);
52}
53
54//******************************************************************************
55//SvL: 24-6-'97 - Added
56//******************************************************************************
57ODINFUNCTION5(BOOL, GetDiskFreeSpaceA,
58 LPCSTR, arg1,
59 PDWORD, arg2,
60 PDWORD, arg3,
61 PDWORD, arg4,
62 PDWORD, arg5)
63{
64 BOOL rc;
65 DWORD dwSectorsPerCluster; // address of sectors per cluster ter
66 DWORD dwBytesPerSector; // address of bytes per sector
67 DWORD dwNumberOfFreeClusters; // address of number of free clusters
68 DWORD dwTotalNumberOfClusters; // address of total number of clusters
69
70 dprintf(("KERNEL32: GetDiskFreeSpaceA %s, 0x%08X, 0x%08X, 0x%08X, 0x%08X,\n",
71 arg1!=NULL?arg1:"NULL", arg2,arg3,arg4,arg5));
72
73 rc = OSLibGetDiskFreeSpace((LPSTR)arg1, &dwSectorsPerCluster, &dwBytesPerSector,
74 &dwNumberOfFreeClusters, &dwTotalNumberOfClusters);
75 if(rc)
76 {
77 if (arg2!=NULL)
78 *arg2 = dwSectorsPerCluster;
79 if (arg3!=NULL)
80 *arg3 = dwBytesPerSector;
81 if (arg4!=NULL)
82 *arg4 = dwNumberOfFreeClusters;
83 if (arg5!=NULL)
84 *arg5 = dwTotalNumberOfClusters;
85
86 /* CW: Windows Media Player setup complains about wrong clustersize when odin is installed on
87 a TVFS drive. This fakes the clustersizes to 32. The following
88 entry must be present in ODIN.INI:
89
90 [DRIVESPACE]
91 TVFSTOHPFS = 1
92 */
93 if(arg2!=NULL) {
94 if(*arg2==1024 && PROFILE_GetOdinIniBool("DRIVESPACE","CLUSTERTO32",0)) {/* TVFS returns 1024 sectors per cluster */
95 dprintf(("KERNEL32: GetDiskFreeSpaceA, TVFS-Drive detected. Faking clustersize to 32.\n"));
96 *arg2=32;
97 if (arg4!=NULL)
98 *arg4 = dwNumberOfFreeClusters<<0x5;
99 if (arg5!=NULL)
100 *arg5 = dwTotalNumberOfClusters<<0x5;
101 }
102 }
103
104 }
105
106 return rc;
107}
108//******************************************************************************
109//******************************************************************************
110ODINFUNCTION5(BOOL, GetDiskFreeSpaceW,
111 LPCWSTR, arg1,
112 PDWORD, arg2,
113 PDWORD, arg3,
114 PDWORD, arg4,
115 PDWORD, arg5)
116{
117 BOOL rc;
118 char *astring;
119
120 astring = UnicodeToAsciiString((LPWSTR)arg1);
121 rc = CALL_ODINFUNC(GetDiskFreeSpaceA)(astring, arg2, arg3, arg4, arg5);
122 FreeAsciiString(astring);
123 return(rc);
124}
125
126
127/*****************************************************************************
128 * Name : GetDiskFreeSpaceEx
129 * Purpose :
130 * Parameters: lpDirectoryName [in] Pointer to a null-terminated string that
131 * specifies a directory on the disk of interest.
132 * This string can be a UNC name. If this
133 * parameter is a UNC name, you must follow it
134 * with an additional backslash. For example, you
135 * would specify \\MyServer\MyShare as
136 * \\MyServer\MyShare\.
137 * If lpDirectoryName is NULL, the
138 * GetDiskFreeSpaceEx function obtains
139 * information about the object store.
140 * Note that lpDirectoryName does not have to
141 * specify the root directory on a disk. The
142 * function accepts any directory on the disk.
143 *
144 * lpFreeBytesAvailableToCaller
145 * [out] Pointer to a variable to receive the
146 * total number of free bytes on the disk that
147 * are available to the user associated with the
148 * calling thread.
149 * lpTotalNumberOfBytes
150 * [out] Pointer to a variable to receive the
151 * total number of bytes on the disk that are
152 * available to the user associated with the
153 * calling thread.
154 * lpTotalNumberOfFreeBytes
155 * [out] Pointer to a variable to receive the
156 * total number of free bytes on the disk.
157 * This parameter can be NULL.
158 * Variables :
159 * Result : Nonzero indicates success. Zero indicates failure. To get
160 * extended error information, call GetLastError.
161 * Remark : Note that the values obtained by this function are of type
162 * ULARGE_INTEGER. Be careful not to truncate these values to
163 * 32 bits.
164 * Status :
165 *
166 * Author : Patrick Haller [Fri, 2000/01/08 23:44]
167 *****************************************************************************/
168
169ODINFUNCTION4(BOOL,GetDiskFreeSpaceExA,
170 LPCSTR, lpDirectoryName,
171 PULARGE_INTEGER, lpFreeBytesAvailableToCaller,
172 PULARGE_INTEGER, lpTotalNumberOfBytes,
173 PULARGE_INTEGER, lpTotalNumberOfFreeBytes )
174{
175 BOOL rc;
176 DWORD dwSectorsPerCluster; // address of sectors per cluster ter
177 DWORD dwBytesPerSector; // address of bytes per sector
178 DWORD dwNumberOfFreeClusters; // address of number of free clusters
179 DWORD dwTotalNumberOfClusters; // address of total number of clusters
180
181 rc = GetDiskFreeSpaceA(lpDirectoryName, &dwSectorsPerCluster, &dwBytesPerSector,
182 &dwNumberOfFreeClusters, &dwTotalNumberOfClusters);
183 if(rc)
184 {
185 if(lpFreeBytesAvailableToCaller!=NULL) {
186 Mul32x32to64(lpFreeBytesAvailableToCaller, dwNumberOfFreeClusters, (dwSectorsPerCluster*dwBytesPerSector));
187 dprintf(("lpFreeBytesAvailableToCaller %x%x", lpFreeBytesAvailableToCaller->LowPart, lpFreeBytesAvailableToCaller->HighPart));
188 }
189 if(lpTotalNumberOfBytes!=NULL) {
190 Mul32x32to64(lpTotalNumberOfBytes, dwTotalNumberOfClusters, (dwSectorsPerCluster*dwBytesPerSector));
191 dprintf(("lpTotalNumberOfBytes %x%x", lpTotalNumberOfBytes->LowPart, lpTotalNumberOfBytes->HighPart));
192 }
193 if(lpTotalNumberOfFreeBytes!=NULL) {
194 memcpy(lpTotalNumberOfFreeBytes, lpFreeBytesAvailableToCaller, sizeof(*lpFreeBytesAvailableToCaller));
195 dprintf(("lpTotalNumberOfFreeBytes %x%x", lpTotalNumberOfFreeBytes->LowPart, lpTotalNumberOfFreeBytes->HighPart));
196 }
197 }
198 return rc;
199}
200
201
202ODINFUNCTION4(BOOL,GetDiskFreeSpaceExW,
203 LPCWSTR, lpDirectoryName,
204 PULARGE_INTEGER, lpFreeBytesAvailableToCaller,
205 PULARGE_INTEGER, lpTotalNumberOfBytes,
206 PULARGE_INTEGER, lpTotalNumberOfFreeBytes )
207{
208 BOOL rc;
209 char *astring;
210
211 dprintf(("KERNEL32: OS2GetDiskFreeSpaceExW\n"));
212 astring = UnicodeToAsciiString((LPWSTR)lpDirectoryName);
213 rc = GetDiskFreeSpaceExA(astring, lpFreeBytesAvailableToCaller, lpTotalNumberOfBytes, lpTotalNumberOfFreeBytes);
214 FreeAsciiString(astring);
215 return(rc);
216}
217
218
219//******************************************************************************
220//******************************************************************************
221UINT WIN32API GetDriveTypeA(LPCSTR lpszDrive)
222{
223 UINT rc;
224 //NOTE: Although GetDriveTypeW handles -1, GetDriveTypeA crashes in NT 4, SP6
225 rc = O32_GetDriveType(lpszDrive);
226 dprintf(("KERNEL32: GetDriveType %s = %d", lpszDrive, rc));
227 return rc;
228}
229//******************************************************************************
230//******************************************************************************
231UINT WIN32API GetDriveTypeW(LPCWSTR lpszDrive)
232{
233 UINT rc;
234 char *astring;
235
236 if(lpszDrive == (LPCWSTR)-1) {
237 return DRIVE_CANNOTDETERMINE; //NT 4, SP6 returns this (VERIFIED)
238 }
239 astring = UnicodeToAsciiString((LPWSTR)lpszDrive);
240 dprintf(("KERNEL32: OS2GetDriveTypeW %s", astring));
241 rc = O32_GetDriveType(astring);
242 FreeAsciiString(astring);
243 return(rc);
244}
245//******************************************************************************
246//******************************************************************************
247ODINFUNCTION8(BOOL, GetVolumeInformationA,
248 LPCSTR, lpRootPathName,
249 LPSTR, lpVolumeNameBuffer,
250 DWORD, nVolumeNameSize,
251 PDWORD, lpVolumeSerialNumber,
252 PDWORD, lpMaximumComponentLength,
253 PDWORD, lpFileSystemFlags,
254 LPSTR, lpFileSystemNameBuffer,
255 DWORD, nFileSystemNameSize)
256{
257 CHAR tmpstring[256];
258 ULONG drive;
259 BOOL rc;
260
261 dprintf(("GetVolumeInformationA %s", lpRootPathName));
262
263 if(lpRootPathName == NULL) {
264 GetCurrentDirectoryA(sizeof(tmpstring), tmpstring);
265 lpRootPathName = tmpstring;
266 }
267
268 if('A' <= *lpRootPathName && *lpRootPathName <= 'Z') {
269 drive = *lpRootPathName - 'A' + 1;
270 }
271 else
272 if('a' <= *lpRootPathName && *lpRootPathName <= 'z') {
273 drive = *lpRootPathName - 'a' + 1;
274 }
275 else {
276 SetLastError(ERROR_INVALID_PARAMETER);
277 return FALSE;
278 }
279
280 if(lpVolumeSerialNumber || lpVolumeNameBuffer) {
281 rc = OSLibDosQueryVolumeSerialAndName(drive, lpVolumeSerialNumber, lpVolumeNameBuffer, nVolumeNameSize);
282 if(lpVolumeSerialNumber) {
283 dprintf2(("Volume serial number: %x", *lpVolumeSerialNumber));
284 }
285 if(lpVolumeNameBuffer) {
286 dprintf2(("Volume name: %s", lpVolumeNameBuffer));
287 }
288 }
289 if(lpFileSystemNameBuffer || lpMaximumComponentLength) {
290 if(!lpFileSystemNameBuffer) {
291 lpFileSystemNameBuffer = tmpstring;
292 nFileSystemNameSize = sizeof(tmpstring);
293 }
294 rc = OSLibDosQueryVolumeFS(drive, lpFileSystemNameBuffer, nFileSystemNameSize);
295 if(lpFileSystemNameBuffer) {
296 dprintf2(("File system name: %s", lpFileSystemNameBuffer));
297 }
298 }
299 if(lpMaximumComponentLength) {
300 if(!strcmp(lpFileSystemNameBuffer, "FAT")) {
301 *lpMaximumComponentLength = 12;
302 }
303 else *lpMaximumComponentLength = 255; //TODO: Always correct? (CDFS?)
304 }
305 if(lpFileSystemFlags) {
306 if(strcmp(lpFileSystemNameBuffer, "FAT")) {
307 *lpFileSystemFlags = FS_CASE_IS_PRESERVED;
308 }
309 else
310 if(!strcmp(lpFileSystemNameBuffer, "CDFS")) {
311 *lpFileSystemFlags = FS_CASE_SENSITIVE; //NT4 returns this
312 }
313 else
314 if(!strcmp(lpFileSystemNameBuffer, "UDF")) {//TODO: correct?
315 *lpFileSystemFlags = FS_CASE_SENSITIVE | FS_UNICODE_STORED_ON_DISK;
316 }
317 else *lpFileSystemFlags = 0;
318
319 dprintf2(("File system flags: %x", lpFileSystemFlags));
320 }
321
322 if(rc) {
323 SetLastError(rc);
324 return FALSE;
325 }
326 SetLastError(ERROR_SUCCESS);
327 return TRUE;
328}
329//******************************************************************************
330//******************************************************************************
331ODINFUNCTION8(BOOL, GetVolumeInformationW,
332 LPCWSTR, lpRootPathName,
333 LPWSTR, lpVolumeNameBuffer,
334 DWORD, nVolumeNameSize,
335 PDWORD, lpVolumeSerialNumber,
336 PDWORD, lpMaximumComponentLength,
337 PDWORD, lpFileSystemFlags,
338 LPWSTR, lpFileSystemNameBuffer,
339 DWORD, nFileSystemNameSize)
340{
341 char *asciiroot,
342 *asciivol,
343 *asciifs;
344 BOOL rc;
345
346 // transform into ascii
347 asciivol = (char *)malloc(nVolumeNameSize+1);
348 asciifs = (char *)malloc(nFileSystemNameSize+1);
349
350 // clear ascii buffers
351 memset (asciivol, 0, (nVolumeNameSize + 1));
352 memset (asciifs, 0, (nFileSystemNameSize + 1));
353
354 if (lpRootPathName != NULL) // NULL is valid!
355 asciiroot = UnicodeToAsciiString((LPWSTR)lpRootPathName);
356 else
357 asciiroot = NULL;
358
359 rc = CALL_ODINFUNC(GetVolumeInformationA)(asciiroot,
360 asciivol,
361 nVolumeNameSize,
362 lpVolumeSerialNumber,
363 lpMaximumComponentLength,
364 lpFileSystemFlags,
365 asciifs,
366 nFileSystemNameSize);
367
368 if (lpVolumeNameBuffer != NULL) /* @@@PH 98/06/07 */
369 AsciiToUnicodeN(asciivol, lpVolumeNameBuffer, nVolumeNameSize);
370
371 if (lpFileSystemNameBuffer != NULL) /* @@@PH 98/06/07 */
372 AsciiToUnicodeN(asciifs, lpFileSystemNameBuffer, nFileSystemNameSize);
373
374
375 if (asciiroot != NULL)
376 FreeAsciiString(asciiroot);
377
378 free(asciifs);
379 free(asciivol);
380 return(rc);
381}
382//******************************************************************************
383//******************************************************************************
384DWORD WIN32API GetLogicalDrives(void)
385{
386 dprintf(("KERNEL32: GetLogicalDrives\n"));
387 return O32_GetLogicalDrives();
388}
389//******************************************************************************
390//******************************************************************************
391UINT WIN32API GetLogicalDriveStringsA(UINT arg1, LPSTR arg2)
392{
393 dprintf(("KERNEL32: OS2GetLogicalDriveStringsA\n"));
394 return O32_GetLogicalDriveStrings(arg1, arg2);
395}
396//******************************************************************************
397//******************************************************************************
398UINT WIN32API GetLogicalDriveStringsW(UINT nBufferLength, LPWSTR lpBuffer)
399{
400 char *asciibuffer = (char *)malloc(nBufferLength+1);
401 DWORD rc;
402
403 dprintf(("KERNEL32: OS2GetLogicalDriveStringsW\n"));
404
405 rc = O32_GetLogicalDriveStrings(nBufferLength, asciibuffer);
406 if(rc) AsciiToUnicode(asciibuffer, lpBuffer);
407 free(asciibuffer);
408 return(rc);
409}
Note: See TracBrowser for help on using the repository browser.