I would like to detect whether a specific...
Articles and Tips: qna
01 Oct 2001
Q.
I would like to detect whether a specific volume is an NSS or a traditional one. Does anyone know how to do this?
A.
You can use NWGetExtendedVolumeInfo to obtain this information, as illustrated in the following sample code. You will note that the mask 0x80000000 checks for a NSS volume.
#include <nwdsapi.h> #include <nwdsconn.h> #include <nwvol.h> #include <stdio.h> #include <stdlib.h> int main( int argc, char* argv[]) { NWDSCCODE dsccode; NWDSContextHandle context; NWCCODE ccode; NWCONN_HANDLE conn_handle; nuint16 volNum; NWVolExtendedInfo volInfo; if ( argc != 3) { puts( "Usage: ExtVInfo <server name> <volume name>"); return EXIT_FAILURE; } dsccode = NWDSCreateContextHandle( &context); if ( dsccode != 0) { printf( "NWDSCreateContextHandle failed, dsccode = %x", dsccode); return EXIT_FAILURE; } ccode = NWDSLoginAsServer( context); if ( ccode != 0) { printf( "NWDSLoginAsServer failed, ccode = %x", ccode); NWDSFreeContext( context); return EXIT_FAILURE; } dsccode = NWDSOpenConnToNDSServer( context, argv[ 1], &conn_handle); if ( dsccode != 0) { printf( "NWDSOpenConnToNDSServer failed, dsccode = %x", dsccode); NWDSFreeContext( context); return EXIT_FAILURE; } dsccode = NWDSAuthenticateConn( context, conn_handle); if ( dsccode != 0) { printf( "NWDSAuthenticateConn failed, dsccode = %x", dsccode); NWDSFreeContext( context); return EXIT_FAILURE; } ccode = NWGetVolumeNumber( conn_handle, argv[ 2], &volNum); if ( ccode != 0) { printf( "NWGetVolumeNumber failed, ccode = %x", ccode); NWDSFreeContext( context); return EXIT_FAILURE; } ccode = NWGetExtendedVolumeInfo( conn_handle, volNum, &volInfo); if ( ccode != 0) { printf( "NWGetExtendedVolumeInfo failed, ccode = %x", ccode); NWDSFreeContext( context); return EXIT_FAILURE; } printf( "%s: %s", argv[ 2], volInfo.statusFlag & NWCompressionEnabledBit ? "compression enabled" : "compression NOT enabled"); printf( ", %s\n", volInfo.statusFlag & 0x80000000 ? "NSS" : "traditional"); printf( "sectorSize : %lu\n", volInfo.sectorSize); printf( "freeableLimboSectors : %lu\n", volInfo.freeableLimboSectors); printf( "nonfreeableLimboSectors : %lu\n", volInfo.nonfreeableLimboSectors); NWDSFreeContext( context); return EXIT_SUCCESS; } ...or assemble and send an NCP packet: #include <errno.h> #include <nit/nwdir.h> #include <nwconn.h> #include <nwerrno.h> #include <stdio.h> #include <stdlib.h> #include <string.h> int main( int argc, char* argv[]) { int volumeNumber; #include <npackon.h> // don't move this directive to a different location struct GetVolumeInformationLevel1RequestPacket { unsigned short SubFuncStrucLen; unsigned char SubFuncCode; unsigned long VolumeNumber; unsigned long InfoLevelNumber; } req; struct GetVolumeInformationLevel1ReplyPacket { unsigned long CurrentServerTime; unsigned char VConsoleVersion; unsigned char VConsoleRevision; unsigned short reserved; unsigned long InfoLevel; // VolInfoDef: unsigned long VolumeType; unsigned long StatusFlagBits; unsigned long SectorSize; unsigned long SectorsPerCluster; unsigned long VolumeSizeInClusters; unsigned long FreedClusters; unsigned long SubAllocFreeableClusters; unsigned long FreeableLimboSectors; unsigned long NonFreeableLimboSectors; unsigned long NonFreeableAvailableSubAllocSectors; unsigned long NonUsableSubAllocSectors; unsigned long SubAllocClusters; unsigned long DataStreamsCount; unsigned long LimboDataStreamsCount; unsigned long OldestDeletedFileAgeInTicks; unsigned long CompressedDataStreamsCount; unsigned long CompressedLimboDataStreamsCount; unsigned long UnCompressedDataStreamsCount; unsigned long PreCompressedSectors; unsigned long CompressedSectors; unsigned long MigratedFiles; unsigned long MigratedSectors; unsigned long ClustersUsedByFAT; unsigned long ClustersUsedByDirectories; unsigned long ClustersUsedByExtendedDirectories; unsigned long TotalDirectoryEntries; unsigned long UnusedDirectoryEntries; unsigned long TotalExtendedDirectoryExtants; unsigned long UnUsedExtendedDirectoryExtants; unsigned long ExtendedAttributesDefined; unsigned long ExtendedAttributeExtantsUsed; unsigned long DirectoryServicesObjectID; unsigned long VolumeLastModifiedDateAndTime; } rep; #include <npackoff.h> // don't move this directive to a different location int ccode; if ( argc != 2) { printf( "Usage: %s <vol_name>\n", argv[ 0]); return EXIT_FAILURE; } if ( GetVolumeNumber( argv[ 1], &volumeNumber) != 0) { printf( "GetVolumeNumber failed, errno = %d (%s), NetWareErrno = %d\n", errno, strerror( errno), NetWareErrno); return EXIT_FAILURE; } printf( "volumeNumber = %d\n", volumeNumber); req.SubFuncStrucLen = 0x900; // Hi-Lo req.SubFuncCode = 34; req.VolumeNumber = volumeNumber; req.InfoLevelNumber = 1; ccode = NWNCPSend( 123, &req, sizeof( req), &rep, sizeof( rep)); if ( ccode != ESUCCESS) { printf( "NWNCPSend failed, ccode = %d\n", ccode); return EXIT_FAILURE; } puts( rep.StatusFlagBits & 2 ? "compression enabled" : "compression not enabled"); puts( rep.StatusFlagBits & 0x80000000 ? "NSS" : "traditional"); return EXIT_SUCCESS; } <END>
* Originally published in Novell AppNotes
Disclaimer
The origin of this information may be internal or external to Novell. While Novell makes all reasonable efforts to verify this information, Novell does not make explicit or implied claims to its validity.