BUG: GetVolumeInformation Doesn't Return Volume Serial Number of Remote Drives on Windows 95/98
ID: Q234741
|
The information in this article applies to:
-
Microsoft Win32 Application Programming Interface (API), included with:
-
Microsoft Windows versions 95, 98
SYMPTOMS
Win32 programs use GetVolumeInformation() to retrieve information about local and remote volumes. On Windows 95 and Windows 98, 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.
Additional query words:
remote network drive serial number obtain
Keywords : kbAPI kbFileIO kbKernBase
Version : winnt:
Platform : winnt
Issue type : kbbug