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

Last change on this file since 4753 was 4753, checked in by bird, 25 years ago

Added inclusion of profile.h.

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