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

Last change on this file since 9304 was 9304, checked in by sandervl, 23 years ago

FindFirst/NextVolumeA fixes for ignoring LVM volumes

File size: 30.6 KB
Line 
1/* $Id: disk.cpp,v 1.39 2002-09-27 14:35:56 sandervl Exp $ */
2
3/*
4 * Win32 Disk API functions for OS/2
5 *
6 * Copyright 1998-2002 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 <stdio.h>
20#include <stdlib.h>
21#include <string.h>
22#include <versionos2.h>
23#include "unicode.h"
24#include "oslibdos.h"
25#include "osliblvm.h"
26#include "asmutil.h"
27#include "profile.h"
28#include "hmdisk.h"
29
30#define DBG_LOCALLOG DBG_disk
31#include "dbglocal.h"
32
33
34ODINDEBUGCHANNEL(KERNEL32-DISK)
35
36
37//******************************************************************************
38//******************************************************************************
39BOOL WIN32API SetVolumeLabelA( LPCSTR arg1, LPCSTR arg2)
40{
41 dprintf(("KERNEL32: OS2SetVolumeLabelA\n"));
42 return O32_SetVolumeLabel(arg1, arg2);
43}
44//******************************************************************************
45//******************************************************************************
46BOOL WIN32API SetVolumeLabelW(LPCWSTR lpRootPathName, LPCWSTR lpVolumeName)
47{
48 char *asciiroot, *asciivolname;
49 BOOL rc;
50
51 dprintf(("KERNEL32: OS2SetVolumeLabelW\n"));
52 asciiroot = UnicodeToAsciiString((LPWSTR)lpRootPathName);
53 asciivolname = UnicodeToAsciiString((LPWSTR)lpVolumeName);
54 rc = O32_SetVolumeLabel(asciiroot, asciivolname);
55 FreeAsciiString(asciivolname);
56 FreeAsciiString(asciiroot);
57 return(rc);
58}
59
60//******************************************************************************
61//******************************************************************************
62BOOL WIN32API GetDiskFreeSpaceA(LPCSTR lpszRootPathName, PDWORD lpSectorsPerCluster,
63 PDWORD lpBytesPerSector, PDWORD lpFreeClusters,
64 PDWORD lpClusters)
65{
66 BOOL rc;
67 DWORD dwSectorsPerCluster; // address of sectors per cluster ter
68 DWORD dwBytesPerSector; // address of bytes per sector
69 DWORD dwNumberOfFreeClusters; // address of number of free clusters
70 DWORD dwTotalNumberOfClusters; // address of total number of clusters
71
72 rc = OSLibGetDiskFreeSpace((LPSTR)lpszRootPathName, &dwSectorsPerCluster, &dwBytesPerSector,
73 &dwNumberOfFreeClusters, &dwTotalNumberOfClusters);
74 if(rc)
75 {
76 if (lpSectorsPerCluster!=NULL)
77 *lpSectorsPerCluster = dwSectorsPerCluster;
78 if (lpBytesPerSector!=NULL)
79 *lpBytesPerSector = dwBytesPerSector;
80 if (lpFreeClusters!=NULL)
81 *lpFreeClusters = dwNumberOfFreeClusters;
82 if (lpClusters!=NULL)
83 *lpClusters = dwTotalNumberOfClusters;
84
85 /* CW: Windows Media Player setup complains about wrong clustersize when odin is installed on
86 a TVFS drive. This fakes the clustersizes to 32. The following
87 entry must be present in ODIN.INI:
88
89 [DRIVESPACE]
90 TVFSTOHPFS = 1
91 */
92 if(lpSectorsPerCluster!=NULL)
93 {
94 if(*lpSectorsPerCluster==1024 && PROFILE_GetOdinIniBool("DRIVESPACE","CLUSTERTO32",0))
95 {/* TVFS returns 1024 sectors per cluster */
96 dprintf(("KERNEL32: GetDiskFreeSpaceA, TVFS-Drive detected. Faking clustersize to 32.\n"));
97 *lpSectorsPerCluster=32;
98 if (lpFreeClusters!=NULL)
99 *lpFreeClusters = dwNumberOfFreeClusters<<0x5;
100 if (lpClusters!=NULL)
101 *lpClusters = dwTotalNumberOfClusters<<0x5;
102 }
103 }
104 }
105 return rc;
106}
107//******************************************************************************
108//******************************************************************************
109BOOL WIN32API GetDiskFreeSpaceW(LPCWSTR lpszRootPathName,
110 PDWORD lpSectorsPerCluster,
111 PDWORD lpBytesPerSector,
112 PDWORD lpFreeClusters,
113 PDWORD lpClusters)
114{
115 BOOL rc;
116 char *astring;
117
118 astring = UnicodeToAsciiString((LPWSTR)lpszRootPathName);
119 rc = GetDiskFreeSpaceA(astring, lpSectorsPerCluster, lpBytesPerSector, lpFreeClusters, lpClusters);
120 FreeAsciiString(astring);
121 return(rc);
122}
123
124
125/*****************************************************************************
126 * Name : GetDiskFreeSpaceEx
127 * Purpose :
128 * Parameters: lpDirectoryName [in] Pointer to a null-terminated string that
129 * specifies a directory on the disk of interest.
130 * This string can be a UNC name. If this
131 * parameter is a UNC name, you must follow it
132 * with an additional backslash. For example, you
133 * would specify \\MyServer\MyShare as
134 * \\MyServer\MyShare\.
135 * If lpDirectoryName is NULL, the
136 * GetDiskFreeSpaceEx function obtains
137 * information about the object store.
138 * Note that lpDirectoryName does not have to
139 * specify the root directory on a disk. The
140 * function accepts any directory on the disk.
141 *
142 * lpFreeBytesAvailableToCaller
143 * [out] Pointer to a variable to receive the
144 * total number of free bytes on the disk that
145 * are available to the user associated with the
146 * calling thread.
147 * lpTotalNumberOfBytes
148 * [out] Pointer to a variable to receive the
149 * total number of bytes on the disk that are
150 * available to the user associated with the
151 * calling thread.
152 * lpTotalNumberOfFreeBytes
153 * [out] Pointer to a variable to receive the
154 * total number of free bytes on the disk.
155 * This parameter can be NULL.
156 * Variables :
157 * Result : Nonzero indicates success. Zero indicates failure. To get
158 * extended error information, call GetLastError.
159 * Remark : Note that the values obtained by this function are of type
160 * ULARGE_INTEGER. Be careful not to truncate these values to
161 * 32 bits.
162 * Status :
163 *
164 * Author : Patrick Haller [Fri, 2000/01/08 23:44]
165 *****************************************************************************/
166
167BOOL WIN32API GetDiskFreeSpaceExA(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//******************************************************************************
199BOOL WIN32API GetDiskFreeSpaceExW(LPCWSTR lpDirectoryName,
200 PULARGE_INTEGER lpFreeBytesAvailableToCaller,
201 PULARGE_INTEGER lpTotalNumberOfBytes,
202 PULARGE_INTEGER lpTotalNumberOfFreeBytes )
203{
204 BOOL rc;
205 char *astring;
206
207 dprintf(("KERNEL32: OS2GetDiskFreeSpaceExW\n"));
208 astring = UnicodeToAsciiString((LPWSTR)lpDirectoryName);
209 rc = GetDiskFreeSpaceExA(astring, lpFreeBytesAvailableToCaller, lpTotalNumberOfBytes, lpTotalNumberOfFreeBytes);
210 FreeAsciiString(astring);
211 return(rc);
212}
213//******************************************************************************
214//Note: NT4, SP6 does not change the last error, regardless of the junk it receives!
215//******************************************************************************
216UINT WIN32API GetDriveTypeA(LPCSTR lpszDrive)
217{
218 UINT rc;
219 ULONG driveIndex;
220
221 if(lpszDrive == 0) {
222 driveIndex = OSLibDosQueryCurrentDisk() - 1;
223 }
224 else
225 if(*lpszDrive >= 'A' && *lpszDrive <= 'Z')
226 driveIndex = (DWORD)(*lpszDrive - 'A');
227 else
228 if(*lpszDrive >= 'a' && *lpszDrive <= 'z') {
229 driveIndex = (DWORD)(*lpszDrive - 'a');
230 }
231 else {
232 //Volume functions only available in Windows 2000 and up
233 if(VERSION_IS_WIN2000_OR_HIGHER() && !strncmp(lpszDrive, VOLUME_NAME_PREFIX, sizeof(VOLUME_NAME_PREFIX)-1))
234 {
235 char *pszVolume;
236 int length;
237
238 //strip volume name prefix (\\\\?\\Volume\\)
239 length = strlen(lpszDrive);
240 pszVolume = (char *)alloca(length);
241
242 if(OSLibLVMStripVolumeName(lpszDrive, pszVolume, length))
243 {
244 rc = OSLibLVMGetDriveType(pszVolume);
245 dprintf(("KERNEL32: GetDriveType %s = %d (LVM)", lpszDrive, rc));
246 return rc;
247 }
248 }
249 return DRIVE_NO_ROOT_DIR; //return value checked in NT4, SP6 (GetDriveType(""), GetDriveType("4");
250 }
251
252 //NOTE: Although GetDriveTypeW handles -1, GetDriveTypeA crashes in NT 4, SP6
253 rc = OSLibGetDriveType(driveIndex);
254 dprintf(("KERNEL32: GetDriveType %s = %d", lpszDrive, rc));
255 return rc;
256}
257//******************************************************************************
258//******************************************************************************
259UINT WIN32API GetDriveTypeW(LPCWSTR lpszDrive)
260{
261 UINT rc;
262 char *astring;
263
264 if(lpszDrive == (LPCWSTR)-1) {
265 return DRIVE_CANNOTDETERMINE; //NT 4, SP6 returns this (VERIFIED)
266 }
267 astring = UnicodeToAsciiString((LPWSTR)lpszDrive);
268 dprintf(("KERNEL32: GetDriveTypeW %s", astring));
269 rc = GetDriveTypeA(astring);
270 FreeAsciiString(astring);
271 return(rc);
272}
273//******************************************************************************
274static int fForce2GBFileSize = FALSE;
275//******************************************************************************
276void WIN32API CustForce2GBFileSize()
277{
278 fForce2GBFileSize = TRUE;
279}
280//******************************************************************************
281//******************************************************************************
282BOOL WIN32API GetVolumeInformationA(LPCSTR lpRootPathName,
283 LPSTR lpVolumeNameBuffer,
284 DWORD nVolumeNameSize,
285 PDWORD lpVolumeSerialNumber,
286 PDWORD lpMaximumComponentLength,
287 PDWORD lpFileSystemFlags,
288 LPSTR lpFileSystemNameBuffer,
289 DWORD nFileSystemNameSize)
290{
291 CHAR tmpstring[256];
292 CHAR szOrgFileSystemName[256] = "";
293 ULONG drive;
294 BOOL rc, fVolumeName = FALSE;
295 char *pszVolume;
296
297 dprintf(("GetVolumeInformationA %s", lpRootPathName));
298
299 if(lpRootPathName == NULL) {
300 GetCurrentDirectoryA(sizeof(tmpstring), tmpstring);
301 lpRootPathName = tmpstring;
302 }
303
304 if('A' <= *lpRootPathName && *lpRootPathName <= 'Z') {
305 drive = *lpRootPathName - 'A' + 1;
306 }
307 else
308 if('a' <= *lpRootPathName && *lpRootPathName <= 'z') {
309 drive = *lpRootPathName - 'a' + 1;
310 }
311 else {
312 //Volume functions only available in Windows 2000 and up
313 if(LOBYTE(GetVersion()) >= 5 && !strncmp(lpRootPathName, VOLUME_NAME_PREFIX, sizeof(VOLUME_NAME_PREFIX)-1))
314 {
315 int length;
316
317 //strip volume name prefix (\\\\?\\Volume\\)
318 length = strlen(lpRootPathName);
319 pszVolume = (char *)alloca(length);
320
321 if(OSLibLVMStripVolumeName(lpRootPathName, pszVolume, length))
322 {
323 pszVolume[length-2] = 0;
324 fVolumeName = TRUE;
325 goto proceed;
326 }
327 }
328 SetLastError(ERROR_INVALID_PARAMETER);
329 return FALSE;
330 }
331proceed:
332
333 if(lpVolumeSerialNumber || lpVolumeNameBuffer) {
334 if(fVolumeName) {
335 rc = OSLibLVMQueryVolumeSerialAndName(pszVolume, lpVolumeSerialNumber, lpVolumeNameBuffer, nVolumeNameSize);
336 }
337 else rc = OSLibDosQueryVolumeSerialAndName(drive, lpVolumeSerialNumber, lpVolumeNameBuffer, nVolumeNameSize);
338 if(lpVolumeSerialNumber) {
339 dprintf2(("Volume serial number: %x", *lpVolumeSerialNumber));
340 }
341 if(lpVolumeNameBuffer) {
342 dprintf2(("Volume name: %s", lpVolumeNameBuffer));
343 }
344 }
345 if(lpFileSystemNameBuffer || lpMaximumComponentLength || lpFileSystemFlags)
346 {
347 if(!lpFileSystemNameBuffer) {
348 lpFileSystemNameBuffer = tmpstring;
349 nFileSystemNameSize = sizeof(tmpstring);
350 }
351 if(fVolumeName) {
352 rc = OSLibLVMQueryVolumeFS(pszVolume, lpFileSystemNameBuffer, nFileSystemNameSize);
353 }
354 else rc = OSLibDosQueryVolumeFS(drive, lpFileSystemNameBuffer, nFileSystemNameSize);
355
356 //save original file system name
357 if(rc == ERROR_SUCCESS) strcpy(szOrgFileSystemName, lpFileSystemNameBuffer);
358
359 if(lpFileSystemNameBuffer)
360 {
361 dprintf2(("File system name: %s", lpFileSystemNameBuffer));
362 if(!strcmp(lpFileSystemNameBuffer, "JFS"))
363 {
364 strcpy(lpFileSystemNameBuffer, "NTFS");
365 }
366 else
367 if(!strcmp(lpFileSystemNameBuffer, "CDFS") ||
368 !strcmp(lpFileSystemNameBuffer, "UDF") ||
369 !strcmp(lpFileSystemNameBuffer, "NTFS") ||
370 !strcmp(lpFileSystemNameBuffer, "FAT32"))
371 {
372 //do nothing
373 }
374 else
375 {//pretend everything else is FAT16 (HPFS and FAT have the same file size limit)
376 strcpy(lpFileSystemNameBuffer, "FAT16");
377 }
378 if(fForce2GBFileSize) {
379 if(strcmp(lpFileSystemNameBuffer, "CDFS") &&
380 strcmp(lpFileSystemNameBuffer, "UDF"))
381 {//everything is FAT -> 2 GB file size limit
382 strcpy(lpFileSystemNameBuffer, "FAT16");
383 }
384 }
385 dprintf2(("Final file system name: %s", lpFileSystemNameBuffer));
386 }
387 }
388 if(lpMaximumComponentLength) {
389 if(!strcmp(szOrgFileSystemName, "FAT16") || !strcmp(szOrgFileSystemName, "FAT")) {
390 *lpMaximumComponentLength = 12; //8.3
391 }
392 else *lpMaximumComponentLength = 255; //TODO: Always correct? (CDFS?)
393 }
394 if(lpFileSystemFlags)
395 {
396 if(strcmp(lpFileSystemNameBuffer, "FAT16")) {
397 *lpFileSystemFlags = FS_CASE_IS_PRESERVED;
398 }
399 else
400 if(!strcmp(lpFileSystemNameBuffer, "CDFS")) {
401 *lpFileSystemFlags = FS_CASE_SENSITIVE; //NT4 returns this
402 }
403 else
404 if(!strcmp(lpFileSystemNameBuffer, "UDF")) {//TODO: correct?
405 *lpFileSystemFlags = FS_CASE_SENSITIVE | FS_UNICODE_STORED_ON_DISK;
406 }
407 else *lpFileSystemFlags = 0;
408
409 dprintf2(("File system flags: %x", lpFileSystemFlags));
410 }
411
412 if(rc) {
413 SetLastError(rc);
414 return FALSE;
415 }
416 SetLastError(ERROR_SUCCESS);
417 return TRUE;
418}
419//******************************************************************************
420//******************************************************************************
421BOOL WIN32API GetVolumeInformationW(LPCWSTR lpRootPathName,
422 LPWSTR lpVolumeNameBuffer,
423 DWORD nVolumeNameSize,
424 PDWORD lpVolumeSerialNumber,
425 PDWORD lpMaximumComponentLength,
426 PDWORD lpFileSystemFlags,
427 LPWSTR lpFileSystemNameBuffer,
428 DWORD nFileSystemNameSize)
429{
430 char *asciiroot,
431 *asciivol,
432 *asciifs;
433 BOOL rc;
434
435 // transform into ascii
436 asciivol = (char *)malloc(nVolumeNameSize+1);
437 asciifs = (char *)malloc(nFileSystemNameSize+1);
438
439 // clear ascii buffers
440 memset (asciivol, 0, (nVolumeNameSize + 1));
441 memset (asciifs, 0, (nFileSystemNameSize + 1));
442
443 if (lpRootPathName != NULL) // NULL is valid!
444 asciiroot = UnicodeToAsciiString((LPWSTR)lpRootPathName);
445 else
446 asciiroot = NULL;
447
448 rc = GetVolumeInformationA(asciiroot, asciivol, nVolumeNameSize, lpVolumeSerialNumber,
449 lpMaximumComponentLength, lpFileSystemFlags, asciifs, nFileSystemNameSize);
450
451 if (lpVolumeNameBuffer != NULL) /* @@@PH 98/06/07 */
452 AsciiToUnicodeN(asciivol, lpVolumeNameBuffer, nVolumeNameSize);
453
454 if (lpFileSystemNameBuffer != NULL) /* @@@PH 98/06/07 */
455 AsciiToUnicodeN(asciifs, lpFileSystemNameBuffer, nFileSystemNameSize);
456
457 if (asciiroot != NULL)
458 FreeAsciiString(asciiroot);
459
460 free(asciifs);
461 free(asciivol);
462 return(rc);
463}
464//******************************************************************************
465//******************************************************************************
466DWORD WIN32API GetLogicalDrives(void)
467{
468 dprintf(("KERNEL32: GetLogicalDrives\n"));
469 return OSLibGetLogicalDrives();
470}
471//******************************************************************************
472//******************************************************************************
473UINT WIN32API GetLogicalDriveStringsA(UINT cchBuffer, LPSTR lpszBuffer)
474{
475 dprintf(("KERNEL32: GetLogicalDriveStringsA", cchBuffer, lpszBuffer));
476 return O32_GetLogicalDriveStrings(cchBuffer, lpszBuffer);
477}
478//******************************************************************************
479//******************************************************************************
480UINT WIN32API GetLogicalDriveStringsW(UINT nBufferLength, LPWSTR lpBuffer)
481{
482 char *asciibuffer = (char *)malloc(nBufferLength+1);
483 DWORD rc;
484
485 dprintf(("KERNEL32: OS2GetLogicalDriveStringsW\n"));
486
487 rc = O32_GetLogicalDriveStrings(nBufferLength, asciibuffer);
488 if(rc) AsciiToUnicode(asciibuffer, lpBuffer);
489 free(asciibuffer);
490 return(rc);
491}
492//******************************************************************************
493typedef struct {
494 HANDLE hLVMVolumeControlData;
495 DWORD lastvol;
496} VOLINFO;
497//******************************************************************************
498HANDLE WIN32API FindFirstVolumeA(LPTSTR lpszVolumeName, DWORD cchBufferLength)
499{
500 HANDLE hVolume;
501 VOLINFO *pVolInfo;
502 char szdrive[3];
503 char szVolume[256];
504
505 if(!VERSION_IS_WIN2000_OR_HIGHER()) {
506 SetLastError(ERROR_NOT_SUPPORTED);
507 return FALSE;
508 }
509
510 hVolume = GlobalAlloc(0, sizeof(VOLINFO));
511 if(hVolume == 0) {
512 dprintf(("ERROR: FindFirstVolumeA: out of memory!!"));
513 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
514 return 0;
515 }
516 pVolInfo = (VOLINFO *)GlobalLock(hVolume);
517 pVolInfo->hLVMVolumeControlData = OSLibLVMQueryVolumeControlData();
518 pVolInfo->lastvol = 0;
519
520 if(OSLibLVMQueryVolumeName(pVolInfo->hLVMVolumeControlData, &pVolInfo->lastvol, szVolume, sizeof(szVolume)) == FALSE) {
521 SetLastError(ERROR_NO_MORE_FILES);
522 goto fail;
523 }
524 if(strlen(szVolume) + 14 + 1 > cchBufferLength) {
525 SetLastError(ERROR_INSUFFICIENT_BUFFER);
526 goto fail;
527 }
528 sprintf(lpszVolumeName, VOLUME_NAME_PREFIX"{%s}\\", szVolume);
529 dprintf(("FindFirstVolumeA returned %s", lpszVolumeName));
530 pVolInfo->lastvol++;
531 GlobalUnlock(hVolume);
532 SetLastError(ERROR_SUCCESS);
533 return hVolume;
534
535fail:
536 GlobalUnlock(hVolume);
537 GlobalFree(hVolume);
538 return 0;
539}
540//******************************************************************************
541//******************************************************************************
542HANDLE WIN32API FindFirstVolumeW(LPWSTR lpszVolumeName, DWORD cchBufferLength)
543{
544 LPSTR pszvolname = NULL;
545 HANDLE hVolume;
546
547 if(!VERSION_IS_WIN2000_OR_HIGHER()) {
548 SetLastError(ERROR_NOT_SUPPORTED);
549 return FALSE;
550 }
551
552 if(cchBufferLength) {
553 pszvolname = (char *)alloca(cchBufferLength);
554 }
555 hVolume = FindFirstVolumeA(pszvolname, cchBufferLength);
556 if(hVolume) {
557 int len = MultiByteToWideChar( CP_ACP, 0, pszvolname, -1, NULL, 0);
558 MultiByteToWideChar(CP_ACP, 0, pszvolname, -1, lpszVolumeName, len);
559 }
560 return hVolume;
561}
562//******************************************************************************
563//******************************************************************************
564BOOL WIN32API FindNextVolumeA(HANDLE hFindVolume, LPTSTR lpszVolumeName,
565 DWORD cchBufferLength)
566{
567 VOLINFO *pVolInfo;
568 char szdrive[3];
569 DWORD DeviceType;
570 char szVolume[256];
571
572 if(!VERSION_IS_WIN2000_OR_HIGHER()) {
573 SetLastError(ERROR_NOT_SUPPORTED);
574 return FALSE;
575 }
576
577 pVolInfo = (VOLINFO *)GlobalLock(hFindVolume);
578 if(pVolInfo == NULL) {
579 SetLastError(ERROR_INVALID_PARAMETER);
580 return FALSE;
581 }
582 if(OSLibLVMQueryVolumeName(pVolInfo->hLVMVolumeControlData, &pVolInfo->lastvol,
583 szVolume, sizeof(szVolume)) == FALSE) {
584 SetLastError(ERROR_NO_MORE_FILES);
585 GlobalUnlock(hFindVolume);
586 return FALSE;
587 }
588 if(strlen(szVolume) + 14 + 1 > cchBufferLength) {
589 SetLastError(ERROR_INSUFFICIENT_BUFFER);
590 GlobalUnlock(hFindVolume);
591 return FALSE;
592 }
593 sprintf(lpszVolumeName, VOLUME_NAME_PREFIX"{%s}\\", szVolume);
594 dprintf(("FindNextVolumeA returned %s", lpszVolumeName));
595 pVolInfo->lastvol++;
596 GlobalUnlock(hFindVolume);
597 SetLastError(ERROR_SUCCESS);
598 return TRUE;
599}
600//******************************************************************************
601//******************************************************************************
602BOOL WIN32API FindNextVolumeW(HANDLE hFindVolume, LPWSTR lpszVolumeName,
603 DWORD cchBufferLength)
604{
605 LPSTR pszvolnameA = NULL;
606 BOOL ret;
607
608 if(!VERSION_IS_WIN2000_OR_HIGHER()) {
609 SetLastError(ERROR_NOT_SUPPORTED);
610 return FALSE;
611 }
612
613 if(cchBufferLength) {
614 pszvolnameA = (char *)alloca(cchBufferLength);
615 }
616 ret = FindNextVolumeA(hFindVolume, pszvolnameA, cchBufferLength);
617 if(ret) {
618 int len = MultiByteToWideChar( CP_ACP, 0, pszvolnameA, -1, NULL, 0);
619 MultiByteToWideChar(CP_ACP, 0, pszvolnameA, -1, lpszVolumeName, len);
620 }
621 return ret;
622}
623//******************************************************************************
624//******************************************************************************
625BOOL WIN32API FindVolumeClose(HANDLE hFindVolume)
626{
627 VOLINFO *pVolInfo;
628
629 if(!VERSION_IS_WIN2000_OR_HIGHER()) {
630 SetLastError(ERROR_NOT_SUPPORTED);
631 return FALSE;
632 }
633
634 if(hFindVolume) {
635 pVolInfo = (VOLINFO *)GlobalLock(hFindVolume);
636 OSLibLVMFreeVolumeControlData(pVolInfo->hLVMVolumeControlData);
637 GlobalUnlock(hFindVolume);
638 GlobalFree(hFindVolume);
639 return TRUE;
640 }
641 return FALSE;
642}
643//******************************************************************************
644//******************************************************************************
645HANDLE WIN32API FindFirstVolumeMountPointA(LPTSTR lpszRootPathName,
646 LPTSTR lpszVolumeMountPoint,
647 DWORD cchBufferLength)
648{
649 if(!VERSION_IS_WIN2000_OR_HIGHER()) {
650 SetLastError(ERROR_NOT_SUPPORTED);
651 return INVALID_HANDLE_VALUE;
652 }
653
654 SetLastError(ERROR_NO_MORE_FILES);
655 return INVALID_HANDLE_VALUE;
656}
657//******************************************************************************
658//******************************************************************************
659HANDLE WIN32API FindFirstVolumeMountPointW(LPWSTR lpszRootPathName,
660 LPWSTR lpszVolumeMountPoint,
661 DWORD cchBufferLength)
662{
663 LPSTR pszmountpointnameA = NULL;
664 LPSTR pszrootA = NULL;
665 HANDLE hVolume;
666
667 if(!VERSION_IS_WIN2000_OR_HIGHER()) {
668 SetLastError(ERROR_NOT_SUPPORTED);
669 return INVALID_HANDLE_VALUE;
670 }
671
672 if(cchBufferLength) {
673 pszmountpointnameA = (char *)alloca(cchBufferLength);
674 }
675 if(lpszRootPathName) {
676 pszrootA = (char *)alloca(lstrlenW(lpszRootPathName)+1);
677
678 int len = WideCharToMultiByte( CP_ACP, 0, lpszRootPathName, -1, NULL, 0, 0, NULL);
679 WideCharToMultiByte(CP_ACP, 0, lpszRootPathName, -1, pszrootA, len, 0, NULL);
680 }
681
682 hVolume = FindFirstVolumeMountPointA(pszrootA, pszmountpointnameA, cchBufferLength);
683 if(hVolume) {
684 int len = MultiByteToWideChar( CP_ACP, 0, pszmountpointnameA, -1, NULL, 0);
685 MultiByteToWideChar(CP_ACP, 0, pszmountpointnameA, -1, lpszVolumeMountPoint, len);
686 }
687 return hVolume;
688}
689//******************************************************************************
690//******************************************************************************
691BOOL WIN32API FindNextVolumeMountPointA(HANDLE hFindVolumeMountPoint,
692 LPTSTR lpszVolumeMountPoint,
693 DWORD cchBufferLength)
694{
695 if(!VERSION_IS_WIN2000_OR_HIGHER()) {
696 SetLastError(ERROR_NOT_SUPPORTED);
697 return FALSE;
698 }
699 SetLastError(ERROR_NO_MORE_FILES);
700 return FALSE;
701}
702//******************************************************************************
703//******************************************************************************
704BOOL WIN32API FindNextVolumeMountPointW(HANDLE hFindVolumeMountPoint,
705 LPWSTR lpszVolumeMountPoint,
706 DWORD cchBufferLength)
707{
708 LPSTR pszmoutpointnameA = NULL;
709 BOOL ret;
710
711 if(!VERSION_IS_WIN2000_OR_HIGHER()) {
712 SetLastError(ERROR_NOT_SUPPORTED);
713 return FALSE;
714 }
715
716 if(cchBufferLength) {
717 pszmoutpointnameA = (char *)alloca(cchBufferLength);
718 }
719 ret = FindFirstVolumeA(pszmoutpointnameA, cchBufferLength);
720 if(ret) {
721 int len = MultiByteToWideChar( CP_ACP, 0, pszmoutpointnameA, -1, NULL, 0);
722 MultiByteToWideChar(CP_ACP, 0, pszmoutpointnameA, -1, lpszVolumeMountPoint, len);
723 }
724 return ret;
725}
726//******************************************************************************
727//******************************************************************************
728BOOL WIN32API FindVolumeMountPointClose(HANDLE hFindVolumeMountPoint)
729{
730 if(!VERSION_IS_WIN2000_OR_HIGHER()) {
731 SetLastError(ERROR_NOT_SUPPORTED);
732 return FALSE;
733 }
734
735 if(hFindVolumeMountPoint) {
736 GlobalFree(hFindVolumeMountPoint);
737 return TRUE;
738 }
739 return FALSE;
740}
741//******************************************************************************
742//******************************************************************************
743BOOL WIN32API GetVolumeNameForVolumeMountPointA(LPCSTR lpszVolumeMountPoint,
744 LPSTR lpszVolumeName,
745 DWORD cchBufferLength)
746{
747 LPSTR pszvol;
748
749 pszvol = (char *)alloca(cchBufferLength);
750 if(pszvol == NULL) {
751 DebugInt3();
752 return FALSE;
753 }
754
755 if(!VERSION_IS_WIN2000_OR_HIGHER()) {
756 SetLastError(ERROR_NOT_SUPPORTED);
757 return FALSE;
758 }
759
760 if(OSLibLVMGetVolumeNameForVolumeMountPoint(lpszVolumeMountPoint, pszvol,
761 cchBufferLength) == TRUE)
762 {
763 int length = strlen(pszvol);
764 if(length + sizeof(VOLUME_NAME_PREFIX) - 1 + 3 > cchBufferLength) {
765 SetLastError(ERROR_INSUFFICIENT_BUFFER);
766 return FALSE;
767 }
768 sprintf(lpszVolumeName, VOLUME_NAME_PREFIX"{%s}\\", pszvol);
769
770 dprintf(("GetVolumeNameForVolumeMountPointA %s returned %s", lpszVolumeMountPoint, lpszVolumeName));
771 SetLastError(ERROR_SUCCESS);
772 return TRUE;
773 }
774 dprintf(("GetVolumeNameForVolumeMountPointA: %s not found!!", lpszVolumeMountPoint));
775 SetLastError(ERROR_FILE_NOT_FOUND);
776 return FALSE;
777}
778//******************************************************************************
779//******************************************************************************
780BOOL WIN32API GetVolumeNameForVolumeMountPointW(LPCWSTR lpszVolumeMountPoint,
781 LPWSTR lpszVolumeName,
782 DWORD cchBufferLength)
783{
784 LPSTR pszmoutpointnameA = NULL;
785 LPSTR pszvolumenameA = NULL;
786 BOOL ret;
787 int len;
788
789 if(!VERSION_IS_WIN2000_OR_HIGHER()) {
790 SetLastError(ERROR_NOT_SUPPORTED);
791 return FALSE;
792 }
793 len = WideCharToMultiByte( CP_ACP, 0, lpszVolumeMountPoint, -1, NULL, 0, 0, NULL);
794 pszmoutpointnameA = (char *)alloca(len+1);
795 WideCharToMultiByte(CP_ACP, 0, lpszVolumeMountPoint, -1, pszmoutpointnameA, len, 0, NULL);
796
797 if(cchBufferLength && lpszVolumeName) {
798 pszvolumenameA = (char *)alloca(cchBufferLength);
799 }
800 ret = GetVolumeNameForVolumeMountPointA(pszmoutpointnameA, pszvolumenameA, cchBufferLength);
801 if(ret) {
802 int len = MultiByteToWideChar( CP_ACP, 0, pszvolumenameA, -1, NULL, 0);
803 MultiByteToWideChar(CP_ACP, 0, pszvolumenameA, -1, lpszVolumeName, len);
804 }
805 return ret;
806}
807//******************************************************************************
808//******************************************************************************
Note: See TracBrowser for help on using the repository browser.