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

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

hard disk access updates & fixes

File size: 30.0 KB
Line 
1/* $Id: disk.cpp,v 1.36 2002-05-10 14:55:10 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 <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//******************************************************************************
274//******************************************************************************
275BOOL WIN32API GetVolumeInformationA(LPCSTR lpRootPathName,
276 LPSTR lpVolumeNameBuffer,
277 DWORD nVolumeNameSize,
278 PDWORD lpVolumeSerialNumber,
279 PDWORD lpMaximumComponentLength,
280 PDWORD lpFileSystemFlags,
281 LPSTR lpFileSystemNameBuffer,
282 DWORD nFileSystemNameSize)
283{
284 CHAR tmpstring[256];
285 CHAR szOrgFileSystemName[256] = "";
286 ULONG drive;
287 BOOL rc, fVolumeName = FALSE;
288 char *pszVolume;
289
290 dprintf(("GetVolumeInformationA %s", lpRootPathName));
291
292 if(lpRootPathName == NULL) {
293 GetCurrentDirectoryA(sizeof(tmpstring), tmpstring);
294 lpRootPathName = tmpstring;
295 }
296
297 if('A' <= *lpRootPathName && *lpRootPathName <= 'Z') {
298 drive = *lpRootPathName - 'A' + 1;
299 }
300 else
301 if('a' <= *lpRootPathName && *lpRootPathName <= 'z') {
302 drive = *lpRootPathName - 'a' + 1;
303 }
304 else {
305 //Volume functions only available in Windows 2000 and up
306 if(LOBYTE(GetVersion()) >= 5 && !strncmp(lpRootPathName, VOLUME_NAME_PREFIX, sizeof(VOLUME_NAME_PREFIX)-1))
307 {
308 int length;
309
310 //strip volume name prefix (\\\\?\\Volume\\)
311 length = strlen(lpRootPathName);
312 pszVolume = (char *)alloca(length);
313
314 if(OSLibLVMStripVolumeName(lpRootPathName, pszVolume, length))
315 {
316 pszVolume[length-2] = 0;
317 fVolumeName = TRUE;
318 goto proceed;
319 }
320 }
321 SetLastError(ERROR_INVALID_PARAMETER);
322 return FALSE;
323 }
324proceed:
325
326 if(lpVolumeSerialNumber || lpVolumeNameBuffer) {
327 if(fVolumeName) {
328 rc = OSLibLVMQueryVolumeSerialAndName(pszVolume, lpVolumeSerialNumber, lpVolumeNameBuffer, nVolumeNameSize);
329 }
330 else rc = OSLibDosQueryVolumeSerialAndName(drive, lpVolumeSerialNumber, lpVolumeNameBuffer, nVolumeNameSize);
331 if(lpVolumeSerialNumber) {
332 dprintf2(("Volume serial number: %x", *lpVolumeSerialNumber));
333 }
334 if(lpVolumeNameBuffer) {
335 dprintf2(("Volume name: %s", lpVolumeNameBuffer));
336 }
337 }
338 if(lpFileSystemNameBuffer || lpMaximumComponentLength || lpFileSystemFlags)
339 {
340 if(!lpFileSystemNameBuffer) {
341 lpFileSystemNameBuffer = tmpstring;
342 nFileSystemNameSize = sizeof(tmpstring);
343 }
344 if(fVolumeName) {
345 rc = OSLibLVMQueryVolumeFS(pszVolume, lpFileSystemNameBuffer, nFileSystemNameSize);
346 }
347 else rc = OSLibDosQueryVolumeFS(drive, lpFileSystemNameBuffer, nFileSystemNameSize);
348
349 //save original file system name
350 if(rc == ERROR_SUCCESS) strcpy(szOrgFileSystemName, lpFileSystemNameBuffer);
351
352 if(lpFileSystemNameBuffer)
353 {
354 dprintf2(("File system name: %s", lpFileSystemNameBuffer));
355 if(!strcmp(lpFileSystemNameBuffer, "JFS"))
356 {
357 strcpy(lpFileSystemNameBuffer, "NTFS");
358 }
359 else
360 if(!strcmp(lpFileSystemNameBuffer, "CDFS") ||
361 !strcmp(lpFileSystemNameBuffer, "UDF") ||
362 !strcmp(lpFileSystemNameBuffer, "NTFS") ||
363 !strcmp(lpFileSystemNameBuffer, "FAT32"))
364 {
365 //do nothing
366 }
367 else
368 {//pretend everything else is FAT16 (HPFS and FAT have the same file size limit)
369 strcpy(lpFileSystemNameBuffer, "FAT16");
370 }
371 dprintf2(("Final file system name: %s", lpFileSystemNameBuffer));
372 }
373 }
374 if(lpMaximumComponentLength) {
375 if(!strcmp(szOrgFileSystemName, "FAT16") || !strcmp(szOrgFileSystemName, "FAT")) {
376 *lpMaximumComponentLength = 12; //8.3
377 }
378 else *lpMaximumComponentLength = 255; //TODO: Always correct? (CDFS?)
379 }
380 if(lpFileSystemFlags)
381 {
382 if(strcmp(lpFileSystemNameBuffer, "FAT16")) {
383 *lpFileSystemFlags = FS_CASE_IS_PRESERVED;
384 }
385 else
386 if(!strcmp(lpFileSystemNameBuffer, "CDFS")) {
387 *lpFileSystemFlags = FS_CASE_SENSITIVE; //NT4 returns this
388 }
389 else
390 if(!strcmp(lpFileSystemNameBuffer, "UDF")) {//TODO: correct?
391 *lpFileSystemFlags = FS_CASE_SENSITIVE | FS_UNICODE_STORED_ON_DISK;
392 }
393 else *lpFileSystemFlags = 0;
394
395 dprintf2(("File system flags: %x", lpFileSystemFlags));
396 }
397
398 if(rc) {
399 SetLastError(rc);
400 return FALSE;
401 }
402 SetLastError(ERROR_SUCCESS);
403 return TRUE;
404}
405//******************************************************************************
406//******************************************************************************
407BOOL WIN32API GetVolumeInformationW(LPCWSTR lpRootPathName,
408 LPWSTR lpVolumeNameBuffer,
409 DWORD nVolumeNameSize,
410 PDWORD lpVolumeSerialNumber,
411 PDWORD lpMaximumComponentLength,
412 PDWORD lpFileSystemFlags,
413 LPWSTR lpFileSystemNameBuffer,
414 DWORD nFileSystemNameSize)
415{
416 char *asciiroot,
417 *asciivol,
418 *asciifs;
419 BOOL rc;
420
421 // transform into ascii
422 asciivol = (char *)malloc(nVolumeNameSize+1);
423 asciifs = (char *)malloc(nFileSystemNameSize+1);
424
425 // clear ascii buffers
426 memset (asciivol, 0, (nVolumeNameSize + 1));
427 memset (asciifs, 0, (nFileSystemNameSize + 1));
428
429 if (lpRootPathName != NULL) // NULL is valid!
430 asciiroot = UnicodeToAsciiString((LPWSTR)lpRootPathName);
431 else
432 asciiroot = NULL;
433
434 rc = GetVolumeInformationA(asciiroot,
435 asciivol,
436 nVolumeNameSize,
437 lpVolumeSerialNumber,
438 lpMaximumComponentLength,
439 lpFileSystemFlags,
440 asciifs,
441 nFileSystemNameSize);
442
443 if (lpVolumeNameBuffer != NULL) /* @@@PH 98/06/07 */
444 AsciiToUnicodeN(asciivol, lpVolumeNameBuffer, nVolumeNameSize);
445
446 if (lpFileSystemNameBuffer != NULL) /* @@@PH 98/06/07 */
447 AsciiToUnicodeN(asciifs, lpFileSystemNameBuffer, nFileSystemNameSize);
448
449
450 if (asciiroot != NULL)
451 FreeAsciiString(asciiroot);
452
453 free(asciifs);
454 free(asciivol);
455 return(rc);
456}
457//******************************************************************************
458//******************************************************************************
459DWORD WIN32API GetLogicalDrives(void)
460{
461 dprintf(("KERNEL32: GetLogicalDrives\n"));
462 return OSLibGetLogicalDrives();
463}
464//******************************************************************************
465//******************************************************************************
466UINT WIN32API GetLogicalDriveStringsA(UINT cchBuffer, LPSTR lpszBuffer)
467{
468 dprintf(("KERNEL32: GetLogicalDriveStringsA", cchBuffer, lpszBuffer));
469 return O32_GetLogicalDriveStrings(cchBuffer, lpszBuffer);
470}
471//******************************************************************************
472//******************************************************************************
473UINT WIN32API GetLogicalDriveStringsW(UINT nBufferLength, LPWSTR lpBuffer)
474{
475 char *asciibuffer = (char *)malloc(nBufferLength+1);
476 DWORD rc;
477
478 dprintf(("KERNEL32: OS2GetLogicalDriveStringsW\n"));
479
480 rc = O32_GetLogicalDriveStrings(nBufferLength, asciibuffer);
481 if(rc) AsciiToUnicode(asciibuffer, lpBuffer);
482 free(asciibuffer);
483 return(rc);
484}
485//******************************************************************************
486typedef struct {
487 HANDLE hLVMVolumeControlData;
488 DWORD lastvol;
489} VOLINFO;
490//******************************************************************************
491HANDLE WIN32API FindFirstVolumeA(LPTSTR lpszVolumeName, DWORD cchBufferLength)
492{
493 HANDLE hVolume;
494 VOLINFO *pVolInfo;
495 char szdrive[3];
496 char szVolume[256];
497
498 if(!VERSION_IS_WIN2000_OR_HIGHER()) {
499 SetLastError(ERROR_NOT_SUPPORTED);
500 return FALSE;
501 }
502
503 hVolume = GlobalAlloc(0, sizeof(VOLINFO));
504 if(hVolume == 0) {
505 dprintf(("ERROR: FindFirstVolumeA: out of memory!!"));
506 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
507 return 0;
508 }
509 pVolInfo = (VOLINFO *)GlobalLock(hVolume);
510 pVolInfo->hLVMVolumeControlData = OSLibLVMQueryVolumeControlData();
511 pVolInfo->lastvol = 0;
512
513 if(OSLibLVMQueryVolumeName(pVolInfo->hLVMVolumeControlData, pVolInfo->lastvol, szVolume, sizeof(szVolume)) == FALSE) {
514 SetLastError(ERROR_NO_MORE_FILES);
515 goto fail;
516 }
517 if(strlen(szVolume) + 14 + 1 > cchBufferLength) {
518 SetLastError(ERROR_INSUFFICIENT_BUFFER);
519 goto fail;
520 }
521 sprintf(lpszVolumeName, VOLUME_NAME_PREFIX"{%s}\\", szVolume);
522 dprintf(("FindFirstVolumeA returned %s", lpszVolumeName));
523 pVolInfo->lastvol++;
524 GlobalUnlock(hVolume);
525 SetLastError(ERROR_SUCCESS);
526 return hVolume;
527
528fail:
529 GlobalUnlock(hVolume);
530 GlobalFree(hVolume);
531 return 0;
532}
533//******************************************************************************
534//******************************************************************************
535HANDLE WIN32API FindFirstVolumeW(LPWSTR lpszVolumeName, DWORD cchBufferLength)
536{
537 LPSTR pszvolname = NULL;
538 HANDLE hVolume;
539
540 if(!VERSION_IS_WIN2000_OR_HIGHER()) {
541 SetLastError(ERROR_NOT_SUPPORTED);
542 return FALSE;
543 }
544
545 if(cchBufferLength) {
546 pszvolname = (char *)alloca(cchBufferLength);
547 }
548 hVolume = FindFirstVolumeA(pszvolname, cchBufferLength);
549 if(hVolume) {
550 int len = MultiByteToWideChar( CP_ACP, 0, pszvolname, -1, NULL, 0);
551 MultiByteToWideChar(CP_ACP, 0, pszvolname, -1, lpszVolumeName, len);
552 }
553 return hVolume;
554}
555//******************************************************************************
556//******************************************************************************
557BOOL WIN32API FindNextVolumeA(HANDLE hFindVolume, LPTSTR lpszVolumeName,
558 DWORD cchBufferLength)
559{
560 VOLINFO *pVolInfo;
561 char szdrive[3];
562 DWORD DeviceType;
563 char szVolume[256];
564
565 if(!VERSION_IS_WIN2000_OR_HIGHER()) {
566 SetLastError(ERROR_NOT_SUPPORTED);
567 return FALSE;
568 }
569
570 pVolInfo = (VOLINFO *)GlobalLock(hFindVolume);
571 if(pVolInfo == NULL) {
572 SetLastError(ERROR_INVALID_PARAMETER);
573 return FALSE;
574 }
575 if(OSLibLVMQueryVolumeName(pVolInfo->hLVMVolumeControlData, pVolInfo->lastvol,
576 szVolume, sizeof(szVolume)) == FALSE) {
577 SetLastError(ERROR_NO_MORE_FILES);
578 GlobalUnlock(hFindVolume);
579 return FALSE;
580 }
581 if(strlen(szVolume) + 14 + 1 > cchBufferLength) {
582 SetLastError(ERROR_INSUFFICIENT_BUFFER);
583 GlobalUnlock(hFindVolume);
584 return FALSE;
585 }
586 sprintf(lpszVolumeName, VOLUME_NAME_PREFIX"{%s}\\", szVolume);
587 dprintf(("FindNextVolumeA returned %s", lpszVolumeName));
588 pVolInfo->lastvol++;
589 GlobalUnlock(hFindVolume);
590 SetLastError(ERROR_SUCCESS);
591 return TRUE;
592}
593//******************************************************************************
594//******************************************************************************
595BOOL WIN32API FindNextVolumeW(HANDLE hFindVolume, LPWSTR lpszVolumeName,
596 DWORD cchBufferLength)
597{
598 LPSTR pszvolnameA = NULL;
599 BOOL ret;
600
601 if(!VERSION_IS_WIN2000_OR_HIGHER()) {
602 SetLastError(ERROR_NOT_SUPPORTED);
603 return FALSE;
604 }
605
606 if(cchBufferLength) {
607 pszvolnameA = (char *)alloca(cchBufferLength);
608 }
609 ret = FindNextVolumeA(hFindVolume, pszvolnameA, cchBufferLength);
610 if(ret) {
611 int len = MultiByteToWideChar( CP_ACP, 0, pszvolnameA, -1, NULL, 0);
612 MultiByteToWideChar(CP_ACP, 0, pszvolnameA, -1, lpszVolumeName, len);
613 }
614 return ret;
615}
616//******************************************************************************
617//******************************************************************************
618BOOL WIN32API FindVolumeClose(HANDLE hFindVolume)
619{
620 VOLINFO *pVolInfo;
621
622 if(!VERSION_IS_WIN2000_OR_HIGHER()) {
623 SetLastError(ERROR_NOT_SUPPORTED);
624 return FALSE;
625 }
626
627 if(hFindVolume) {
628 pVolInfo = (VOLINFO *)GlobalLock(hFindVolume);
629 OSLibLVMFreeVolumeControlData(pVolInfo->hLVMVolumeControlData);
630 GlobalUnlock(hFindVolume);
631 GlobalFree(hFindVolume);
632 return TRUE;
633 }
634 return FALSE;
635}
636//******************************************************************************
637//******************************************************************************
638HANDLE WIN32API FindFirstVolumeMountPointA(LPTSTR lpszRootPathName,
639 LPTSTR lpszVolumeMountPoint,
640 DWORD cchBufferLength)
641{
642 if(!VERSION_IS_WIN2000_OR_HIGHER()) {
643 SetLastError(ERROR_NOT_SUPPORTED);
644 return FALSE;
645 }
646
647 SetLastError(ERROR_NO_MORE_FILES);
648 return 0;
649}
650//******************************************************************************
651//******************************************************************************
652HANDLE WIN32API FindFirstVolumeMountPointW(LPWSTR lpszRootPathName,
653 LPWSTR lpszVolumeMountPoint,
654 DWORD cchBufferLength)
655{
656 LPSTR pszmountpointnameA = NULL;
657 LPSTR pszrootA = NULL;
658 HANDLE hVolume;
659
660 if(!VERSION_IS_WIN2000_OR_HIGHER()) {
661 SetLastError(ERROR_NOT_SUPPORTED);
662 return FALSE;
663 }
664
665 if(cchBufferLength) {
666 pszmountpointnameA = (char *)alloca(cchBufferLength);
667 }
668 if(lpszRootPathName) {
669 pszrootA = (char *)alloca(lstrlenW(lpszRootPathName)+1);
670
671 int len = WideCharToMultiByte( CP_ACP, 0, lpszRootPathName, -1, NULL, 0, 0, NULL);
672 WideCharToMultiByte(CP_ACP, 0, lpszRootPathName, -1, pszrootA, len, 0, NULL);
673 }
674
675 hVolume = FindFirstVolumeMountPointA(pszrootA, pszmountpointnameA, cchBufferLength);
676 if(hVolume) {
677 int len = MultiByteToWideChar( CP_ACP, 0, pszmountpointnameA, -1, NULL, 0);
678 MultiByteToWideChar(CP_ACP, 0, pszmountpointnameA, -1, lpszVolumeMountPoint, len);
679 }
680 return hVolume;
681}
682//******************************************************************************
683//******************************************************************************
684BOOL WIN32API FindNextVolumeMountPointA(HANDLE hFindVolumeMountPoint,
685 LPTSTR lpszVolumeMountPoint,
686 DWORD cchBufferLength)
687{
688 if(!VERSION_IS_WIN2000_OR_HIGHER()) {
689 SetLastError(ERROR_NOT_SUPPORTED);
690 return FALSE;
691 }
692 SetLastError(ERROR_NO_MORE_FILES);
693 return FALSE;
694}
695//******************************************************************************
696//******************************************************************************
697BOOL WIN32API FindNextVolumeMountPointW(HANDLE hFindVolumeMountPoint,
698 LPWSTR lpszVolumeMountPoint,
699 DWORD cchBufferLength)
700{
701 LPSTR pszmoutpointnameA = NULL;
702 BOOL ret;
703
704 if(!VERSION_IS_WIN2000_OR_HIGHER()) {
705 SetLastError(ERROR_NOT_SUPPORTED);
706 return FALSE;
707 }
708
709 if(cchBufferLength) {
710 pszmoutpointnameA = (char *)alloca(cchBufferLength);
711 }
712 ret = FindFirstVolumeA(pszmoutpointnameA, cchBufferLength);
713 if(ret) {
714 int len = MultiByteToWideChar( CP_ACP, 0, pszmoutpointnameA, -1, NULL, 0);
715 MultiByteToWideChar(CP_ACP, 0, pszmoutpointnameA, -1, lpszVolumeMountPoint, len);
716 }
717 return ret;
718}
719//******************************************************************************
720//******************************************************************************
721BOOL WIN32API FindVolumeMountPointClose(HANDLE hFindVolumeMountPoint)
722{
723 if(!VERSION_IS_WIN2000_OR_HIGHER()) {
724 SetLastError(ERROR_NOT_SUPPORTED);
725 return FALSE;
726 }
727
728 if(hFindVolumeMountPoint) {
729 GlobalFree(hFindVolumeMountPoint);
730 return TRUE;
731 }
732 return FALSE;
733}
734//******************************************************************************
735//******************************************************************************
736BOOL WIN32API GetVolumeNameForVolumeMountPointA(LPCSTR lpszVolumeMountPoint,
737 LPSTR lpszVolumeName,
738 DWORD cchBufferLength)
739{
740 LPSTR pszvol;
741
742 pszvol = (char *)alloca(cchBufferLength);
743 if(pszvol == NULL) {
744 DebugInt3();
745 return FALSE;
746 }
747
748 if(!VERSION_IS_WIN2000_OR_HIGHER()) {
749 SetLastError(ERROR_NOT_SUPPORTED);
750 return FALSE;
751 }
752
753 if(OSLibLVMGetVolumeNameForVolumeMountPoint(lpszVolumeMountPoint, pszvol,
754 cchBufferLength) == TRUE)
755 {
756 int length = strlen(pszvol);
757 if(length + sizeof(VOLUME_NAME_PREFIX) - 1 + 3 > cchBufferLength) {
758 SetLastError(ERROR_INSUFFICIENT_BUFFER);
759 return FALSE;
760 }
761 sprintf(lpszVolumeName, VOLUME_NAME_PREFIX"{%s}\\", pszvol);
762
763 dprintf(("GetVolumeNameForVolumeMountPointA %s returned %s", lpszVolumeMountPoint, lpszVolumeName));
764 SetLastError(ERROR_SUCCESS);
765 return TRUE;
766 }
767 dprintf(("GetVolumeNameForVolumeMountPointA: %s not found!!", lpszVolumeMountPoint));
768 SetLastError(ERROR_FILE_NOT_FOUND);
769 return FALSE;
770}
771//******************************************************************************
772//******************************************************************************
773BOOL WIN32API GetVolumeNameForVolumeMountPointW(LPCWSTR lpszVolumeMountPoint,
774 LPWSTR lpszVolumeName,
775 DWORD cchBufferLength)
776{
777 LPSTR pszmoutpointnameA = NULL;
778 LPSTR pszvolumenameA = NULL;
779 BOOL ret;
780 int len;
781
782 if(!VERSION_IS_WIN2000_OR_HIGHER()) {
783 SetLastError(ERROR_NOT_SUPPORTED);
784 return FALSE;
785 }
786 len = WideCharToMultiByte( CP_ACP, 0, lpszVolumeMountPoint, -1, NULL, 0, 0, NULL);
787 pszmoutpointnameA = (char *)alloca(len+1);
788 WideCharToMultiByte(CP_ACP, 0, lpszVolumeMountPoint, -1, pszmoutpointnameA, len, 0, NULL);
789
790 if(cchBufferLength && lpszVolumeName) {
791 pszvolumenameA = (char *)alloca(cchBufferLength);
792 }
793 ret = GetVolumeNameForVolumeMountPointA(pszmoutpointnameA, pszvolumenameA, cchBufferLength);
794 if(ret) {
795 int len = MultiByteToWideChar( CP_ACP, 0, pszvolumenameA, -1, NULL, 0);
796 MultiByteToWideChar(CP_ACP, 0, pszvolumenameA, -1, lpszVolumeName, len);
797 }
798 return ret;
799}
800//******************************************************************************
801//******************************************************************************
Note: See TracBrowser for help on using the repository browser.