nwconn: implement Get Extended Volume Information
All checks were successful
Source release / source-package (push) Successful in 48s
All checks were successful
Source release / source-package (push) Successful in 48s
Wire NCP 0x16/0x33 Get Extended Volume Information to a real reply instead of returning 0xfb. The WebSDK documents NCP 0x2222/22/51 as taking a VolumeNumber and returning a low-high VolInfoReplyLen, an NWVolExtendedInfo structure, and a length-prefixed volume name. The SDK headers define NWVolExtendedInfo as 33 32-bit fields covering volume type, status flags, sector and cluster geometry, free-space counters, suballocation/limbo/compression/migration counters, directory counters, EA counters, a Directory Services object id, and a last-modified timestamp. Map the Unix filesystem data already used by the older volume-information calls to the core extended-volume fields: report a NetWare 386 v3.1 style volume type, 512-byte sectors, 8 sectors per cluster, total/free clusters, and directory-entry counters derived from fs_usage. Report NetWare-specific suballocation, limbo, compression, migration, EA, Directory Services, and timestamp fields as zero for now. Add the SDK request/reply semantics to the inline endpoint comment and remove the corresponding TODO entry. This enables the documented endpoint path while keeping the mapping conservative; fields MARS-NWE cannot currently model remain zero rather than guessed.
This commit is contained in:
106
src/nwconn.c
106
src/nwconn.c
@@ -1646,27 +1646,97 @@ static int handle_ncp_serv(void)
|
||||
|
||||
case 0x33 : { /* Get Extended Volume Information */
|
||||
/*
|
||||
* TODO(ncp-compat): Implement NCP 0x16/0x33
|
||||
* Get Extended Volume Information.
|
||||
* NCP 0x2222/22/51 Get Extended Volume Information
|
||||
*
|
||||
* SDK context: function 22 (0x16), subfunction 51 (0x33) takes
|
||||
* a VolumeNumber and returns VolInfoReplyLen, a VolumeInfo
|
||||
* structure, and the volume name. The documented VolumeInfo
|
||||
* structure contains fields such as VolumeType, StatusFlagBits,
|
||||
* SectorSize, SectorsPerCluster, VolumeSizeInClusters,
|
||||
* FreedClusters, directory-entry counters, EA counters, a
|
||||
* DirectoryServicesObjectID, and VolumeLastModifiedDateAndTime.
|
||||
* WebSDK / nwvol.h context:
|
||||
* Request:
|
||||
* byte VolumeNumber
|
||||
* Reply:
|
||||
* word VolInfoReplyLen (Lo-Hi)
|
||||
* NWVolExtendedInfo VolumeInfo (VolInfoReplyLen bytes)
|
||||
* byte VolNameLen
|
||||
* byte VolumeName[VolNameLen]
|
||||
*
|
||||
* The existing older volume-info calls return only the small
|
||||
* NetWare 2.x/3.x style subset, so filling this reply needs a
|
||||
* deliberate mapping from Unix filesystem data to the extended
|
||||
* SDK structure.
|
||||
* NWVolExtendedInfo contains 33 little-endian 32-bit fields:
|
||||
* volume type, status flags, sector/cluster geometry, total and
|
||||
* free cluster counts, suballocation/limbo/compression/migration
|
||||
* counters, directory-entry counters, EA counters, a Directory
|
||||
* Services object id, and the last-modified date/time.
|
||||
*
|
||||
* MARS-NWE maps the Unix filesystem data we already expose via
|
||||
* the older volume-information calls to the core geometry and
|
||||
* capacity fields. NetWare-specific suballocation, limbo,
|
||||
* compression, migration, EA, and DS fields are reported as zero.
|
||||
*/
|
||||
#if 0
|
||||
int volume = (int) *(p+1);
|
||||
/* next 3 byte are low bytes of volume */
|
||||
#endif
|
||||
completition = 0xfb; /* not known yet */
|
||||
struct XDATA {
|
||||
uint8 vol_info_reply_len[2];
|
||||
uint8 vol_type[4];
|
||||
uint8 status_flag[4];
|
||||
uint8 sector_size[4];
|
||||
uint8 sectors_per_cluster[4];
|
||||
uint8 vol_size_in_clusters[4];
|
||||
uint8 free_clusters[4];
|
||||
uint8 sub_alloc_freeable_clusters[4];
|
||||
uint8 freeable_limbo_sectors[4];
|
||||
uint8 nonfreeable_limbo_sectors[4];
|
||||
uint8 avail_sub_alloc_sectors[4];
|
||||
uint8 nonuseable_sub_alloc_sectors[4];
|
||||
uint8 sub_alloc_clusters[4];
|
||||
uint8 num_data_streams[4];
|
||||
uint8 num_limbo_data_streams[4];
|
||||
uint8 oldest_del_file_age_in_ticks[4];
|
||||
uint8 num_compressed_data_streams[4];
|
||||
uint8 num_compressed_limbo_data_streams[4];
|
||||
uint8 num_noncompressible_data_streams[4];
|
||||
uint8 precompressed_sectors[4];
|
||||
uint8 compressed_sectors[4];
|
||||
uint8 num_migrated_data_streams[4];
|
||||
uint8 migrated_sectors[4];
|
||||
uint8 clusters_used_by_fat[4];
|
||||
uint8 clusters_used_by_dirs[4];
|
||||
uint8 clusters_used_by_ext_dirs[4];
|
||||
uint8 total_dir_entries[4];
|
||||
uint8 unused_dir_entries[4];
|
||||
uint8 total_ext_dir_extants[4];
|
||||
uint8 unused_ext_dir_extants[4];
|
||||
uint8 ext_attrs_defined[4];
|
||||
uint8 ext_attr_extants_used[4];
|
||||
uint8 directory_services_object_id[4];
|
||||
uint8 vol_last_modified_date_and_time[4];
|
||||
uint8 vol_name_len;
|
||||
uint8 vol_name[16];
|
||||
} *xdata = (struct XDATA*) responsedata;
|
||||
uint8 name[100];
|
||||
int volume = (int) *(p+1);
|
||||
int result = nw_get_volume_name(volume, name, sizeof(name));
|
||||
|
||||
memset(xdata, 0, sizeof(struct XDATA));
|
||||
if (result > -1) {
|
||||
struct fs_usage fsp;
|
||||
int namlen = strlen((char*)name);
|
||||
|
||||
if (namlen > 16) namlen = 16;
|
||||
U16_TO_16(33 * 4, xdata->vol_info_reply_len);
|
||||
U32_TO_32(3, xdata->vol_type); /* VINetWare386v31 */
|
||||
U32_TO_32(512, xdata->sector_size);
|
||||
U32_TO_32(8, xdata->sectors_per_cluster); /* 4 KiB clusters */
|
||||
|
||||
if (!nw_get_fs_usage(name, &fsp, 0)) {
|
||||
U32_TO_32(fsp.fsu_blocks/8, xdata->vol_size_in_clusters);
|
||||
U32_TO_32(fsp.fsu_bavail/8, xdata->free_clusters);
|
||||
U32_TO_32(fsp.fsu_files, xdata->total_dir_entries);
|
||||
U32_TO_32(fsp.fsu_ffree, xdata->unused_dir_entries);
|
||||
}
|
||||
|
||||
xdata->vol_name_len = namlen;
|
||||
strmaxcpy(xdata->vol_name, name, namlen);
|
||||
data_len = 2 + (33 * 4) + 1 + namlen;
|
||||
XDPRINTF((5,0,
|
||||
"NCP22/33 GetExtendedVolumeInfo: vol=%d name=`%s` len=%d",
|
||||
volume, name, data_len));
|
||||
} else {
|
||||
completition = (uint8) -result;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user