#3 Problem with GetVolumeInformation API might affect StSystem routines

open
nobody
7
2014-09-01
2003-02-11
Anonymous
No

Exported from Bugzilla, issue 2653.

--- Comment added on 3/25/2002 11:57:12 AM ---
The GetVolumeInformation API fails in certain contexts on Win9x OSs, this may
affect the following StSystem routines that use the API:

GetMediaID
IsDriveReady
ReadVolumeLabel

From Microsoft support:

http://support.microsoft.com/default.aspx?scid=kb;EN-US;q234741

-------------------->8 cut here 8<--------------------
BUG: GetVolumeInformation Doesn't Return Volume Serial Number of Remote Drives
on Windows (Q234741)

The information in this article applies to:

Microsoft Win32 Application Programming Interface (API), included with:
the operating system: Microsoft Windows 95
the operating system: Microsoft Windows 98
the operating system: Microsoft Windows Millennium Edition

SYMPTOMS

Win32 programs use GetVolumeInformation() to retrieve information about local
and remote volumes. On Microsoft Windows 95, Microsoft Windows 98, and Microsoft
Windows Millennium Edition (Me) GetVolumeInformation() does not retrieve the
actual serial number of remote volumes, but always returns zero for the volume
serial
number.

RESOLUTION

To obtain the volume serial number of a remote volume, open a file on the remote
volume and use GetFileInformationByHandle(). Part of the returned information is
the
serial number of the volume on which the file is located. This strategy works as
long as there is a file on the remote volume that can be opened. The following
sample
code demonstrates how to do this:

#define WIN32_LEAN_AND_MEAN

#include <windows.h>
#include <stdio.h>

BOOL GetVolumeSerialNumber (LPCSTR pszRootPathName, DWORD *pdwSerialNum);

void main (int argc, char **argv)
{
BOOL fResult;
char *pszDriveName;

// volume information we want to collect
char szVolName[MAX_PATH];
char szFileSysName[80];
DWORD dwSerialNumber;
DWORD dwMaxComponentLen;
DWORD dwFileSysFlags;

// Validate command-line arguments.
if (argc != 2)
{
printf("usage: %s drive\n\tdrive = C:\\, \\\\svr\\share\\\n",
argv[0]);
printf("\tnote: the trailing backslash is needed\n");
return;
}

pszDriveName = argv[1];

fResult = GetVolumeInformation(pszDriveName, szVolName, MAX_PATH,
&dwSerialNumber, &dwMaxComponentLen,
&dwFileSysFlags, szFileSysName, 80);
if (fResult)
{
// If the serial number wasn't returned, try to get it a
// different way.
if (dwSerialNumber == 0)
GetVolumeSerialNumber (pszDriveName, &dwSerialNumber);

printf("volume name = %s\n", szVolName);
printf("serial number = %#lx\n", dwSerialNumber);
}
else
printf("could not get info for %s, error = %lu\n",
pszDriveName, GetLastError());
}

/*
GetVolumeSerialNumber( pszRootPathName, pdwSerialNum )

Retrieves the serial number of a local or remote volume.

Parameters
pszRootPathName
The volume to get the serial number of. Must be specified as
one of:
A drive letter, colon and trailing backslash. C:\
A UNC name with trailing backslash. \\svr\share\

pdwSerialNum
A pointer to a DWORD that will contain the serial number when
the function returns. Note: the caller must allocate the memory
for this parameter.

Return value
Returns TRUE if it successfully retrieves a volume serial number, or
FALSE if it can't.
*/
BOOL GetVolumeSerialNumber (LPCSTR pszRootPathName, DWORD *pdwSerialNum)
{
BOOL bReturn = FALSE; // Assume that we haven't get the serial number,
// then set it to true if we do get it.

HANDLE hFile;
BY_HANDLE_FILE_INFORMATION bhFileInfo;

HANDLE hFileFind;
WIN32_FIND_DATA wfdFileData;
char szFindFileName[MAX_PATH];

/*
Search for any file that we can open and retrieve information about.
That information will include the serial number of the volume on
which the file resides.
*/
lstrcpy (szFindFileName, pszRootPathName);
lstrcat (szFindFileName, "*");

hFileFind = FindFirstFile (szFindFileName, &wfdFileData);
if (INVALID_HANDLE_VALUE == hFileFind)
goto EXIT_DONE;

do
{
/* Make sure that we've found a file and not a directory */
if (!(wfdFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
{
/*
Found a file. Now, use the full path to open the file and get
information about it. This information includes the serial
number of the volume on which the file resides. If we do get
the info, we can bail out because we're done.

If we can't open this file, look for another one we can open.
*/
lstrcpy (szFindFileName+lstrlen(pszRootPathName),
wfdFileData.cFileName);

hFile = CreateFile (szFindFileName,
0, // don't need to open for read or write
FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, 0, NULL);
if (INVALID_HANDLE_VALUE != hFile)
{
bReturn = GetFileInformationByHandle(hFile, &bhFileInfo);
CloseHandle(hFile);

if (bReturn)
break;
}
}
}
while (FindNextFile(hFileFind, &wfdFileData));
CloseHandle (hFileFind); /* don't need the find handle anymore */

/* If we have the serial number, return it to the caller */
if (bReturn )
{
__try
{
*pdwSerialNum = bhFileInfo.dwVolumeSerialNumber;
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
SetLastError (ERROR_INVALID_PARAMETER);
bReturn = FALSE;
}
}

EXIT_DONE:
return (bReturn);
}

STATUS

Microsoft has confirmed this to be a bug in the Microsoft products listed at the
beginning of this article.
-------------------->8 cut here 8<--------------------

Discussion


Log in to post a comment.

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:





No, thanks