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

Last change on this file since 7742 was 7742, checked in by sandervl, 24 years ago

minor update

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