nwconn: align AFP get and scan info layouts with WebSDK

This commit is contained in:
Mario Fetka
2026-05-30 20:55:53 +00:00
parent b1a5f9a0b3
commit f0864c1150

View File

@@ -1784,6 +1784,7 @@ static int afp_fill_file_info_response(const char *unixname,
const uint8 *display_path,
int display_path_len,
int volume,
int include_prodos_info,
uint8 *response,
uint32 *entry_id_out,
int *fallback_out)
@@ -1799,7 +1800,7 @@ static int afp_fill_file_info_response(const char *unixname,
entry_id = afp_get_or_create_entry_id(unixname, volume, &stbuff, fallback_out);
memset(response, 0, 120);
memset(response, 0, include_prodos_info ? 120 : 114);
U32_TO_BE32(entry_id, response + 0);
U32_TO_BE32(parent_id, response + 4);
U16_TO_BE16(afp_basic_attributes(volume, unixname, &stbuff), response + 8);
@@ -1854,7 +1855,7 @@ static int afp_fill_file_info_response(const char *unixname,
/* ProDOS info at offset 114 stays zero until a real Mac namespace maps it. */
if (entry_id_out) *entry_id_out = entry_id;
return(120);
return(include_prodos_info ? 120 : 114);
}
static int afp_get_file_information(uint8 *afp_req, int afp_len,
@@ -1909,7 +1910,8 @@ static int afp_get_file_information(uint8 *afp_req, int afp_len,
}
result = afp_fill_file_info_response(unixname, afp_req + 9, path_len,
volume, response, &entry_id, &fallback);
volume, afp_req[0] == 0x0f,
response, &entry_id, &fallback);
if (result < 0) {
XDPRINTF((2,0, "%s stat failed: vol=%d entry=0x%08x path='%s' unix='%s' result=-0x%x errno=%d",
call_name, (int)volume_number, request_entry_id,
@@ -2251,7 +2253,7 @@ static int afp_scan_file_information(uint8 *afp_req, int afp_len,
int seen = 0;
int result;
if (afp_len < 15) {
if (afp_len < 17) {
XDPRINTF((2,0, "%s rejected: short request len=%d",
call_name, afp_len));
return(-0x7e); /* NCP Boundary Check Failed */
@@ -2262,25 +2264,16 @@ static int afp_scan_file_information(uint8 *afp_req, int afp_len,
last_seen_id = GET_BE32(afp_req + 6);
/*
* WebSDK documents AFP Scan File Information (0x0a) and AFP 2.0 Scan
* File Information (0x11) with a DesiredResponseCount word between
* MacLastSeenID and SearchBitMap. Earlier smoke coverage used a compact
* internal layout without that word. Accept both so existing probes keep
* working, while new tests exercise the documented header layout.
* WebSDK / nwafp.h layout only. AFP has no mars_nwe compact request
* variant here: after the subfunction byte the packet contains volume,
* base entry ID, last-seen ID, desired response count, search bitmap,
* request bitmap, path length, then the AFP path string.
*/
if (afp_len >= 17 && afp_len >= 17 + (int)afp_req[16]) {
desired_count = GET_BE16(afp_req + 10);
search_mask = GET_BE16(afp_req + 12);
request_mask = GET_BE16(afp_req + 14);
path_len = (int)afp_req[16];
path_off = 17;
} else {
desired_count = 1;
search_mask = GET_BE16(afp_req + 10);
request_mask = GET_BE16(afp_req + 12);
path_len = (int)afp_req[14];
path_off = 15;
}
desired_count = GET_BE16(afp_req + 10);
search_mask = GET_BE16(afp_req + 12);
request_mask = GET_BE16(afp_req + 14);
path_len = (int)afp_req[16];
path_off = 17;
if (path_len < 0 || afp_len < path_off + path_len) {
XDPRINTF((2,0, "%s rejected: boundary check len=%d path_len=%d path_off=%d",
@@ -2332,7 +2325,7 @@ static int afp_scan_file_information(uint8 *afp_req, int afp_len,
child_entry_id = afp_get_or_create_entry_id(childname, volume, &stbuff,
&child_fallback);
if (last_seen_id && !seen) {
if (last_seen_id && last_seen_id != 0xffffffffU && !seen) {
if (child_entry_id == last_seen_id)
seen = 1;
continue;
@@ -2349,19 +2342,20 @@ static int afp_scan_file_information(uint8 *afp_req, int afp_len,
}
result = afp_fill_file_info_response(childname, display_path, display_path_len,
volume, response + 4,
volume, afp_req[0] == 0x11,
response + 2,
&entry_id, &fallback);
if (result < 0)
continue;
U32_TO_BE32(entry_id ? entry_id : child_entry_id, response);
U16_TO_BE16(1, response);
closedir(dir);
XDPRINTF((3,0, "%s: vol=%d entry=0x%08x last=0x%08x desired=%u mask=0x%04x req=0x%04x path='%s' reply_entry=0x%08x%s",
XDPRINTF((3,0, "%s: vol=%d entry=0x%08x last=0x%08x desired=%u mask=0x%04x req=0x%04x path='%s' count=1 reply_entry=0x%08x%s",
call_name, (int)volume_number, request_entry_id, last_seen_id,
(unsigned)desired_count, search_mask, request_mask,
visable_data(afp_req + path_off, path_len),
entry_id ? entry_id : child_entry_id,
(fallback || child_fallback) ? " fallback" : ""));
return(4 + 120);
return(2 + result);
}
closedir(dir);