Commit f18708fa authored by Stewart Brodie's avatar Stewart Brodie
Browse files

Now works against Windows NT 4.0 servers.

Detail:
  NT 4.0 Lan Manager appears not to like single character wildcards being
    used in some circumstances.  So I've thrown away all the code which
    handles this and replaced it with code which simply performs a complete
    directory search and doing the matching myself.  This also reduces the
    number of SMB transactions required to do a name translation to 1
    instead of 5 (except in the case of a directory containing an awful
    lot of entries)
  Contentious character handling fixed.  Previously if a doubly-mapped
    character was used, it would match any character instead of just
    itself and its partner.  eg. q+a would match qua instead of just
    q+a and q&a.
Admin:
  Checked desktop usage against STYX (NT 4 test machine) and against a
    Windows 98 server to confirm that support for that hasn't been affected
    by these changes.

Version 1.87, 1.1.1.1.2.8. Tagged as 'LanManFS-1_87-1_1_1_1_2_8'
parent 6cb00b82
...@@ -4,11 +4,11 @@ ...@@ -4,11 +4,11 @@
* *
*/ */
#define Module_MajorVersion_CMHG 1.87 #define Module_MajorVersion_CMHG 1.87
#define Module_MinorVersion_CMHG 1.1.1.1.2.7 #define Module_MinorVersion_CMHG 1.1.1.1.2.8
#define Module_Date_CMHG 19 Jan 1999 #define Module_Date_CMHG 22 Jan 1999
#define Module_MajorVersion "1.87" #define Module_MajorVersion "1.87"
#define Module_Version 187 #define Module_Version 187
#define Module_MinorVersion "1.1.1.1.2.7" #define Module_MinorVersion "1.1.1.1.2.8"
#define Module_Date "19 Jan 1999" #define Module_Date "22 Jan 1999"
...@@ -618,10 +618,13 @@ static const char lanmanfs_inverse_lookup_table[257]= ...@@ -618,10 +618,13 @@ static const char lanmanfs_inverse_lookup_table[257]=
"珀矣粤肄蓍裨跋鈿韵鴦"; "珀矣粤肄蓍裨跋鈿韵鴦";
/* These two structures MUST be kept in step in order to allow the
* wildcard resolution code function correctly
*/
static const char lanmanfs_contentious_characters[]= static const char lanmanfs_contentious_characters[]=
"+=><,\xa0"; "+=><,\xa0";
//static const char lanmanfs_contentious_pairing[]= static const char lanmanfs_contentious_pairing[]=
// "&@%$^\x20"; "&@%$^\x20";
static void Xlt_NameDOStoROX2 ( char *dst, char *src, RISCOS_ATTRIBS *pRA ) static void Xlt_NameDOStoROX2 ( char *dst, char *src, RISCOS_ATTRIBS *pRA )
{ {
...@@ -679,90 +682,116 @@ static int Xlt_CopyViaInverseTable( char *dst, const char *src, int blat ) ...@@ -679,90 +682,116 @@ static int Xlt_CopyViaInverseTable( char *dst, const char *src, int blat )
return wild_count; return wild_count;
} }
static err_t Xlt_LookupNameROtoDOSX2 ( char *dst, char *src ) typedef struct {
char *dstcpy;
char dstcpybuf[DOS_NAME_LEN + 4];
char matchbuf[DOS_NAME_LEN + 4];
} Xlt_NXCX2_Data;
/* An unusual routine. The SMB_ReadDirectoryEntriesX2 routine calls this
* function back in order to process each directory entry as it is
* discovered whilst we are searching for filename matches. In order to
* get that routine to stop when we have found a match, we return it a
* value of EOUTOFMEM. If we want it to continue, we return OK.
*/
static err_t Xlt_NameXlateCallbackX2 ( BYTE *entry, int format, void *_dst )
{ {
static char NameBuf[DOS_NAME_LEN + 4]; Xlt_NXCX2_Data *dst = _dst;
DOS_ATTRIBS dos_attr; char *eptr = (char *) (entry + 23);
int i, wild_count; char *dptr = 1 + strrchr(dst->matchbuf, '\\');
char *eos; err_t res = OK;
int already_has_extn = 0;
debug3("Xlt_NameXlateCallbackX2: checking `%s', against `%s' in `%s'\n",
eos = strchr(src, '\0'); (char *) entry + 23,
if ((eos - src) >= 5) { dptr,
int len, type; dst->dstcpybuf);
if (sscanf(eos-4, ",%x%n", &type, &len) == 1 && len == 3) {
already_has_extn = 1; for (;;) {
char e = *eptr++;
char d = *dptr++;
if (e == d || toupper(e) == toupper(d)) {
if (e) continue;
/* We have a match */
res = EOUTOFMEM;
break;
}
else if (e == ',' && d == 0) {
/* Might have been a filetype suffix */
int type, num;
if ((sscanf(eptr, "%x%n", &type, &num) == 1 && num == 3)
|| strcmp(eptr, FileString_DeadFile) == 0
|| strcmp(eptr, FileString_UntypedFile) == 0) {
/* It was */
res = EOUTOFMEM;
break;
}
}
else {
int i;
for (i=0; lanmanfs_contentious_characters[i]; ++i) {
if ((e == lanmanfs_contentious_characters[i] ||
e == lanmanfs_contentious_pairing[i]) &&
(d == lanmanfs_contentious_characters[i] ||
d == lanmanfs_contentious_pairing[i])) {
break; /* OK! */
}
}
if (lanmanfs_contentious_characters[i] == 0) return OK;
}
} }
}
NameBuf[0] = *dst++; /* Copy the A: bit of the name */ if (res == EOUTOFMEM) {
NameBuf[1] = *dst++; strcpy(dst->dstcpy, (char *) entry+23);
wild_count = Xlt_CopyViaInverseTable(NameBuf+2, src, 0); }
strcpy(dst, NameBuf+2); return res;
}
debug1("Looking for %s\n", NameBuf);
if (SMB_GetAttribs(NameBuf, &dos_attr) == OK) { static err_t Xlt_NameROtoDOSX2 ( char *dst, char *src )
debug0("Found verbatim\n"); {
return OK; static Xlt_NXCX2_Data private;
char *inptr;
err_t status;
private.matchbuf[0] = dst[0];
private.matchbuf[1] = dst[1];
Xlt_CopyViaInverseTable(private.matchbuf + 2, src, 0);
debug0("\n\n");
debug1("Xlt_NameROtoDOSX2: `%s'\n", src);
debug1("Xlt_CopyViaInverseTable -> `%s'\n", private.matchbuf);
strcpy(private.dstcpybuf, private.matchbuf);
private.dstcpy = strrchr(private.dstcpybuf, '\\');
if (private.dstcpy) {
strcpy(++private.dstcpy, "*");
} }
else {
eos = strchr(NameBuf, '\0'); private.dstcpy = strchr(private.dstcpybuf, '\0');
if (!already_has_extn) { strcpy(private.dstcpy, "\\*");
strcpy(eos, ",???");
debug1("Looking for %s\n", NameBuf);
if (SMB_GetAttribs(NameBuf, &dos_attr) == OK) {
strcpy(dst, NameBuf+2);
debug0("Had a type\n");
return OK;
}
} }
*eos = '\0'; debug1("Xlt_NameROtoDOSX2 initiates a dir search of `%s'\n",
if (wild_count == 0) return OK; private.dstcpybuf);
Xlt_CopyViaInverseTable(NameBuf+2, src, 1); /* Blat with wildcards */
debug1("Looking for %s\n", NameBuf); for (status = OK, inptr = private.dstcpybuf; status == OK; inptr = NULL) {
if (SMB_GetAttribs(NameBuf, &dos_attr) != OK) { status = SMB_ReadDirEntries(inptr, 512, Xlt_NameXlateCallbackX2,
if (!already_has_extn) { &private);
Xlt_CopyViaInverseTable(dst, src, 0); switch (status) {
return ENOTPRESENT; case OK:
} break;
strcpy(NameBuf+i, ",???"); case EOUTOFMEM:
debug1("Looking for %s\n", NameBuf); /* Found it */
if (SMB_GetAttribs(NameBuf, &dos_attr) != OK) { strcpy(dst, private.dstcpybuf);
Xlt_CopyViaInverseTable(dst, src, 0); /* Unblat */ debug1("\n**RIGHT. Got a match: `%s'\n", dst);
return ENOTPRESENT; break;
default:
/* Definitely didn't find it - revert to original filename */
strcpy(dst, private.matchbuf);
debug1("\n**WRONG. Not got a match. Reverting to `%s'\n", dst);
break;
} }
debug0("Had a type\n");
} }
debug0("Had contentious characters\n");
strcpy(dst, NameBuf+2);
return OK;
}
static err_t Xlt_NameXlateCallbackX2 ( BYTE *entry, int format, void *dst )
{
strcpy(dst, (char *) entry+23);
debug1("Xlt_NameXlateCallbackX2: `%s'\n", dst);
return EOUTOFMEM; /* Match first only */
}
static err_t Xlt_NameROtoDOSX2 ( char *dst, char *src )
{
debug1("Xlt_NameROtoDOSX2: `%s'\n", src);
if (Xlt_LookupNameROtoDOSX2 ( dst, src ) == OK) {
/* Need to perform a search to find the exact name now */
static char dstcpy[DOS_NAME_LEN];
err_t res;
debug1("Searching for a match for `%s'\n", dst);
strcpy(dstcpy, dst); /* Copy the wildcarded filespec */
res = SMB_ReadDirEntries(dstcpy, 1, Xlt_NameXlateCallbackX2,
1 + strrchr(dstcpy, '\\'));
strcpy(dst, dstcpy);
debug1("End of search for a match - result `%s'\n", dst);
}
return OK; return OK;
} }
#endif #endif
...@@ -1004,19 +1033,18 @@ err_t Xlt_SplitLeafnameX2 ( char *leafname, RISCOS_ATTRIBS *pRA, ...@@ -1004,19 +1033,18 @@ err_t Xlt_SplitLeafnameX2 ( char *leafname, RISCOS_ATTRIBS *pRA,
err_t res = ENOTPRESENT; err_t res = ENOTPRESENT;
const int fff00 = 0xFFF00; const int fff00 = 0xFFF00;
pRA->loadaddr = pRA->loadaddr | (fff00) | 0xFFF00000; pRA->loadaddr = pRA->loadaddr | (fff00) | 0xFFF00000;
*terminator = NULL; *terminator = NULL;
if (leafname == NULL) { if (leafname == NULL) {
return res; return res;
} }
debug1("Xlt_SplitLeafnameX2(%s,....)\n", leafname); debug1("Xlt_SplitLeafnameX2(\"%s\",....)\n", leafname);
term = strchr(leafname, '\0'); term = strchr(leafname, '\0');
if ((term - leafname) < 5) return res; if ((term - leafname) < 5) return res;
leafname = term - 4; leafname = term - 4;
if (leafname[0] != FileChar_TypedNamePrefix) return res; if (leafname[0] != FileChar_TypedNamePrefix) return res;
if (stricmp(leafname+1, FileString_UntypedFile) == 0) { if (stricmp(leafname+1, FileString_UntypedFile) == 0) {
pRA->loadaddr = pRA->execaddr = 0; pRA->loadaddr = pRA->execaddr = 0x03800000;
*terminator = leafname; *terminator = leafname;
res = OK; res = OK;
} }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment