dosutils: use NCP87 DOS info fields in NDIR

Add a Client32 NCP87 helper for obtaining DOS namespace file and
subdirectory information and use it in NDIR.

The new helper reads the classic NCP87 subfunction 6 RIM_ALL DOS info
block, including timestamps, inherited rights, directory identifiers and
size metadata.

Use the NCP87 inherited rights mask for the inherited-rights column while
keeping the existing Client32 effective-rights path for the effective
rights column.  Also use the NCP87 modify, archive, last-access and
creation date fields for the /DATES display, falling back to DOS
findfirst timestamps when the NCP87 info request is not available.

Tighten the /DATES layout so the full Created/Copied timestamp remains
within an 80-column DOS screen.
This commit is contained in:
Mario Fetka
2026-05-25 09:17:56 +02:00
parent 7117bfff68
commit 6d2d3f367f
5 changed files with 244 additions and 18 deletions

115
c32ncp.c
View File

@@ -314,6 +314,121 @@ int c32_ncp87_obtain_rim_attributes(const char *name,
}
int c32_ncp87_obtain_ndir_info(const char *path_name,
uint16 dir_handle,
C32_NDIR_INFO *info_out,
uint16 *actual_out,
uint16 *handle_lo_out,
uint16 *handle_hi_out)
{
uint16 handle_lo, handle_hi;
uint8 hdr[16];
uint8 path[0x140];
uint8 rep0[0x180];
uint8 rep1[0x40];
uint8 rawout[32];
uint16 raw_ret_ax, raw_ret_dx;
uint16 actual_lo;
UI path_len;
int rc;
int namelen;
if (!info_out)
return(1);
memset(info_out, 0, sizeof(*info_out));
if (actual_out) *actual_out = 0;
if (handle_lo_out) *handle_lo_out = 0;
if (handle_hi_out) *handle_hi_out = 0;
rc = c32_get_ncp_handle(&handle_lo, &handle_hi);
if (rc)
return(10 + rc);
/*
* NCP87 subfunction 6: Obtain File or Subdirectory Information.
*
* This asks for the classic DOS info block (RIM_ALL). ncpfs' old
* nw_info_struct layout is:
* +00 space allocated
* +04 attributes
* +20 creation time/date/id
* +28 modify time/date/id
* +36 last access date
* +38 archive time/date/id
* +46 inherited rights mask
* +48 directory numbers
* +76 name length/name
*/
memset(hdr, 0, sizeof(hdr));
hdr[0] = 6; /* NCP87 subfunction 6 */
hdr[1] = 0; /* source namespace DOS */
hdr[2] = 0; /* target namespace DOS */
c32_put_word_lh(hdr + 3, 0x0006); /* SA_ALL */
c32_put_dword_lh(hdr + 5, 0x00000FFFUL); /* RIM_ALL */
path_len = c32_build_handle_path_from_dos_path(path, (uint8)dir_handle,
0, 0, path_name);
memset(rep0, 0, sizeof(rep0));
memset(rep1, 0, sizeof(rep1));
memset(rawout, 0, sizeof(rawout));
C32_NCP87_Raw5_Probe(handle_lo, handle_hi,
hdr, 9,
path, path_len,
rep0, sizeof(rep0),
rep1, sizeof(rep1),
rawout);
raw_ret_ax = c32_get_word_lh(rawout + 14);
raw_ret_dx = c32_get_word_lh(rawout + 16);
actual_lo = c32_get_word_lh(rawout + 18);
if (actual_out) *actual_out = actual_lo;
if (handle_lo_out) *handle_lo_out = handle_lo;
if (handle_hi_out) *handle_hi_out = handle_hi;
if (raw_ret_ax != 0 || raw_ret_dx != 0)
return(20);
info_out->space_allocated = c32_get_dword_lh(rep0 + 0);
info_out->attributes = c32_get_dword_lh(rep0 + 4);
info_out->flags = c32_get_word_lh(rep0 + 8);
info_out->data_size = c32_get_dword_lh(rep0 + 10);
info_out->total_size = c32_get_dword_lh(rep0 + 14);
info_out->number_of_streams = c32_get_word_lh(rep0 + 18);
info_out->creation_time = c32_get_word_lh(rep0 + 20);
info_out->creation_date = c32_get_word_lh(rep0 + 22);
info_out->creator_id = c32_get_dword_hl(rep0 + 24);
info_out->modify_time = c32_get_word_lh(rep0 + 28);
info_out->modify_date = c32_get_word_lh(rep0 + 30);
info_out->modifier_id = c32_get_dword_hl(rep0 + 32);
info_out->last_access_date = c32_get_word_lh(rep0 + 36);
info_out->archive_time = c32_get_word_lh(rep0 + 38);
info_out->archive_date = c32_get_word_lh(rep0 + 40);
info_out->archiver_id = c32_get_dword_hl(rep0 + 42);
info_out->inherited_rights = c32_get_word_lh(rep0 + 46);
info_out->dir_ent_num = c32_get_dword_lh(rep0 + 48);
info_out->dos_dir_num = c32_get_dword_lh(rep0 + 52);
info_out->vol_number = c32_get_dword_lh(rep0 + 56);
info_out->ea_data_size = c32_get_dword_lh(rep0 + 60);
info_out->ea_key_count = c32_get_dword_lh(rep0 + 64);
info_out->ea_key_size = c32_get_dword_lh(rep0 + 68);
info_out->ns_creator = c32_get_dword_lh(rep0 + 72);
namelen = rep0[76];
if (namelen > 255)
namelen = 255;
info_out->name_len = (uint8)namelen;
memcpy(info_out->name, rep0 + 77, namelen);
info_out->name[namelen] = '\0';
return(0);
}
int c32_ncp87_modify_dos_attributes(char *name,
uint16 dir_handle,
uint32 attrs,