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

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

CustForce2GBFileSize function added to force GetVolumeInformation to tell the app all partitions are FAT

File size: 30.7 KB
Line 
1/* $Id: disk.cpp,v 1.37 2002-05-14 09:28:19 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 //tetsetsetetsetsetset
573 SetLastError(ERROR_NO_MORE_FILES);
574 return FALSE;
575 //tetsetsetetsetsetset
576
577 if(!VERSION_IS_WIN2000_OR_HIGHER()) {
578 SetLastError(ERROR_NOT_SUPPORTED);
579 return FALSE;
580 }
581
582 pVolInfo = (VOLINFO *)GlobalLock(hFindVolume);
583 if(pVolInfo == NULL) {
584 SetLastError(ERROR_INVALID_PARAMETER);
585 return FALSE;
586 }
587 if(OSLibLVMQueryVolumeName(pVolInfo->hLVMVolumeControlData, pVolInfo->lastvol,
588 szVolume, sizeof(szVolume)) == FALSE) {
589 SetLastError(ERROR_NO_MORE_FILES);
590 GlobalUnlock(hFindVolume);
591 return FALSE;
592 }
593 if(strlen(szVolume) + 14 + 1 > cchBufferLength) {
594 SetLastError(ERROR_INSUFFICIENT_BUFFER);
595 GlobalUnlock(hFindVolume);
596 return FALSE;
597 }
598 sprintf(lpszVolumeName, VOLUME_NAME_PREFIX"{%s}\\", szVolume);
599 dprintf(("FindNextVolumeA returned %s", lpszVolumeName));
600 pVolInfo->lastvol++;
601 GlobalUnlock(hFindVolume);
602 SetLastError(ERROR_SUCCESS);
603 return TRUE;
604}
605//******************************************************************************
606//******************************************************************************
607BOOL WIN32API FindNextVolumeW(HANDLE hFindVolume, LPWSTR lpszVolumeName,
608 DWORD cchBufferLength)
609{
610 LPSTR pszvolnameA = NULL;
611 BOOL ret;
612
613 if(!VERSION_IS_WIN2000_OR_HIGHER()) {
614 SetLastError(ERROR_NOT_SUPPORTED);
615 return FALSE;
616 }
617
618 if(cchBufferLength) {
619 pszvolnameA = (char *)alloca(cchBufferLength);
620 }
621 ret = FindNextVolumeA(hFindVolume, pszvolnameA, cchBufferLength);
622 if(ret) {
623 int len = MultiByteToWideChar( CP_ACP, 0, pszvolnameA, -1, NULL, 0);
624 MultiByteToWideChar(CP_ACP, 0, pszvolnameA, -1, lpszVolumeName, len);
625 }
626 return ret;
627}
628//******************************************************************************
629//******************************************************************************
630BOOL WIN32API FindVolumeClose(HANDLE hFindVolume)
631{
632 VOLINFO *pVolInfo;
633
634 if(!VERSION_IS_WIN2000_OR_HIGHER()) {
635 SetLastError(ERROR_NOT_SUPPORTED);
636 return FALSE;
637 }
638
639 if(hFindVolume) {
640 pVolInfo = (VOLINFO *)GlobalLock(hFindVolume);
641 OSLibLVMFreeVolumeControlData(pVolInfo->hLVMVolumeControlData);
642 GlobalUnlock(hFindVolume);
643 GlobalFree(hFindVolume);
644 return TRUE;
645 }
646 return FALSE;
647}
648//******************************************************************************
649//******************************************************************************
650HANDLE WIN32API FindFirstVolumeMountPointA(LPTSTR lpszRootPathName,
651 LPTSTR lpszVolumeMountPoint,
652 DWORD cchBufferLength)
653{
654 if(!VERSION_IS_WIN2000_OR_HIGHER()) {
655 SetLastError(ERROR_NOT_SUPPORTED);
656 return FALSE;
657 }
658
659 SetLastError(ERROR_NO_MORE_FILES);
660 return 0;
661}
662//******************************************************************************
663//******************************************************************************
664HANDLE WIN32API FindFirstVolumeMountPointW(LPWSTR lpszRootPathName,
665 LPWSTR lpszVolumeMountPoint,
666 DWORD cchBufferLength)
667{
668 LPSTR pszmountpointnameA = NULL;
669 LPSTR pszrootA = NULL;
670 HANDLE hVolume;
671
672 if(!VERSION_IS_WIN2000_OR_HIGHER()) {
673 SetLastError(ERROR_NOT_SUPPORTED);
674 return FALSE;
675 }
676
677 if(cchBufferLength) {
678 pszmountpointnameA = (char *)alloca(cchBufferLength);
679 }
680 if(lpszRootPathName) {
681 pszrootA = (char *)alloca(lstrlenW(lpszRootPathName)+1);
682
683 int len = WideCharToMultiByte( CP_ACP, 0, lpszRootPathName, -1, NULL, 0, 0, NULL);
684 WideCharToMultiByte(CP_ACP, 0, lpszRootPathName, -1, pszrootA, len, 0, NULL);
685 }
686
687 hVolume = FindFirstVolumeMountPointA(pszrootA, pszmountpointnameA, cchBufferLength);
688 if(hVolume) {
689 int len = MultiByteToWideChar( CP_ACP, 0, pszmountpointnameA, -1, NULL, 0);
690 MultiByteToWideChar(CP_ACP, 0, pszmountpointnameA, -1, lpszVolumeMountPoint, len);
691 }
692 return hVolume;
693}
694//******************************************************************************
695//******************************************************************************
696BOOL WIN32API FindNextVolumeMountPointA(HANDLE hFindVolumeMountPoint,
697 LPTSTR lpszVolumeMountPoint,
698 DWORD cchBufferLength)
699{
700 if(!VERSION_IS_WIN2000_OR_HIGHER()) {
701 SetLastError(ERROR_NOT_SUPPORTED);
702 return FALSE;
703 }
704 SetLastError(ERROR_NO_MORE_FILES);
705 return FALSE;
706}
707//******************************************************************************
708//******************************************************************************
709BOOL WIN32API FindNextVolumeMountPointW(HANDLE hFindVolumeMountPoint,
710 LPWSTR lpszVolumeMountPoint,
711 DWORD cchBufferLength)
712{
713 LPSTR pszmoutpointnameA = NULL;
714 BOOL ret;
715
716 if(!VERSION_IS_WIN2000_OR_HIGHER()) {
717 SetLastError(ERROR_NOT_SUPPORTED);
718 return FALSE;
719 }
720
721 if(cchBufferLength) {
722 pszmoutpointnameA = (char *)alloca(cchBufferLength);
723 }
724 ret = FindFirstVolumeA(pszmoutpointnameA, cchBufferLength);
725 if(ret) {
726 int len = MultiByteToWideChar( CP_ACP, 0, pszmoutpointnameA, -1, NULL, 0);
727 MultiByteToWideChar(CP_ACP, 0, pszmoutpointnameA, -1, lpszVolumeMountPoint, len);
728 }
729 return ret;
730}
731//******************************************************************************
732//******************************************************************************
733BOOL WIN32API FindVolumeMountPointClose(HANDLE hFindVolumeMountPoint)
734{
735 if(!VERSION_IS_WIN2000_OR_HIGHER()) {
736 SetLastError(ERROR_NOT_SUPPORTED);
737 return FALSE;
738 }
739
740 if(hFindVolumeMountPoint) {
741 GlobalFree(hFindVolumeMountPoint);
742 return TRUE;
743 }
744 return FALSE;
745}
746//******************************************************************************
747//******************************************************************************
748BOOL WIN32API GetVolumeNameForVolumeMountPointA(LPCSTR lpszVolumeMountPoint,
749 LPSTR lpszVolumeName,
750 DWORD cchBufferLength)
751{
752 LPSTR pszvol;
753
754 pszvol = (char *)alloca(cchBufferLength);
755 if(pszvol == NULL) {
756 DebugInt3();
757 return FALSE;
758 }
759
760 if(!VERSION_IS_WIN2000_OR_HIGHER()) {
761 SetLastError(ERROR_NOT_SUPPORTED);
762 return FALSE;
763 }
764
765 if(OSLibLVMGetVolumeNameForVolumeMountPoint(lpszVolumeMountPoint, pszvol,
766 cchBufferLength) == TRUE)
767 {
768 int length = strlen(pszvol);
769 if(length + sizeof(VOLUME_NAME_PREFIX) - 1 + 3 > cchBufferLength) {
770 SetLastError(ERROR_INSUFFICIENT_BUFFER);
771 return FALSE;
772 }
773 sprintf(lpszVolumeName, VOLUME_NAME_PREFIX"{%s}\\", pszvol);
774
775 dprintf(("GetVolumeNameForVolumeMountPointA %s returned %s", lpszVolumeMountPoint, lpszVolumeName));
776 SetLastError(ERROR_SUCCESS);
777 return TRUE;
778 }
779 dprintf(("GetVolumeNameForVolumeMountPointA: %s not found!!", lpszVolumeMountPoint));
780 SetLastError(ERROR_FILE_NOT_FOUND);
781 return FALSE;
782}
783//******************************************************************************
784//******************************************************************************
785BOOL WIN32API GetVolumeNameForVolumeMountPointW(LPCWSTR lpszVolumeMountPoint,
786 LPWSTR lpszVolumeName,
787 DWORD cchBufferLength)
788{
789 LPSTR pszmoutpointnameA = NULL;
790 LPSTR pszvolumenameA = NULL;
791 BOOL ret;
792 int len;
793
794 if(!VERSION_IS_WIN2000_OR_HIGHER()) {
795 SetLastError(ERROR_NOT_SUPPORTED);
796 return FALSE;
797 }
798 len = WideCharToMultiByte( CP_ACP, 0, lpszVolumeMountPoint, -1, NULL, 0, 0, NULL);
799 pszmoutpointnameA = (char *)alloca(len+1);
800 WideCharToMultiByte(CP_ACP, 0, lpszVolumeMountPoint, -1, pszmoutpointnameA, len, 0, NULL);
801
802 if(cchBufferLength && lpszVolumeName) {
803 pszvolumenameA = (char *)alloca(cchBufferLength);
804 }
805 ret = GetVolumeNameForVolumeMountPointA(pszmoutpointnameA, pszvolumenameA, cchBufferLength);
806 if(ret) {
807 int len = MultiByteToWideChar( CP_ACP, 0, pszvolumenameA, -1, NULL, 0);
808 MultiByteToWideChar(CP_ACP, 0, pszvolumenameA, -1, lpszVolumeName, len);
809 }
810 return ret;
811}
812//******************************************************************************
813//******************************************************************************
Note: See TracBrowser for help on using the repository browser.