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:
115
c32ncp.c
115
c32ncp.c
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user