Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 42 additions & 3 deletions kernel/dosfns.c
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,44 @@ const char FAR *get_basename(__XFAR(const char)fname)
return fname;
}

/* Extracts the device name from a path for IsDevice() validation.
* Preserves names with an optional trailing colon, while leaving
* bare drive specifications untouched.
*
* Examples:
* "NUL:" -> "NUL:"
* "C:\DIR\NUL:" -> "NUL:"
* "C:NUL:" -> "NUL:"
* "NUL" -> "NUL"
* "C:" -> ""
* "C:\DIR\FILE" -> "FILE"
*/
const char FAR *get_devname(__XFAR(const char) fname)
{
const char FAR *froot = get_basename(fname);
const char FAR *name_start;

/* If a valid basename was found, or the path doesn't end in ':', we're done */
if (*froot != '\0' || froot == fname || *(froot - 1) != ':')
return froot;

/* Walk back before the trailing ':' to find the start of the device token */
name_start = froot - 1;
while (name_start > fname &&
name_start[-1] != '/' &&
name_start[-1] != '\\' &&
name_start[-1] != ':')
{
name_start--;
}

/* Single-character prefixes before the colon (e.g., "C:") are bare drive specs */
if ((froot - 1) - name_start < 2)
return froot;

return name_start;
}

STATIC void ConvertPathNameToFCBName(char *FCBName, const char FAR *PathName)
{
ConvertNameSZToName83(FCBName, get_basename(PathName));
Expand Down Expand Up @@ -1423,7 +1461,7 @@ COUNT DosLockUnlock(COUNT hndl, LONG pos, LONG len, COUNT unlock)
struct dhdr FAR *IsDevice(__XFAR(const char)fname)
{
struct dhdr FAR *dhp;
const char FAR *froot = get_basename(fname);
const char FAR *froot = get_devname(fname);
int i;

/* /// BUG!!! This is absolutely wrong. A filename of "NUL.LST" must be
Expand Down Expand Up @@ -1464,8 +1502,9 @@ struct dhdr FAR *IsDevice(__XFAR(const char)fname)
for (i = 0; i < FNAME_SIZE; i++)
{
unsigned char c1 = (unsigned char)froot[i];
/* ignore extensions and handle filenames shorter than FNAME_SIZE */
if (c1 == '.' || c1 == '\0')
/* ignore extensions and handle filenames shorter than FNAME_SIZE;
a trailing colon ("NUL:") also ends the name */
if (c1 == '.' || c1 == '\0' || c1 == ':')
{
/* check if remainder of device name consists of spaces or nulls */
for (; i < FNAME_SIZE; i++)
Expand Down
5 changes: 4 additions & 1 deletion kernel/newstuff.c
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,7 @@ COUNT truename(__XFAR(const char) src, char FAR *dest, COUNT mode)
dest[2] = '\\';
if (result & IS_DEVICE)
{
froot = get_basename(src);
froot = get_devname(src);
if (froot == src || froot == src + 5)
{
if (froot == src + 5)
Expand Down Expand Up @@ -528,6 +528,9 @@ COUNT truename(__XFAR(const char) src, char FAR *dest, COUNT mode)
while(*src != '/' && *src != '\\' && *src != '\0')
{
char c = *src++;
/* "NUL:" - ignore the colon that follows a device name */
if (c == ':' && *src == '\0' && (result & IS_DEVICE))
break;
if (c == '*')
{
/* register the wildcard, even if no '?' is appended */
Expand Down
1 change: 1 addition & 0 deletions kernel/proto.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ __FAR(sft)get_sft(UCOUNT);

/* dosfns.c */
__FAR(const char)get_basename(__XFAR(const char));
__FAR(const char)get_devname(__XFAR(const char));
BOOL check_break(void);
UCOUNT GenericReadSft(__FAR(sft) sftp, UCOUNT n,__FAR(void) bp,
COUNT * err, BOOL force_binary);
Expand Down