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

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

logging updates

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