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

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

GetVolumeInformation bugfix + invalid VirtualFree calls corrected + free named shared memory

File size: 15.8 KB
Line 
1/* $Id: disk.cpp,v 1.24 2000-12-12 23:57:15 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//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//Note: NT4, SP6 does not change the last error, regardless of the junk it receives!
220//******************************************************************************
221UINT WIN32API GetDriveTypeA(LPCSTR lpszDrive)
222{
223 UINT rc;
224 ULONG driveIndex;
225
226 if(lpszDrive == 0) {
227 driveIndex = OSLibDosQueryCurrentDisk() - 1;
228 }
229 else
230 if(*lpszDrive >= 'A' && *lpszDrive <= 'Z')
231 driveIndex = (DWORD)(*lpszDrive - 'A');
232 else
233 if(*lpszDrive >= 'a' && *lpszDrive <= 'z') {
234 driveIndex = (DWORD)(*lpszDrive - 'a');
235 }
236 else {
237 return DRIVE_NO_ROOT_DIR; //return value checked in NT4, SP6 (GetDriveType(""), GetDriveType("4");
238 }
239
240 //NOTE: Although GetDriveTypeW handles -1, GetDriveTypeA crashes in NT 4, SP6
241// rc = OSLibGetDriveType(driveIndex);
242 rc = O32_GetDriveType(lpszDrive);
243 dprintf(("KERNEL32: GetDriveType %s = %d", lpszDrive, rc));
244 return rc;
245}
246//******************************************************************************
247//******************************************************************************
248UINT WIN32API GetDriveTypeW(LPCWSTR lpszDrive)
249{
250 UINT rc;
251 char *astring;
252
253 if(lpszDrive == (LPCWSTR)-1) {
254 return DRIVE_CANNOTDETERMINE; //NT 4, SP6 returns this (VERIFIED)
255 }
256 astring = UnicodeToAsciiString((LPWSTR)lpszDrive);
257 dprintf(("KERNEL32: OS2GetDriveTypeW %s", astring));
258 rc = O32_GetDriveType(astring);
259 FreeAsciiString(astring);
260 return(rc);
261}
262//******************************************************************************
263//******************************************************************************
264ODINFUNCTION8(BOOL, GetVolumeInformationA,
265 LPCSTR, lpRootPathName,
266 LPSTR, lpVolumeNameBuffer,
267 DWORD, nVolumeNameSize,
268 PDWORD, lpVolumeSerialNumber,
269 PDWORD, lpMaximumComponentLength,
270 PDWORD, lpFileSystemFlags,
271 LPSTR, lpFileSystemNameBuffer,
272 DWORD, nFileSystemNameSize)
273{
274 CHAR tmpstring[256];
275 ULONG drive;
276 BOOL rc;
277
278 dprintf(("GetVolumeInformationA %s", lpRootPathName));
279
280 if(lpRootPathName == NULL) {
281 GetCurrentDirectoryA(sizeof(tmpstring), tmpstring);
282 lpRootPathName = tmpstring;
283 }
284
285 if('A' <= *lpRootPathName && *lpRootPathName <= 'Z') {
286 drive = *lpRootPathName - 'A' + 1;
287 }
288 else
289 if('a' <= *lpRootPathName && *lpRootPathName <= 'z') {
290 drive = *lpRootPathName - 'a' + 1;
291 }
292 else {
293 SetLastError(ERROR_INVALID_PARAMETER);
294 return FALSE;
295 }
296
297 if(lpVolumeSerialNumber || lpVolumeNameBuffer) {
298 rc = OSLibDosQueryVolumeSerialAndName(drive, lpVolumeSerialNumber, lpVolumeNameBuffer, nVolumeNameSize);
299 if(lpVolumeSerialNumber) {
300 dprintf2(("Volume serial number: %x", *lpVolumeSerialNumber));
301 }
302 if(lpVolumeNameBuffer) {
303 dprintf2(("Volume name: %s", lpVolumeNameBuffer));
304 }
305 }
306 if(lpFileSystemNameBuffer || lpMaximumComponentLength || lpFileSystemFlags) {
307 if(!lpFileSystemNameBuffer) {
308 lpFileSystemNameBuffer = tmpstring;
309 nFileSystemNameSize = sizeof(tmpstring);
310 }
311 rc = OSLibDosQueryVolumeFS(drive, lpFileSystemNameBuffer, nFileSystemNameSize);
312 if(lpFileSystemNameBuffer) {
313 dprintf2(("File system name: %s", lpFileSystemNameBuffer));
314 }
315 }
316 if(lpMaximumComponentLength) {
317 if(!strcmp(lpFileSystemNameBuffer, "FAT")) {
318 *lpMaximumComponentLength = 12;
319 }
320 else *lpMaximumComponentLength = 255; //TODO: Always correct? (CDFS?)
321 }
322 if(lpFileSystemFlags)
323 {
324 if(strcmp(lpFileSystemNameBuffer, "FAT")) {
325 *lpFileSystemFlags = FS_CASE_IS_PRESERVED;
326 }
327 else
328 if(!strcmp(lpFileSystemNameBuffer, "CDFS")) {
329 *lpFileSystemFlags = FS_CASE_SENSITIVE; //NT4 returns this
330 }
331 else
332 if(!strcmp(lpFileSystemNameBuffer, "UDF")) {//TODO: correct?
333 *lpFileSystemFlags = FS_CASE_SENSITIVE | FS_UNICODE_STORED_ON_DISK;
334 }
335 else *lpFileSystemFlags = 0;
336
337 dprintf2(("File system flags: %x", lpFileSystemFlags));
338 }
339
340 if(rc) {
341 SetLastError(rc);
342 return FALSE;
343 }
344 SetLastError(ERROR_SUCCESS);
345 return TRUE;
346}
347//******************************************************************************
348//******************************************************************************
349ODINFUNCTION8(BOOL, GetVolumeInformationW,
350 LPCWSTR, lpRootPathName,
351 LPWSTR, lpVolumeNameBuffer,
352 DWORD, nVolumeNameSize,
353 PDWORD, lpVolumeSerialNumber,
354 PDWORD, lpMaximumComponentLength,
355 PDWORD, lpFileSystemFlags,
356 LPWSTR, lpFileSystemNameBuffer,
357 DWORD, nFileSystemNameSize)
358{
359 char *asciiroot,
360 *asciivol,
361 *asciifs;
362 BOOL rc;
363
364 // transform into ascii
365 asciivol = (char *)malloc(nVolumeNameSize+1);
366 asciifs = (char *)malloc(nFileSystemNameSize+1);
367
368 // clear ascii buffers
369 memset (asciivol, 0, (nVolumeNameSize + 1));
370 memset (asciifs, 0, (nFileSystemNameSize + 1));
371
372 if (lpRootPathName != NULL) // NULL is valid!
373 asciiroot = UnicodeToAsciiString((LPWSTR)lpRootPathName);
374 else
375 asciiroot = NULL;
376
377 rc = CALL_ODINFUNC(GetVolumeInformationA)(asciiroot,
378 asciivol,
379 nVolumeNameSize,
380 lpVolumeSerialNumber,
381 lpMaximumComponentLength,
382 lpFileSystemFlags,
383 asciifs,
384 nFileSystemNameSize);
385
386 if (lpVolumeNameBuffer != NULL) /* @@@PH 98/06/07 */
387 AsciiToUnicodeN(asciivol, lpVolumeNameBuffer, nVolumeNameSize);
388
389 if (lpFileSystemNameBuffer != NULL) /* @@@PH 98/06/07 */
390 AsciiToUnicodeN(asciifs, lpFileSystemNameBuffer, nFileSystemNameSize);
391
392
393 if (asciiroot != NULL)
394 FreeAsciiString(asciiroot);
395
396 free(asciifs);
397 free(asciivol);
398 return(rc);
399}
400//******************************************************************************
401//******************************************************************************
402DWORD WIN32API GetLogicalDrives(void)
403{
404 dprintf(("KERNEL32: GetLogicalDrives\n"));
405 return OSLibGetLogicalDrives();
406}
407//******************************************************************************
408//******************************************************************************
409UINT WIN32API GetLogicalDriveStringsA(UINT arg1, LPSTR arg2)
410{
411 dprintf(("KERNEL32: OS2GetLogicalDriveStringsA\n"));
412 return O32_GetLogicalDriveStrings(arg1, arg2);
413}
414//******************************************************************************
415//******************************************************************************
416UINT WIN32API GetLogicalDriveStringsW(UINT nBufferLength, LPWSTR lpBuffer)
417{
418 char *asciibuffer = (char *)malloc(nBufferLength+1);
419 DWORD rc;
420
421 dprintf(("KERNEL32: OS2GetLogicalDriveStringsW\n"));
422
423 rc = O32_GetLogicalDriveStrings(nBufferLength, asciibuffer);
424 if(rc) AsciiToUnicode(asciibuffer, lpBuffer);
425 free(asciibuffer);
426 return(rc);
427}
428//******************************************************************************
429//******************************************************************************
430
Note: See TracBrowser for help on using the repository browser.