Source
...
Target
Commits (2)
  • Ben Avison's avatar
    Compatibility change for Microsoft security fix MS09-001. · 3ba506cd
    Ben Avison authored
    Detail:
      Security fix MS09-001 (detailed in Microsoft Knowledge base article KB958687)
      fixes some vulnerabilities in the SMB protocol which LanManFS uses. This
      highlighted an error in SMB_WriteRaw which reported zero data bytes but then
      supplied an offset to the non existant bytes: this is now faulted by Windows.
      As there are no data bytes, the offset should also be zero.
    Admin:
      Fix received from Rob Sprowson 2009-01-19.
    
    Version 2.31. Tagged as 'LanManFS-2_31'
    3ba506cd
  • Ben Avison's avatar
    Multiple fixes. · 186192a3
    Ben Avison authored
    Detail:
      Too many to list here: see doc/RPSChanges.
    Admin:
      Received from Rob Sprowson approx 2009-02-08. Builds, but not tested by ROOL.
    
    Version 2.32. Tagged as 'LanManFS-2_32'
    186192a3
......@@ -14,4 +14,4 @@
|
Dir <Obey$Dir>
wimpslot 4000k
amu_machine rm.LanManFSD OPTIONS=-DCHECK_ARMBOOT_EXISTS SPRITES=RAM
amu_machine rm.LanManFSD OPTIONS=-DCHECK_ARMBOOT_EXISTS ROMSPRITES=FALSE
/* (2.30)
/* (2.32)
*
* This file is automatically maintained by srccommit, do not edit manually.
* Last processed by srccommit version: 1.68.
* Last processed by srccommit version: 1.1.
*
*/
#define Module_MajorVersion_CMHG 2.30
#define Module_MajorVersion_CMHG 2.32
#define Module_MinorVersion_CMHG
#define Module_Date_CMHG 16 Feb 2004
#define Module_Date_CMHG 15 Apr 2009
#define Module_MajorVersion "2.30"
#define Module_Version 230
#define Module_MajorVersion "2.32"
#define Module_Version 232
#define Module_MinorVersion ""
#define Module_Date "16 Feb 2004"
#define Module_Date "15 Apr 2009"
#define Module_ApplicationDate "16-Feb-04"
#define Module_ApplicationDate "15-Apr-09"
#define Module_ComponentName "LanManFS"
#define Module_ComponentPath "RiscOS/Sources/Networking/Omni/Protocols/LanManFS"
#define Module_FullVersion "2.30"
#define Module_HelpVersion "2.30 (16 Feb 2004)"
#define Module_LibraryVersionInfo "2:30"
#define Module_FullVersion "2.32"
#define Module_HelpVersion "2.32 (15 Apr 2009)"
#define Module_LibraryVersionInfo "2:32"
......@@ -40,6 +40,7 @@
#include "xlate.h"
#include "omni.h"
#include "LanMan.h"
#include "LMVars.h"
/* "Default" filetype logic ------------------------------------- */
......@@ -54,14 +55,13 @@ struct ext_type
int type;
};
static struct ext_type FTypes[] =
static const struct ext_type FTypes[] =
{
{ "TXT", 0xFFF }, /* Text */
{ "C", 0xFFF },
{ "H", 0xFFF },
{ "ASM", 0xFFF },
{ "ARC", 0xDDC }, /* Spark */
{ "TIF", 0xFF0 }, /* TIFF File */
{ "JPG", 0xC85 }, /* JPEG */
{ "PS", 0xFF5 }, /* Postscript */
{ NULL, 0 }
};
......@@ -70,7 +70,7 @@ static struct ext_type FTypes[] =
static void GetDefaultType ( char *leafname, RISCOS_ATTRIBS *ra )
{
struct ext_type *pET;
const struct ext_type *pET;
int ftype;
_kernel_swi_regs rset ;
......@@ -87,8 +87,9 @@ static void GetDefaultType ( char *leafname, RISCOS_ATTRIBS *ra )
leafname = strchr(leafname, '.');
if ( leafname == NULL ) /* No extension */
{
debug1("No suffix,assuming Text filetype for '%s'\n", leafname );
ra->loadaddr = Default_FileType << 8;
debug2("Assuming filetype %03x for '%s' due to no suffix\n", LM_Vars.default_type, leafname );
ra->loadaddr = (ra->loadaddr & 0xFFF000FF) |
(LM_Vars.default_type << 8);
return;
}
......@@ -100,7 +101,8 @@ static void GetDefaultType ( char *leafname, RISCOS_ATTRIBS *ra )
rset.r[2] = MMM_TYPE_RISCOS;
if (_kernel_swi(MimeMap_Translate, &rset, &rset) == NULL)
{
ra->loadaddr = rset.r[3] << 8;
ra->loadaddr = (ra->loadaddr & 0xFFF000FF) |
(rset.r[3] << 8);
debug2("Mimemap gave type %X for '%s'\n", rset.r[3], leafname );
return;
}
......@@ -365,7 +367,6 @@ err_t Attr_GetInfo ( char *filename, char *leafname,
return Attr_GetInfoX2 ( filename, leafname, pRA );
#endif
if ( SetFileName(filename) != OK )
return EBADNAME;
......
......@@ -39,53 +39,23 @@
#include "NameCache.h"
/* Some globals ================================== */
#define NAMEBUF_LEN (2*DOS_NAME_LEN)
#define name_R(x) ((char *)R[x])
static char DOSnamebuf [NAMEBUF_LEN];
static char DOSnamebuf[NAMEBUF_LEN];
static err_t FileGetAttribs ( char *filename, DOS_ATTRIBS *pda,
RISCOS_ATTRIBS *pra );
#define name_R(x) ((char *)R[x])
/* Func subroutines=============================================== */
#define NAMES_ONLY 14
#define MOST_INFO 15
#define ALL_INFO 19
/* Read-directory subroutines --------- */
/* The directory entries can take one of three forms, taking up
a variable degree of space
NAMES_ONLY - 16 bytes (12 bytes of name, plus 0 terminator, plus
word rounding).
MOST_INFO - 36 bytes
ALL_INFO - 44 bytes
*/
static char RD_CurrentPath[DOS_NAME_LEN];
/* Read-directory subroutines ======================================= */
static int RD_Reason;
static char *RD_BufPtr;
static int RD_BufLen;
static int RD_ReqCount; /* No. of entries required */
static int RD_ReqOffset; /* Offset of currently required dir entry */
static int RD_CurOffset; /* Offset of next entry to be given to
Dir_CallbackFn */
static int RD_CurCount; /* No. of entries given */
/* ---------------- */
/* SNB: the blocks being written are those required by:
* NAMES_ONLY => OS_GBPB 9 => (FSEntry_Func 14)
* MOST_INFO => OS_GBPB 10 => (FSEntry_Func 15)
* ALL_INFO => OS_GBPB 11 => (FSEntry_Func 19)
/* Write one directory entry to the supplied buffer
* The directory entries can take one of three forms, taking up
* a variable degree of space
*/
static char *WriteEntry ( int reason, char *ptr, BYTE *entry, int format )
{
......@@ -107,17 +77,18 @@ static char *WriteEntry ( int reason, char *ptr, BYTE *entry, int format )
Xlt_ExpandSearchEntry(entry, DOSnamebuf, namebuf, &da, &ra);
name_len = strlen(namebuf) + 1;
debug1("WriteEntry (%s)\n", namebuf);
switch ( reason )
{
case NAMES_ONLY:
case FSEntry_Func_Reason_ReadDirectoryEntries:
rec_len = name_len;
if (rec_len <= RD_BufLen) {
memcpy(ptr, namebuf, name_len);
}
break;
case MOST_INFO:
case FSEntry_Func_Reason_ReadDirectoriesAndInformation:
rec_len = (20+name_len+3) & ~3; /* Round up to whole word */
if (rec_len <= RD_BufLen) {
IntPtr = (int *)ptr;
......@@ -130,7 +101,7 @@ static char *WriteEntry ( int reason, char *ptr, BYTE *entry, int format )
}
break;
case ALL_INFO:
case FSEntry_Func_Reason_ReadDirectoryEntriesAndInformation:
rec_len = (29+name_len)+3 & ~3; /* Round up to whole word */
if (rec_len <= RD_BufLen) {
IntPtr = (int *)ptr;
......@@ -163,7 +134,7 @@ static char *WriteEntry ( int reason, char *ptr, BYTE *entry, int format )
/* ------------------------------ */
static err_t Dir_CallbackFn ( BYTE *entry, int format, void *pw )
static err_t Dir_CallbackFn ( BYTE *entry, int format, bool *taken, void *pw )
{
(void) pw;
#ifdef LONGNAMES
......@@ -187,48 +158,49 @@ static err_t Dir_CallbackFn ( BYTE *entry, int format, void *pw )
}
}
// debug3 ("Entry: current %d req %d count %d\n",
// RD_CurOffset, RD_ReqOffset, RD_ReqCount );
if ( RD_ReqOffset == RD_CurOffset )
{
*taken = false;
if ( RD_ReqCount > 0 )
{
char *w_result = WriteEntry ( RD_Reason, RD_BufPtr, entry, format );
if (w_result != NULL) {
RD_BufPtr = w_result;
RD_ReqCount--;
RD_ReqOffset++;
RD_CurCount++;
*taken = true;
}
else {
debug0("Oh dear - client ran out of buffer space!\n");
RD_CurOffset++;
return EOUTOFMEM;
}
}
}
RD_CurOffset++;
return OK;
}
/* ----------------- */
/* Called in 2 situations
* - starting a search from scratch (dir_offset = 0)
* - continuing a search (dir_offset != 0)
* The underlying SMB routine must track whether it has been called
* recursively or from within Xlt_NameROtoDOSX2_sub and deal with
* abandoning searches appropriately.
*/
static err_t Func_ReadDir ( int reason, char *path_name, char *buffer,
int n_names, int dir_offset, int buflen, int *pOutNread,
int *pOutNextOffset )
{
static Transact_SearchContext scon;
int tmp;
static Transact_SearchContext con;
int one_name;
err_t res;
debug2 ( "\n\n>> ReadDir reason %d path %s", reason, path_name );
debug2 ( " offset %d count %d\n", dir_offset, n_names );
debug2 ( " offset %d count %d", dir_offset, n_names );
debug1 ( " buflen %d\n", buflen);
/* Make sure the number of names we read will fit into buffer ---- */
tmp = (reason == NAMES_ONLY) ? 16 :
(reason == MOST_INFO) ? 36 : 44;
/* Make sure the number of names we read will fit into buffer */
one_name = (reason == FSEntry_Func_Reason_ReadDirectoryEntries) ? 16 :
(reason == FSEntry_Func_Reason_ReadDirectoriesAndInformation) ? 36 : 44;
#ifdef LONGNAMES
/* Of course, the above calculation assumes that the filename is at most
......@@ -245,104 +217,95 @@ static err_t Func_ReadDir ( int reason, char *path_name, char *buffer,
* unnecessary buffer overruns - especially when there are not very
* many files with long names or even no files with long names.
*/
/* There is no code inside this #ifdef - it just marks my comment. */
#endif
if ( n_names*tmp > buflen ) n_names = buflen/tmp;
if ( (n_names * one_name) > buflen ) n_names = buflen/one_name;
if ( n_names <= 0 ) return EBADPARAM;
debug1( "Adjusted count=%d\n", n_names );
RD_Reason = reason;
RD_BufPtr = buffer;
RD_BufLen = buflen;
RD_CurCount = 0;
RD_ReqCount = n_names;
RD_ReqOffset = dir_offset;
debug1("Actual count=%d\n", n_names );
/* Convert path adding wildcard search spec */
res = Xlt_ConvertPath( path_name, DOSnamebuf );
if ( res != OK ) return res;
tmp = strlen(DOSnamebuf);
if ( DOSnamebuf[strlen( DOSnamebuf ) - 1] != '\\' )
strcat( DOSnamebuf, "\\");
#ifdef LONGNAMES
if ( DOSnamebuf[tmp-1] == '\\' )
strcpy( DOSnamebuf+tmp, "*" );
else
strcpy( DOSnamebuf+tmp, "\\*" );
strcat( DOSnamebuf, "*" );
#else
if ( DOSnamebuf[tmp-1] == '\\' )
strcpy( DOSnamebuf+tmp, "????????.???" );
else
strcpy( DOSnamebuf+tmp, "\\????????.???" );
strcat( DOSnamebuf, "????????.???" );
#endif
/* Start a new search? ----------------------------------- */
if ( RD_ReqOffset == 0 || /* New start */
RD_ReqOffset < RD_CurOffset || /* Going back in search */
strcmp(DOSnamebuf, RD_CurrentPath) != 0 ) /* New directory */
/* Start a new search? */
if (dir_offset == 0)
{
debug1("\n>> Start search (%s)\n", DOSnamebuf);
strcpy ( RD_CurrentPath, DOSnamebuf);
RD_CurOffset = 0;
res = SMB_ReadDirEntries ( DOSnamebuf, RD_ReqCount+RD_ReqOffset,
Dir_CallbackFn, NULL, &scon );
debug2( ">> Start search (%s) count %d\n", DOSnamebuf, RD_ReqCount);
con.resume_key = 0;
res = SMB_ReadDirEntries ( DOSnamebuf, RD_ReqCount,
Dir_CallbackFn, NULL, &con );
}
else
else {
con.resume_key = dir_offset;
res = OK;
}
/* Continue search, if needs be */
while ( res == OK && /* More names available */
RD_ReqCount > 0 ) /* More names wanted */
{
debug0("\n>> Continue search\n");
res = SMB_ReadDirEntries ( NULL, RD_ReqCount+RD_ReqOffset-RD_CurOffset,
Dir_CallbackFn, NULL, &scon );
debug3( ">> Continue search (%s) count %d resume %08x\n", DOSnamebuf, RD_ReqCount, con.resume_key);
res = SMB_ReadDirEntries ( DOSnamebuf, RD_ReqCount,
Dir_CallbackFn, NULL, &con );
}
/* Process results */
if (res == EOUTOFMEM && RD_BufLen == -1) {
/* Special result when client buffer space exhausted */
debug0("Client buffer space was exhausted\n");
res = OK;
}
debug2("End search, res=%d RD_ReqCount=%d\n", res, RD_ReqCount);
if ( res != OK ) /* Ran out of files, or error */
{
RD_CurrentPath[0] = 0; /* Stop any repeat searches */
if ( res != OK ) { /* Ran out of files, or error */
*pOutNextOffset = -1;
}
else
{
if (RD_BufLen < 0) {
/* OK - was out of buffer space, force restart */
*pOutNextOffset = RD_ReqOffset;
//RD_CurOffset = 0;
//RD_CurrentPath[0] = 0;
}
else {
*pOutNextOffset = RD_ReqOffset;
}
}
*pOutNread = RD_ReqOffset-dir_offset;
*pOutNextOffset = con.resume_key;
*pOutNread = RD_CurCount;
if ( res == ENOMOREFILES )
return OK;
return res;
}
#if 0 /* Never called */
static err_t Func_ReadFreeSpace ( int sixtyfourbit, char *name, int *R )
{
_kernel_swi_regs r;
_kernel_oserror *err;
if (sixtyfourbit)
{
fspc_64 dsr[3];
r.r[0] = 4;
r.r[2] = (int) &dsr;
r.r[3] = (int) name;
err = Omni_FreeOp_SWI(&r);
if (err != NULL)
return ENOTPRESENT;
R[0] = dsr[1].lo;
R[1] = dsr[1].hi;
R[2] = 0x7FFFFFFF;
R[3] = dsr[0].lo;
R[4] = dsr[0].hi;
}
else
{
struct disk_size_response dsr;
r.r[0] = 2;
......@@ -353,24 +316,20 @@ static err_t Func_ReadFreeSpace ( int sixtyfourbit, char *name, int *R )
return ENOTPRESENT;
R[0] = dsr.freeblks;
if (sixtyfourbit) {
R[1] = R[4] = 0;
R[2] = 0x7FFFFFFF;
R[3] = dsr.totalblks;
}
else {
R[1] = 0x7FFFFFFF;
R[2] = dsr.totalblks;
}
return OK;
}
#endif
/* Func ============================================================= */
_kernel_oserror *fsentry_func ( int *R )
{
err_t err;
bool flushnames = false;
debug1("FS_func(%d)", R[0] );
......@@ -423,8 +382,10 @@ _kernel_oserror *fsentry_func ( int *R )
}
}
#endif
if ( err == OK )
if ( err == OK ) {
err = SMB_Rename ( DOSnamebuf, DOSnamebuf+DOS_NAME_LEN );
flushnames = true;
}
#ifdef LONGNAMES
if (SMB_IsLongNameFS(DOSnamebuf + DOS_NAME_LEN)) {
......@@ -476,11 +437,13 @@ _kernel_oserror *fsentry_func ( int *R )
case FSEntry_Func_Reason_BootFilingSystem:
LM_Boot();
err = OK;
flushnames = true;
break;
case FSEntry_Func_Reason_ShutDown:
/* On shutdown, disconnect all drives */
err = SMB_Shutdown();
flushnames = true;
break;
case FSEntry_Func_Reason_ReadDirectoryEntries:
......@@ -490,26 +453,13 @@ _kernel_oserror *fsentry_func ( int *R )
R[3], R[4], R[5], &R[3], &R[4] );
break;
case FSEntry_Func_Reason_ResolveWildcard:
/* Tell FileSwitch to do it itself */
R[4] = -1;
err = OK;
break;
case FSEntry_Func_Reason_ReadFreeSpace:
err = Func_ReadFreeSpace ( 0, name_R(1), R );
break;
case FSEntry_Func_Reason_ReadFreeSpace64:
err = Func_ReadFreeSpace ( 1, name_R(1), R );
break;
default:
err = EBADPARAM;
break;
}
#ifdef LONGNAMES
NameCache_Flush(ncf_FSFUNC_EXIT);
if (flushnames) NameCache_Flush(ncf_FSFUNC_EXIT);
#endif
return Xlt_Error(err);
......@@ -542,6 +492,7 @@ _kernel_oserror *fsentry_file( int *R )
int tmp;
DOS_ATTRIBS da;
RISCOS_ATTRIBS ra;
bool flushnames = false;
debug1("FS_file(%d)", R[0] );
......@@ -570,6 +521,7 @@ _kernel_oserror *fsentry_file( int *R )
ra.execaddr = R[3];
ra.flags = ROA_READ | ROA_WRITE;
Xlt_CnvROtoDOS(&ra, &da, CNV_DATETIME | CNV_ATTRIBS );
flushnames = true;
#ifdef LONGNAMES
strncpy(DOSnamebuf + DOS_NAME_LEN, DOSnamebuf, DOS_NAME_LEN);
if (Xlt_AddROType(DOSnamebuf, ra.loadaddr)) {
......@@ -637,6 +589,7 @@ _kernel_oserror *fsentry_file( int *R )
break;
}
flushnames = true;
if ( R[0] == FSEntry_File_Reason_WriteLoadAddress )
{
ra.loadaddr = R[2];
......@@ -675,6 +628,7 @@ _kernel_oserror *fsentry_file( int *R )
ra.loadaddr = R[2];
ra.execaddr = R[3];
ra.flags = R[5];
flushnames = true;
#ifdef LONGNAMES
{
......@@ -706,6 +660,7 @@ _kernel_oserror *fsentry_file( int *R )
R[3] = ra.execaddr;
R[4] = da.length;
R[5] = ra.flags;
flushnames = true;
if ( da.attr & ATTR_DIR )
{
......@@ -727,6 +682,7 @@ _kernel_oserror *fsentry_file( int *R )
case FSEntry_File_Reason_CreateDirectory:
Xlt_CnvRenameX2 ( DOSnamebuf, DOSnamebuf );
err = SMB_MkDir ( DOSnamebuf );
flushnames = true;
break;
/* Read information calls ---------------------------- */
......@@ -759,7 +715,7 @@ _kernel_oserror *fsentry_file( int *R )
}
#ifdef LONGNAMES
NameCache_Flush(ncf_FSFILE_EXIT);
if (flushnames) NameCache_Flush(ncf_FSFILE_EXIT);
#endif
return Xlt_Error(err);
......@@ -1058,6 +1014,7 @@ bool FS_Init(void)
for ( i=0; i<MAXFILES; i++ )
FileTbl[i].Free = true;
NextHandle = 0;
return true;
}
......@@ -43,7 +43,7 @@
#include "netbios.h"
#include "SMB.h"
#include "xlate.h"
#include "version.h"
#include "VersionNum"
#include "omni.h"
#include "printers.h"
#include "RPC.h"
......@@ -92,13 +92,6 @@ struct NETBIOS_TRANSPORT *NB_ActiveTransport; /* Selected net transport */
static pfnTransportInit NB_InitedTransport; /* Identify active transport */
static bool LM_Declared; /* True if we're registered as a filing system */
/* ------------------------------- */
char Default_FileTName[6];
int Default_FileType;
/* ------------------------------- */
#define CMOS_FSNUMBER 5
......@@ -340,21 +333,6 @@ static _kernel_oserror *Cmd_LanMan ( const char *args )
/* --------------------- */
#if 0
static char *(LM_local_num)(char *buf)
{
char *sep, *map, *space = buf;
if (_swix(Territory_ReadSymbols, _INR(0,1)|_OUT(0), -1, 1, &sep)) return buf;
if (_swix(Territory_ReadSymbols, _INR(0,1)|_OUT(0), -1, 2, &map)) return buf;
while (space && *sep) {
space = strchr(space, ' ');
if (space) *space = *sep;
}
return buf;
}
#endif
static _kernel_oserror *Cmd_Free ( const char *args )
{
_kernel_swi_regs r;
......@@ -376,18 +354,18 @@ static _kernel_oserror *Cmd_Free ( const char *args )
if (e == NULL) {
if (values[3] == 0 && values[5] == 0) {
printf("Bytes free &%08x\n", values[2] );
printf("Bytes free &%08X\n", values[2] );
if (values[4] != -1) {
printf("Bytes used &%08x\n", values[4] );
printf("Bytes used &%08X\n", values[4] );
}
else {
printf("Bytes used unavailable\n");
}
}
else {
printf("Bytes free &%08x%08x\n", values[3], values[2] );
printf("Bytes free &%08X%08X\n", values[3], values[2] );
if (values[4] != -1) {
printf("Bytes used &%08x%08x\n", values[5], values[4] );
printf("Bytes used &%08X%08X\n", values[5], values[4] );
}
else {
printf("Bytes used unavailable\n");
......@@ -484,6 +462,9 @@ static void SetDefaultVars ( void )
#endif
LM_Vars.initialised = LMInitState_Uninitialised;
LM_Vars.namemode = NM_FIRSTCAPS;
/* See where IP packets are going to be sent */
name = getenv("Inet$EtherType");
strcpyn ( LM_Vars.drivername,
(name==NULL) ? DEFAULT_ETHER_TYPE : name, NAME_LIMIT );
......@@ -500,10 +481,26 @@ static void SetDefaultVars ( void )
if ( name != NULL ) *name = 0;
}
/* Following 'get from CMOS' bits added 980127:RCE *
* to address user complain that it has to be typed in every time *
/* See if the user has overridden the default filetype */
name = getenv("LanMan$DefaultType");
if (name != NULL)
{
_swix(OS_FSControl, _INR(0,1)|_OUT(2), 31, name, &LM_Vars.default_type);
}
else
{
LM_Vars.default_type = CNV_DEFAULT_TYPE;
}
/* Read the base of the OS ROM so there's an address to use for
* untyped load/exec address, ensuring they would abort if used
*/
_swix(OS_Module, _INR(0,2)|_OUT(3), 12, 0, 0, &LM_Vars.untyped_address);
LM_Vars.untyped_address = LM_Vars.untyped_address & ~((1<<20) - 1);
/* Following 'get from CMOS' bits added 980127:RCE
* to address user complaints that it has to be typed in every time
*/
Lgn_Init();
GetFSName(fs_name);
if (fs_name[0] != '\0')
......@@ -511,20 +508,6 @@ static void SetDefaultVars ( void )
strcpy(LM_Vars.workgroup,fs_name);
}
LM_Vars.namemode = NM_FIRSTCAPS;
// load and convert default filetype to textual HEX
if(name = getenv(DefaultTypeEnvVar),name)
{
_swix(OS_FSControl,_INR(0,1)|_OUT(2),31,name,&Default_FileType);
}
else
{
Default_FileType=Default_File_Type_Number;
}
sprintf(Default_FileTName,",%03x",Default_FileType);
/* Set transport type from CMOS, unless overridden on command line */
#ifdef NO_NETBEUI
LanMan_InitTransport(NB_NBIP_Setup);
......@@ -564,7 +547,10 @@ static _kernel_oserror *Cmd_LMInfo ( const char *args )
(void) args;
Omni_Debug();
if (LM_Vars.verbose)
{
printf("Status: %s\n", LM_Status());
Stat_Show();
}
return NULL;
}
......@@ -641,15 +627,6 @@ static _kernel_oserror *Cmd_LMPrinters ( const char *args )
/* --------------------- */
static _kernel_oserror *Cmd_LMStats ( const char *args )
{
(void) args;
Stat_Show();
return NULL;
}
/* --------------------- */
static _kernel_oserror *Cmd_FS ( const char *args )
{
/* This is a *Configure/Status command handler - it's therefore unusual */
......@@ -792,7 +769,6 @@ static CommandFnPtr Cmd_Dispatch[] =
CmdEntry(LMLogoff),
CmdEntry(LMServer),
CmdEntry(LMPrinters),
CmdEntry(LMStats),
CmdEntry(FS),
CmdEntry(LMTransport),
CmdEntry(LMNameServer),
......@@ -936,7 +912,7 @@ static err_t ProcessCmdLine ( const char *_line )
case 'H':
case '?':
printf( "Lan Man client for RISCOS, version " VERSION_STRING
printf( "SMB client for RISCOS, version " Module_FullVersion
"\nWritten by Ian Harvey 1994-1996\nUse:\n"
"\t-dea0\tto use 'ea0' for network driver (etc)\n"
"\t-n\tto disable network browsing\n"
......@@ -1183,7 +1159,7 @@ static _kernel_oserror *LM_init_phase_2(void)
/*LM_StartupBoot();*/
if (want_boot) {
if (LM_Vars.verbose) printf("Booting ...\n");
if (LM_Vars.verbose) printf("Booting...\n");
LM_Boot();
}
......
......@@ -92,7 +92,7 @@
/* ---------------- */
struct status_resp /* Structure used to process STATUS_RESPOMSE */
struct status_resp /* Structure used to process STATUS_RESPONSE */
{
int nt_search; /* Name-type to respond to */
struct FindName_res *pRes; /* Pointer to result buf */
......@@ -273,8 +273,11 @@ EXPORT nametype_t _NB_DecodeName ( NETNAME *pnn, char *buf )
static uint NB_GetTime (void)
{
/* This is well-defined for RISCOS */
return * (uint *)0x10C;
uint tick;
/* Centisecond tick */
(void) _swix(OS_ReadMonotonicTime, _OUT(0), &tick);
return tick;
}
......@@ -1334,7 +1337,7 @@ static NAME_ENTRY *FindRemoteName ( NETNAME *pnn )
NBIP_CallbackFn_handler();
if (pNE->status == RMT_FOUND)
{
debug1("Name found at %lX\n", pNE->IPaddress.s_addr);
debug1("Name found at %X\n", pNE->IPaddress.s_addr);
return pNE;
}
}
......@@ -1358,7 +1361,7 @@ static NAME_ENTRY *FindRemoteName ( NETNAME *pnn )
pNE->TTL_StartTime = NB_GetTime();
pNE->TTL_Interval = 1; /* Doesn't last for long */
pNE->IPaddress = GetIPAddr ( (BYTE *) (pHE->h_addr_list[0]) );
debug1("Name found in hosts at %lX\n", pNE->IPaddress.s_addr);
debug1("Name found in hosts at %X\n", pNE->IPaddress.s_addr);
return pNE;
}
......@@ -1626,7 +1629,7 @@ static bool ReadData ( int sid, BYTE *where, int len, uint timeout, int flags )
if ( NB_GetTime() - tstart > timeout )
{
debug0("Timeout\n");
if ( timeout > 0) debug1("Timeout after %dcs\n", timeout);
return false;
}
}
......@@ -1641,7 +1644,7 @@ static err_t ConnectAttempt ( NBIP_SESSION *pNS, NETNAME *pnnFarEnd )
struct sockaddr_in sa;
BYTE *p; uint len;
debug2("Attempting to connect - addr=%lXh, port %d\n",
debug2("Attempting to connect - addr=%Xh, port %d\n",
pNS->rmt_addr.sin_addr.s_addr, ntohs(pNS->rmt_addr.sin_port) );
/* Entered with pNS->sid = a socket descriptor, and pNS->rmt_addr is
......@@ -1698,7 +1701,7 @@ static err_t ConnectAttempt ( NBIP_SESSION *pNS, NETNAME *pnnFarEnd )
return EDATALEN;
pNS->rmt_addr.sin_addr = GetIPAddr( DatagramBuf );
pNS->rmt_addr.sin_port = htons(GetShort( DatagramBuf+4 ));
debug2("Retargeted to %lXh, port %d\n",
debug2("Retargeted to %Xh, port %d\n",
pNS->rmt_addr.sin_addr.s_addr, ntohs(pNS->rmt_addr.sin_port) );
return ERETARGET;
}
......
......@@ -102,12 +102,11 @@ static void NameCache_Exit(void)
{
free(NameCache.data);
NameCache.data = NULL;
debug1("NameCache hits: %d\n", NameCache.hits);
}
void NameCache_Flush(ncf_reason why)
{
debug1("NameCacheFlush(reason = %d)\n", why);
debug2("NameCacheFlush(reason = %d) hits %d\n", why, NameCache.hits);
if (why == ncf_REINIT) NameCache.hits = 0;
if (NameCache.data) {
NameCache.head = 0;
......
......@@ -85,7 +85,7 @@
/* ---------------- */
struct status_resp /* Structure used to process STATUS_RESPOMSE */
struct status_resp /* Structure used to process STATUS_RESPONSE */
{
int nt_search; /* Name-type to respond to */
struct FindName_res *pRes; /* Pointer to result buf */
......
......@@ -51,7 +51,7 @@
#include "rpc.h"
#include "lanman.h"
#include "printers.h"
#include "version.h"
#include "VersionNum"
#include "xlate.h"
#include "lmvars.h"
#include "stats.h"
......@@ -90,7 +90,6 @@
typedef struct namelist NAMELIST; /* Our general holds-everything list */
/* Information on a server */
struct server_extra_info
{
NAMELIST *known_disks; /* -> list of D_VALID_TAG records */
......@@ -100,10 +99,7 @@ struct server_extra_info
char info_string[INFO_STR_LEN];
};
/* ------------------------ */
/* Information on a current connection */
struct mount_extra_info
{
NAMELIST *servername; /* Server ID -> S_VALID_TAG record*/
......@@ -119,7 +115,6 @@ struct share_extra_info
};
/* Multipurpose name-list structure */
struct namelist
{
int tag; /* One or other VALID_TAG */
......@@ -136,20 +131,13 @@ struct namelist
struct namelist *master_link;
};
/* ------------------------------------- */
static NAMELIST *MasterList = NULL; /* List of everything we've malloc'd */
static NAMELIST *FreeList = NULL; /* Used for deleted items */
static NAMELIST *MountsList = NULL; /* Current mounts */
static NAMELIST *ServerList = NULL; /* Known servers (known disks/printers
hang off the side of this list) */
/* Name-list functions ***************************** */
/* This adds a given name to a list, and returns a pointer to
the item. If an item of the same name already exists on
the list, no allocation is performed; the existing item
is returned. New allocations have all their 'extra_info'
fields set to zero.
*/
/* Name-list functions ============================================= */
static NAMELIST *alloc_nl(void)
{
......@@ -180,13 +168,11 @@ static NAMELIST *alloc_nl(void)
return pNL;
}
/* ----------------------- */
/* FreeAllLists() ---------------------------------*/
/* This frees everything we've allocated; it also does some
heavy deletion of things to prevent grief if it gets called
twice, etc.
*/
static void FreeAllLists(void)
{
NAMELIST *pNL, *pNL2;
......@@ -205,8 +191,13 @@ static void FreeAllLists(void)
}
/* =========================================== */
/* AddToList() ------------------------------------*/
/* This adds a given name to a list, and returns a pointer to
the item. If an item of the same name already exists on
the list, no allocation is performed; the existing item
is returned. New allocations have all their 'extra_info'
fields set to zero.
*/
static NAMELIST *AddToList( NAMELIST **pListHead, int valid_tag,
char *name_in )
{
......@@ -248,8 +239,7 @@ static NAMELIST *AddToList( NAMELIST **pListHead, int valid_tag,
return pNLnew;
}
/* ------------------ */
/* FindInList() -----------------------------------*/
static NAMELIST *FindInList ( NAMELIST *ListHead, char *name_in )
{
NAMELIST *pNL;
......@@ -271,8 +261,7 @@ static NAMELIST *FindInList ( NAMELIST *ListHead, char *name_in )
return NULL; /* Not found */
}
/* ------------------------- */
/* DeleteFromList() -------------------------------*/
static void DeleteFromList( NAMELIST **pListHead, NAMELIST *item )
{
NAMELIST *pNL;
......@@ -297,25 +286,14 @@ static void DeleteFromList( NAMELIST **pListHead, NAMELIST *item )
FreeList = item;
}
/* Main Routines =================================================== */
static NAMELIST *MountsList = NULL; /* Current mounts */
static NAMELIST *ServerList = NULL; /* Known servers (known disks/printers
hang off the side of this list) */
/* ---------------------------- */
/* FindActiveMount()
Given a disk (D_VALID_TAG) record, finds out if it is the current
/* FindActiveMount() ------------------------------*/
/* Given a disk (D_VALID_TAG) record, finds out if it is the current
active mounts list. If so, returns a NAMELIST * for the corresponding
entry in the list.
If not, returns NULL.
*/
static NAMELIST *FindActiveMount ( NAMELIST *pD )
{
NAMELIST *pNL;
......@@ -327,9 +305,7 @@ static NAMELIST *FindActiveMount ( NAMELIST *pD )
return NULL;
}
/* ---------------------------- */
/* Validate() -------------------------------------*/
static NAMELIST *Validate(int id, int validtag)
{
NAMELIST *pNL;
......@@ -342,16 +318,14 @@ static NAMELIST *Validate(int id, int validtag)
return NULL;
}
/* ---------------------------- */
static char work_buf[80];
static char name_buf[NAME_LIMIT+16];
/* DoCLIop() --------------------------------------*/
/* This does a CLI operation on the given mount. The command
string should contain a %s at the point where the mount
name should be put, it will be replaced by "LanMan::mountname"
*/
static char work_buf[80];
static char name_buf[NAME_LIMIT+16];
static err_t DoCLIop ( char *command, int mount_id )
{
_kernel_swi_regs R;
......@@ -367,8 +341,7 @@ static err_t DoCLIop ( char *command, int mount_id )
return Xlt_SetOSError( _kernel_swi ( XOS_Bit | OS_CLI, &R, &R ));
}
/* ------------------------------------ */
/* MountNameCpy() ---------------------------------*/
static void MountNameCpy ( char *d, char *s )
{
int n_written=0, c;
......@@ -387,18 +360,17 @@ static void MountNameCpy ( char *d, char *s )
*d = 0;
}
/* BootMount() ------------------------------------ */
static int ReentryCount = 0;
/* BootMount() ------------------------------------ */
/* Runs the !ArmBoot file, if such a thing exists. The !ArmBoot file
may contain perfectly valid *Connect commands, and so this bit
will be reentrant. The laws are therefore this: nothing following
the call to DoCLIop must rely on any static variables/buffers which
are able to be modified by any *command or SWI. As a safeguard, we
limit the number of times this can be reentered (the limit is
MAX_DRIVES) */
static int ReentryCount = 0;
MAX_DRIVES)
*/
#ifdef CHECK_ARMBOOT_EXISTS
static err_t BootMount_check_file ( NAMELIST *pNLmount, const char *leaf )
{
......@@ -439,7 +411,6 @@ static err_t BootMount ( NAMELIST *pNLmount )
#endif
/* Safety check */
if ( ReentryCount >= MAX_DRIVES )
return EBOOTREENTRY;
......@@ -464,10 +435,10 @@ static err_t BootMount ( NAMELIST *pNLmount )
return res;
}
/* Omni_MountServer makes a connection to a server; --------
/* Omni_MountServer() ------------------------------- */
/* Makes a connection to a server;
it is the XXXX_OmniOp 0 SWI.
*/
err_t Omni_MountServer ( char *servname, char *userID, char *passwd,
char *mountname, char *mountpath, int *mount_id_out )
{
......@@ -547,8 +518,8 @@ err_t Omni_MountServer ( char *servname, char *userID, char *passwd,
return BootMount ( pNLmount );
}
/* Omni_DismountServer does XXXX_OmniOp 1 ------------ */
/* Omni_DismountServer() --------------------------*/
/* Does XXXX_OmniOp 1 */
err_t Omni_DismountServer ( int mount_id )
{
NAMELIST *pNL = Validate(mount_id, (int)M_VALID_TAG);
......@@ -564,15 +535,13 @@ err_t Omni_DismountServer ( int mount_id )
return OK;
}
/* Omni_FreeSpace does XXXX_OmniOp 2 ------------------- */
/* Omni_FreeSpace() -------------------------------*/
/* Does XXXX_OmniOp 2 */
static uint size_clip ( uint val, uint limit, uint blksize )
{
return (val > limit) ? 0xFFFFFFFFU : val * blksize;
}
/* ------------------ */
static err_t Omni_DetermineFreeSpace ( int mount_id,
struct disk_size_response *DSR)
{
......@@ -608,10 +577,8 @@ static err_t Omni_FreeSpace ( int mount_id,
return OK;
}
typedef struct fspc_64 {
unsigned lo, hi;
} fspc_64;
/* Omni_FreeSpace64() ------------------------------*/
/* Does XXXX_OmniOp 4 */
static err_t Omni_FreeSpace64 ( int mount_id, int *success,
fspc_64 *freespace_out, fspc_64 *usedspace_out, fspc_64 *totspace_out )
{
......@@ -633,9 +600,7 @@ static err_t Omni_FreeSpace64 ( int mount_id, int *success,
return OK;
}
/* Subroutines to help enumeration routines ----------------------- */
/* Subroutines to help enumeration routines ======================== */
static char *enum_ptr;
static int enum_bytes_left;
......@@ -680,8 +645,8 @@ static bool enum_write_string( char *str, int maxlen )
return true;
}
/* Omni_ListServers does XXXX_OmniOp 3 -------------------------- */
/* Omni_ListServers() -----------------------------*/
/* Does XXXX_OmniOp 3 */
static err_t Omni_ListServers ( char *buf_ptr, int buf_size, int token_in,
char * *pNextByte_out, int *pToken_out )
{
......@@ -739,8 +704,8 @@ static err_t Omni_ListServers ( char *buf_ptr, int buf_size, int token_in,
return OK;
}
/* Omni_ListMounts does XXXX_OmniOp 4 -------------------------- */
/* Omni_ListMounts() ------------------------------*/
/* Does XXXX_OmniOp 4 */
static err_t Omni_ListMounts (
char *buf_ptr, int buf_size, int token_in,
int server_id, char *server_name,
......@@ -819,9 +784,8 @@ static err_t Omni_ListMounts (
return OK;
}
/* Omni_ListActiveMounts does XXXX_OmniOp 5 -------------------------- */
/* Omni_ListActiveMounts() ------------------------*/
/* Does XXXX_OmniOp 5 */
static err_t Omni_ListActiveMounts ( char *buf_ptr, int buf_size,
int token_in, char * *pNextByte_out, int *pToken_out )
{
......@@ -868,8 +832,8 @@ static err_t Omni_ListActiveMounts ( char *buf_ptr, int buf_size,
return OK;
}
/* Omni_ListPrinters does XXXX_OmniOp 16 -------------------------- */
/* Omni_ListPrinters() ------------------------*/
/* Does XXXX_OmniOp 16 */
static err_t Omni_ListPrinters ( char *buf_ptr, int buf_size,
int token_in, char * *pNextByte_out, int *pToken_out )
{
......@@ -935,29 +899,23 @@ out_of_buffer:
return OK;
}
/* Omni_OpenRoot () -------------------
Triggers a filer_opendir on the root directory for a given mount
*/
/* Omni_OpenRoot () -------------------------------*/
/* Triggers a filer_opendir on the root directory for a given mount */
static err_t Omni_OpenRoot ( int mount_id )
{
return DoCLIop ("Filer_OpenDir %s.$", mount_id );
}
/* Omni_OpenUserRoot () -------------------
Triggers a filer_opendir on the user's home directory for a given mount
*/
/* Omni_OpenUserRoot () ---------------------------*/
/* Triggers a filer_opendir on the user's home directory for a given mount */
static err_t Omni_OpenUserRoot ( int mount_id )
{
return DoCLIop ("Filer_OpenDir %s.$", mount_id );
}
/* Omni_GetNewMountInfo() -------------------
Works out whether a new password or userID will be needed for
/* Omni_GetNewMountInfo() -------------------------*/
/* Works out whether a new password or userID will be needed for
a new mount on an existing server.
(02-07-96) This is called when a user double-clicks on an icon in
......@@ -965,10 +923,7 @@ static err_t Omni_OpenUserRoot ( int mount_id )
with the server id and the (as I understand it) short name of the
mount, and we get to say whether we have all the information we
need to mount it.
*/
static err_t Omni_GetNewMountInfo ( int server_id, char *MountPath,
int *pFlags_out )
{
......@@ -1015,12 +970,8 @@ static err_t Omni_GetNewMountInfo ( int server_id, char *MountPath,
return OK;
}
/* Omni_GetMountInfo() ----------------------
Gets info about an existing mount.
*/
/* Omni_GetMountInfo() ----------------------------*/
/* Gets info about an existing mount */
err_t Omni_GetMountInfo ( int mount_id, char **pServName,
char **pUserName, char **pMountName, char **pMountPath, int *pServerID )
{
......@@ -1042,24 +993,15 @@ err_t Omni_GetMountInfo ( int mount_id, char **pServName,
return OK;
}
/* -------------------- */
static err_t Omni_NotDoneYet(void)
{
return ENOTPRESENT;
}
/* Exported functions ========================================== */
bool Omni_Registered = false;
/* Exported functions ============================================== */
/* Omni_GetDrvLetter() ----------------------------------
static bool Omni_Registered = false;
Gets an SMB drive letter given a mount name.
/* Omni_GetDrvLetter() ----------------------------*/
/* Gets an SMB drive letter given a mount name.
Returns 0 if not found. 'Name' should be not contain
spaces or invalid chars, otherwise it won't be found.
*/
char Omni_GetDrvLetter ( char *name )
{
NAMELIST *pNL = FindInList ( MountsList, name );
......@@ -1071,11 +1013,9 @@ char Omni_GetDrvLetter ( char *name )
}
/* Omni_GetMountID () --------------- */
/* Omni_GetMountID() ------------------------------*/
/* This should be used when the mount name is from dodgy
sources, as it will do 'MountNameCpy' processing on it first.
*/
int Omni_GetMountID ( char *name )
{
......@@ -1084,11 +1024,8 @@ int Omni_GetMountID ( char *name )
return (int) FindInList(MountsList, lclname);
}
/* Omni_GetDefaultType() ---------------
Attempts to ask OmniFiler for the type for a given file name.
*/
/* Omni_GetDefaultType() --------------------------*/
/* Attempts to ask OmniFiler for the type for a given file name */
err_t Omni_GetDefaultType ( char *name, int * pType_out )
{
_kernel_swi_regs R;
......@@ -1115,12 +1052,8 @@ err_t Omni_GetDefaultType ( char *name, int * pType_out )
return OK;
}
/* OmniOp_SWI() ---------------------------
Provides the LanMan_OmniOp SWI handler.
*/
/* OmniOp_SWI() -----------------------------------*/
/* Provides the LanMan_OmniOp SWI handler */
_kernel_oserror *OmniOp_SWI ( _kernel_swi_regs *R )
{
err_t res;
......@@ -1246,23 +1179,19 @@ _kernel_oserror *OmniOp_SWI ( _kernel_swi_regs *R )
Rout_chr(1),
Rout_int(3) );
break;
default:
res = Omni_NotDoneYet();
res = ENOTPRESENT;
}
return Xlt_Error(res);
}
/* Omni_FreeOp_SWI() --------------------------------------
This is not strictly OmniClient. Instead it is for use by
/* Omni_FreeOp_SWI() ------------------------------*/
/* This is not strictly OmniClient. Instead it is for use by
the Free module. On exit, set R1 to 0 if we want the Z
bit set on return.
*/
static char logstring[200];
static char *ExtractName ( char * s )
{
char *p = strrchr(s, ':'); /* Finds last ':' in name */
......@@ -1350,14 +1279,13 @@ _kernel_oserror *Omni_FreeOp_SWI (_kernel_swi_regs *R )
return Xlt_Error(EBADPARAM);
}
/* ----------------------------------------------- */
void Omni_RecheckInfo( int flags )
{
/* This is called after *Commands or other actions which
/* Omni_RecheckInfo() -----------------------------*/
/* This is called after *Commands or other actions which
might change the available mounts or network information.
It basically calls Omni_EnumerateMounts.
*/
*/
void Omni_RecheckInfo( int flags )
{
_kernel_swi_regs R;
if ( Omni_Registered )
......@@ -1368,8 +1296,7 @@ void Omni_RecheckInfo( int flags )
}
}
/* =============================================== */
/* Omni_Register() --------------------------------*/
static void Omni_Register(void)
{
_kernel_swi_regs R;
......@@ -1387,13 +1314,13 @@ static void Omni_Register(void)
{
R.r[4] = (int) "Lan Manager/TCPIP client\n"
"\xA9 Acorn Computers Ltd, 1997\n"
VERSION_STRING;
Module_FullVersion " ("Module_ApplicationDate")";
}
else
{
R.r[4] = (int) "Lan Manager/NetBEUI client\n"
"\xA9 Acorn Computers Ltd, 1997\n"
VERSION_STRING;
Module_FullVersion " ("Module_ApplicationDate")";
}
R.r[5] = 0; /* Site ID word. Ignore this! */
......@@ -1403,8 +1330,7 @@ static void Omni_Register(void)
Omni_Registered = true;
}
/* ---------------------------------------- */
/* Omni_Free_Register() ---------------------------*/
static void Omni_Free_Register(bool OnNotOff)
{
_kernel_swi_regs R;
......@@ -1419,12 +1345,10 @@ static void Omni_Free_Register(bool OnNotOff)
_kernel_swi ( SWI_Free_Deregister, &R, &R );
}
/* Omni_StartUp() -------------------------
Attempts to register us with OmniFiler and the
/* Omni_StartUp() ---------------------------------*/
/* Attempts to register us with OmniFiler and the
Free module. Called when the module loads.
*/
void Omni_StartUp ( void )
{
if ( !Omni_Registered )
......@@ -1433,14 +1357,11 @@ void Omni_StartUp ( void )
Omni_Free_Register(true);
}
/* ------------------------- */
/* Omni_Shutdown() --------------------------------*/
/* This is called if we're about to die.
If so, we should deregister ourselves with OmniFiler, and
free any alloc'd memory.
*/
void Omni_Shutdown ( void )
{
_kernel_swi_regs R;
......@@ -1463,12 +1384,10 @@ void Omni_Shutdown ( void )
Omni_Free_Register(false);
}
/* Omni_ClearLists() --------------------------------- */
/* Omni_ClearLists() ------------------------------*/
/* This is called when a *LMLOGOFF or similar is done,
and deletes all servers which we don't currently have
a connection to */
void Omni_ClearLists ( void )
{
NAMELIST *pNLsrv, *pNLdisk, *pNLtmp;
......@@ -1519,8 +1438,7 @@ void Omni_ClearLists ( void )
}
/* Omni_ServiceCall() -------------------------------- */
/* Omni_ServiceCall() -----------------------------*/
void Omni_ServiceCall ( _kernel_swi_regs *R )
{
switch ( R->r[0] )
......@@ -1540,30 +1458,7 @@ void Omni_ServiceCall ( _kernel_swi_regs *R )
}
}
/* Omni_Debug() ------------------------------------- */
static void showname ( NAMELIST *pNL )
{
if ( pNL == NULL )
printf("(none) ");
else
printf("'%s' ", pNL->name);
}
static void showlist ( NAMELIST *pNL )
{
if ( pNL == NULL ) printf("(none) ");
while ( pNL != NULL )
{
printf("'%s' ", pNL->name);
pNL = pNL->next;
}
}
/* ------------------------------ */
/* Omni_AddInfo()----------------------------------*/
void Omni_AddInfo ( int flags, char *serv_name, char *string, char *comment )
{
NAMELIST *pNLsrv, **list;
......@@ -1617,6 +1512,7 @@ void Omni_AddInfo ( int flags, char *serv_name, char *string, char *comment )
}
}
/* Omni_DumpServers() -----------------------------*/
_kernel_oserror *Omni_DumpServers(void)
{
err_t res;
......@@ -1628,6 +1524,7 @@ _kernel_oserror *Omni_DumpServers(void)
return NULL;
}
/* Omni_DumpSharesPrint() -------------------------*/
static void Omni_DumpSharesPrint(NAMELIST *pNL, const char *type)
{
for (; pNL != NULL; pNL = pNL->next) {
......@@ -1635,6 +1532,7 @@ static void Omni_DumpSharesPrint(NAMELIST *pNL, const char *type)
}
}
/* Omni_DumpServersPrint() ------------------------*/
static void Omni_DumpServersPrint(NAMELIST *pNL)
{
for (; pNL != NULL; pNL = pNL->next) {
......@@ -1642,6 +1540,7 @@ static void Omni_DumpServersPrint(NAMELIST *pNL)
}
}
/* Omni_DumpShares() ------------------------------*/
_kernel_oserror *Omni_DumpShares(char *server_name)
{
err_t res;
......@@ -1672,7 +1571,25 @@ _kernel_oserror *Omni_DumpShares(char *server_name)
return NULL;
}
/* ------------------- */
/* Omni_Debug() -----------------------------------*/
static void showname ( NAMELIST *pNL )
{
if ( pNL == NULL )
printf("(none) ");
else
printf("'%s' ", pNL->name);
}
static void showlist ( NAMELIST *pNL )
{
if ( pNL == NULL ) printf("(none) ");
while ( pNL != NULL )
{
printf("'%s' ", pNL->name);
pNL = pNL->next;
}
}
void Omni_Debug ( void )
{
......
......@@ -78,6 +78,7 @@
#include <ctype.h>
#include <time.h>
#include "kernel.h"
#include "swis.h"
/* Our includes */
......@@ -98,7 +99,7 @@
/* Timeouts * */
/* Reply timeout (12s) */
/* Reply timeout, in cs */
#ifdef LONGNAMES
#define REPLY_TIMEOUT 4000
......@@ -340,7 +341,6 @@ static struct ActiveShare SMB_Shares[MAX_SHARES];
BYTE SMB_WorkBuf[SMBWORKBUF_SIZE];
/* SMB routines ======================================================== */
static int DOS_Errs[] =
......@@ -816,7 +816,7 @@ static err_t SMB_WriteRaw ( hSHARE hS, int fid, int offset,
SMB_TxWords[8] = 0; /* Reserved */
SMB_TxWords[9] = 0; /* Reserved */
SMB_TxWords[10] = 0; /* # of data bytes immediately following */
SMB_TxWords[11] = 0x3C; /* Offset to immediate data bytes */
SMB_TxWords[11] = 0; /* Offset to immediate data bytes */
res = Do_SMB ( hS, SMBwriteBraw, 12, NULL, NULL );
if ( res != OK )
......@@ -1818,7 +1818,7 @@ static err_t SMB_GetAttribsX2 (hSHARE hS, char *filename, DOS_ATTRIBS *pAttr )
fnbuffer[4] = '\0';
Transact_init(&tp, 6 * 2); /* will accept 6 WORD return params */
Transact_addsetupword(&tp, TRANSACT2_FINDFIRST);
if (LM_Vars.namemode & 4) {
if (LM_Vars.namemode & NM_INTERNAL) {
Transact_addword(&tp, ATTR_DIR | ATTR_SYS | ATTR_HID); /* findfirst_Attribute */
}
else {
......@@ -2075,13 +2075,6 @@ static err_t SMB_GetFreeSpaceX2 ( hSHARE hS, struct disk_size_response *pDSR )
pDSR->freeblks = total_avail_allocs;
pDSR->totalblks = total_allocs;
/*
debug2("S/A %10d %#08x\n", sectors_per_alloc, sectors_per_alloc);
debug2("T A %10d %#08x\n", total_allocs, total_allocs);
debug2("TAA %10d %#08x\n", total_avail_allocs, total_avail_allocs);
debug2("B?S %10d %#08x\n", (DWORD) bytes_per_sector, (DWORD) bytes_per_sector);
*/
return OK;
}
#endif
......@@ -2128,67 +2121,60 @@ enum {
ffirst_FORCE_CLOSE = 1,
ffirst_CLOSE_IF_DONE = 2,
ffirst_RETURN_KEYS = 4,
fnext_CONTINUE = 8
fnext_CONTINUE = 8, /* This bit allows continuation without the need to use resume keys */
ffirst_BACKUP_INTENT = 16
};
#ifdef DEBUGLIB
static int SIDS=0;
#endif
static err_t SMB_AbandonFind2( hSHARE hS, WORD dir_handle )
{
dprintf(("SID", "Terminating search op (dir_handle = 0x%04x) (%d open)\n",
dir_handle, --SIDS));
debug1("Terminating search op (dir_handle = %x)\n", dir_handle);
SMB_TxWords[0] = dir_handle;
return Do_SMB(hS, SMBfindclose2, 1, NULL, NULL);
}
/* Implement directory searching via TRANSACT2/FINDFIRST/FINDNEXT */
static err_t SMB_ReadDirEntriesX2 ( hSHARE hS, char *path, int count,
ENUM_DIR_FN dirfn, void *private,
struct Transact2_SearchContext *con )
Transact_SearchContext *con )
{
char *ptr_last_filename;
err_t res;
BYTE *p;
int n_read = 0;
int eos;
int lastname;
int i;
const int first_flags = /*ffirst_CLOSE_IF_DONE |*/ ffirst_RETURN_KEYS;
const int next_flags = /*ffirst_CLOSE_IF_DONE |*/ ffirst_RETURN_KEYS;// | fnext_CONTINUE;
int flags;
const int first_flags = ffirst_RETURN_KEYS;
const int next_flags = ffirst_RETURN_KEYS;
bool path_changed = false;
bool taken;
if (path != NULL && con->t1.NextSearchOK == true || count < 0) {
/* We need to abandon the current search attached to dir_handle.
* Ignore errors.
*/
debug3("SMB_ReadDirEntriesX2 -> path (%p) NextSearchOK (%d) count (%d)\n",
path, con->t1.NextSearchOK, count);
/* Despite having a resume key it may be necessary to restart */
if ( (path != NULL) && (strcmp( path, con->dir_path ) != 0) )
path_changed = true;
if ( path_changed || (con->resume_key == 0) ) {
/* Path changed due to recursion or new search */
if (con->dir_handle_valid) {
debug1("SMB_ReadDirEntriesX2 -> abandon old search of dir handle %x\n", con->dir_handle);
(void) SMB_AbandonFind2( hS, con->dir_handle );
con->dir_handle_valid = false;
}
}
con->t1. NextSearchOK = false;
if (count < 0) return ENOMOREFILES;
strcpy( con->dir_path, path );
con->resume_key_encountered = (con->resume_key == 0) ? true : false;
//count = min (count, 10);
/* For a new search, ensure the request allows for "." and ".." which are
* always given and would therefore end up oscillating with 0 useful files
* found and a resume key of 0 again
*/
count = max( count, 3 );
/* Implement directory searching via TRANSACT2/FINDFIRST/FINDNEXT */
if (path != NULL) {
/* Initial search - note we accept SIX return parameters - contrary to
* Microsoft's own document - because it doesn't work if you only pass 5. Grr.
*/
if (con->dir_handle_valid) {
SMB_AbandonFind2( hS, con->dir_handle);
con->dir_handle_valid = false;
}
con->resume_key = 0;
flags = first_flags;
Transact_init(&con->tp, 6 * 2); /* will accept 6 WORD return params */
Transact_addsetupword(&con->tp, TRANSACT2_FINDFIRST);
if (LM_Vars.namemode & 4) {
if (LM_Vars.namemode & NM_INTERNAL) {
Transact_addword(&con->tp, ATTR_DIR | ATTR_SYS | ATTR_HID); /* findfirst_Attribute */
}
else {
......@@ -2205,10 +2191,11 @@ static err_t SMB_ReadDirEntriesX2 ( hSHARE hS, char *path, int count,
p = con->tp.parms_out_buf;
con->dir_handle = Transact_getword(p); p += 2;
con->dir_handle_valid = true;
dprintf(("SID", "SID = 0x%04hx (%d open)\n", con->dir_handle, ++SIDS));
debug1("SMB_ReadDirEntriesX2 -> new dir handle %x\n", con->dir_handle);
}
else {
/* continuation */
/* Continuation */
con->resume_key_encountered = true;
flags = next_flags;
Transact_init(&con->tp, 4 * 2); /* will accept 4 WORD return params */
Transact_addsetupword(&con->tp, TRANSACT2_FINDNEXT);
......@@ -2217,7 +2204,8 @@ static err_t SMB_ReadDirEntriesX2 ( hSHARE hS, char *path, int count,
Transact_addword(&con->tp, 1); /* Search level */
Transact_addlong(&con->tp, con->resume_key); /* Resume key from previous */
Transact_addword(&con->tp, next_flags); /* findnext_flags */
Transact_addstring(&con->tp, con->last_filename); /* resumption filename */
Transact_addstring(&con->tp, ""); /* no name needed */
debug1("SMB_ReadDirEntriesX2 -> continue with key %08x\n", con->resume_key);
res = SMB_Transact2(hS, &con->tp);
if (res != OK)
return res;
......@@ -2226,18 +2214,8 @@ static err_t SMB_ReadDirEntriesX2 ( hSHARE hS, char *path, int count,
/* Remainder of response handling is common to both sub-commands */
n_read = Transact_getword(p); p += 2;
eos = Transact_getword(p); p += 2;
p += 2; /* skip error offset */
lastname = Transact_getword(p);
if (lastname == 0) {
ptr_last_filename = NULL;
}
else {
ptr_last_filename = (char *) con->tp.data_out_buf + lastname;
}
if (eos) {
if (eos)
debug0(">> Server said it was the end of the search operation\n");
}
p = con->tp.data_out_buf;
/* At this point, p is pointing to the start of the returned data
......@@ -2247,156 +2225,222 @@ static err_t SMB_ReadDirEntriesX2 ( hSHARE hS, char *path, int count,
if (n_read == 0)
return ENOMOREFILES;
for (i=1; i <= n_read; ++i) {
for (i = 1; i <= n_read; i++) {
int length;
DWORD next_resume_key;
if (flags & ffirst_RETURN_KEYS) {
/* Get next resume key */
next_resume_key = Transact_getlong(p); p += 4;
}
length = p[22];
//debug2("ding - got one (length = %d) `%s'\n", length, p+23);
//DumpBuffer(p, 2 + 2 + 2 + 2 +2 +2 + 4 + 4 +2 + 1 + length);
res = dirfn(p, 1, private);
if ( con->resume_key_encountered ) {
debug1("SMB_ReadDirEntriesX2 -> call back with key %08x\n", next_resume_key);
res = dirfn(p, 1, &taken, private);
if (taken) con->resume_key = next_resume_key;
if (res != OK) {
/* Entry expander must have run out of space! Remember where the
* search was at, and try to rewind it a bit by using the resume
* key and the last_filename
*/
/* If the search said this was the end of the search though, it will
* have already terminated the search, so NextSearchOK becomes false
* and it will have to restart the search next time around.
*/
//NextSearchOK = eos ? false : true;
debug0("Bugger. Looks like client ran out of space (or could be name xlate code)\n");
if (eos) {
(void) SMB_AbandonFind2( hS, con->dir_handle );
con->dir_handle_valid = false;
}
else {
int j;
con->t1.NextSearchOK = true;
for (j=i; j<n_read; ++j) dirfn(p, 1, private);
}
/* Entry expander must have run out of space! */
debug0("SMB_ReadDirEntriesX2 -> caller ran out of space (or could be name xlate code)\n");
return EOUTOFMEM;
}
}
else {
con->resume_key = next_resume_key;
ptr_last_filename = (char *) p + 23;
(void) strncpy(con->last_filename, ptr_last_filename?ptr_last_filename:"",
sizeof(con->last_filename));
debug2("SMB_ReadDirEntriesX2 -> awaiting key %08x (got %08x)\n", con->resume_key, next_resume_key);
if ( next_resume_key == con->resume_key )
con->resume_key_encountered = true;
}
p += 23 + length + 1;
if ( i == count ) /* By implication, if n_read >= count */
{
debug3("i = %3d; count = %3d; n_read = %3d\n", i, count, n_read);
debug0("OK - there are more to come later; ");
if (flags & ffirst_RETURN_KEYS) {
debug1("Resume key is 0x%08x; ", con->resume_key);
}
debug1("Next filename is `%s'\n", con->last_filename);
con->t1.NextSearchOK = true;
}
}
if (eos) {
if (eos)
debug0(">> Server said it was the end of the search operation\n");
con->t1.NextSearchOK = false;
}
return con->t1.NextSearchOK ? OK : ENOMOREFILES;
return eos ? ENOMOREFILES : OK;
}
#endif
err_t SMB_ReadDirEntries ( char *path, int count,
ENUM_DIR_FN dirfn, void *private, Transact_SearchContext *conp )
ENUM_DIR_FN dirfn, void *private, void *context )
{
err_t res;
int i, n_read;
BYTE *entry;
int i, n_read, eos;
BYTE *p;
BUFCHAIN pB, pBres;
static Transact_SearchContext rde_context;
struct Transact1_SearchContext *con;
Transact_SearchContext *con;
bool path_changed = false;
bool taken;
con = (conp == NULL) ? &rde_context.t1 : &conp->t1;
/* Start or continue search? */
/* Don't be silly */
if (count < 0) return ENOMOREFILES;
if ( path != NULL ) /* Start search */
{
con->SearchDrive = GetShare(path, &res);
if ( con->SearchDrive == NULL )
con = (Transact_SearchContext *)context;
if (con->resume_key == 0) {
/* Start search */
con->search_drive = GetShare(path, &res);
if ( con->search_drive == NULL )
return res;
}
else
{
if ( !con->NextSearchOK || con->SearchDrive == NULL )
else {
/* Continue search */
if ( con->search_drive == NULL )
return ENOMOREFILES;
}
#ifdef LONGNAMES
if (con->SearchDrive->hServer->t2flags & T2FLAGS_LONGNAMES)
{
struct Transact2_SearchContext *const t2sc = (conp == NULL) ? &rde_context.t2 : &conp->t2;
return SMB_ReadDirEntriesX2(con->SearchDrive, path, count, dirfn, private, t2sc);
if ( con->search_drive->hServer->t2flags & T2FLAGS_LONGNAMES ) {
/* Long names enabled */
return SMB_ReadDirEntriesX2(con->search_drive, path, count, dirfn, private, con);
}
#endif
/* Check 'count' */
/* Despite having a resume key it may be necessary to restart */
if ( (path != NULL) && (strcmp( path, con->dir_path ) != 0) )
path_changed = true;
if ( count <= 0 )
return ENOMOREFILES;
if (con->resume_key == 0) {
/* New search */
strcpy( con->dir_path, path );
con->resume_key_encountered = true;
con->dir_handle_valid = false;
count = min ( count, SEARCH_COUNT ); /* Don't do more than is convenient */
/* For a new search, ensure the request allows for "." and ".." which are
* always given and would therefore end up oscillating with 0 useful files
* found and a resume key of 0 again
*/
count = max( count, 3 );
if ( path != NULL ) /* Starting search */
{
/* Initial search */
pB = MkDataBlock ( NULL, DATA_VARBLK, NULL, 0, false );
if ( pB != NULL )
pB = MkDataString( pB, DATA_ASCII, path+2 );
debug1("SMB_ReadDirEntries -> new search of %s\n", path);
}
else /* Continue search */
{
pB = MkDataBlock (NULL, DATA_VARBLK, con->SearchState,
else {
/* Continuation */
debug1("SMB_ReadDirEntries -> continue with key %08x\n", con->resume_key);
if (!path_changed && con->dir_handle_valid &&
((WORD)con->resume_key == con->dir_handle)) {
/* Path is the same, search key non zero, state valid */
debug0("SMB_ReadDirEntries -> hyperspace\n");
con->resume_key_encountered = true;
pB = MkDataBlock (NULL, DATA_VARBLK, con->resume_state,
SEARCH_ST_SIZE, false);
if ( pB != NULL)
pB = MkDataString( pB, DATA_ASCII, "" );
}
else {
/* Emulate the state resumption, slow but infrequent */
debug0("SMB_ReadDirEntries -> emulation\n");
con->resume_key_encountered = false;
pB = MkDataBlock ( NULL, DATA_VARBLK, NULL, 0, false );
if ( pB != NULL )
pB = MkDataString( pB, DATA_ASCII, path+2 );
while (!con->resume_key_encountered) {
/* Do search */
if ( pB == NULL )
return EOUTOFMEM;
SMB_TxWords[0] = max( count, SEARCH_COUNT );
SMB_TxWords[1] = ATTR_DIR /* | ATTR_SYS | ATTR_HID */;
res = Do_SMB( con->search_drive, SMBsearch, 2, pB, &pBres );
if ( res != OK )
return res;
FreeChain( GetData( pBres, SMB_WorkBuf, SMB_RxByteCount ) );
/* Do search */
/* Scan for a match */
n_read = SMB_RxWords[0];
eos = (n_read < count);
if (eos)
debug0(">> Server said it was the end of the search operation\n");
SMB_TxWords[0] = count;
SMB_TxWords[1] = ATTR_DIR /* | ATTR_SYS | ATTR_HID */;
con->NextSearchOK = false;
p = SMB_WorkBuf+3;
/* At this point, p is pointing to the start of the returned data
* buffer, n_read contains the number of files known to be in the
* return buffer, eos is non-zero if the search is completed.
*/
if (n_read == 0)
return ENOMOREFILES;
for (i = 1; i <= n_read; i++) {
DWORD next_resume_key;
res = Do_SMB ( con->SearchDrive, SMBsearch, 2, pB, &pBres );
/* Prep resumption */
memcpy( con->resume_state, p, SEARCH_ST_SIZE );
/* Get next resume key */
_swix(OS_CRC, _INR(0,3)|_OUT(0), 0, p+30, p+SEARCH_TOT_SIZE, 1, &next_resume_key);
if (next_resume_key == con->resume_key) {
strcpy( con->dir_path, path );
con->resume_key_encountered = true;
break;
}
p += SEARCH_TOT_SIZE;
}
/* Again again... */
pB = MkDataBlock (NULL, DATA_VARBLK, con->resume_state,
SEARCH_ST_SIZE, false);
if ( pB != NULL)
pB = MkDataString( pB, DATA_ASCII, "" );
}
}
}
/* Do search */
if ( pB == NULL )
return EOUTOFMEM;
count = min( count, SEARCH_COUNT );
SMB_TxWords[0] = count;
SMB_TxWords[1] = ATTR_DIR /* | ATTR_SYS | ATTR_HID */;
res = Do_SMB( con->search_drive, SMBsearch, 2, pB, &pBres );
if ( res != OK )
return res;
FreeChain( GetData( pBres, SMB_WorkBuf, SMB_RxByteCount ) );
/* Extract all data */
/* Remainder of response handling is common to both sub-commands */
n_read = SMB_RxWords[0];
eos = (n_read < count);
if (eos)
debug0(">> Server said it was the end of the search operation\n");
FreeChain( GetData ( pBres, SMB_WorkBuf, SMB_RxByteCount ) );
p = SMB_WorkBuf+3;
/* At this point, p is pointing to the start of the returned data
* buffer, n_read contains the number of files known to be in the
* return buffer, eos is non-zero if the search is completed.
*/
if (n_read == 0)
return ENOMOREFILES;
/* Process it */
n_read = SMB_RxWords[0];
entry = SMB_WorkBuf+3;
for (i = 1; i <= n_read; i++) {
DWORD next_resume_key;
for ( i=1; i<=n_read; i++ )
{
entry[42] = 0;
dirfn ( entry+SEARCH_ST_SIZE, 0, private );
if ( i == count ) /* By implication, if n_read >= count */
{
con->NextSearchOK = true;
memcpy ( con->SearchState, entry, SEARCH_ST_SIZE );
/* Get next resume key */
_swix(OS_CRC, _INR(0,3)|_OUT(0), 0, p+30, p+SEARCH_TOT_SIZE, 1, &next_resume_key);
p[SEARCH_TOT_SIZE - 1] = 0;
debug1("SMB_ReadDirEntries -> call back with key %08x\n", next_resume_key);
res = dirfn(p+SEARCH_ST_SIZE, 0, &taken, private);
if (taken) {
con->resume_key = next_resume_key;
memcpy( con->resume_state, p, SEARCH_ST_SIZE );
con->dir_handle = (WORD)next_resume_key;
con->dir_handle_valid = true;
}
entry += SEARCH_TOT_SIZE;
if (res != OK) {
/* Entry expander must have run out of space! */
debug0("SMB_ReadDirEntries -> caller ran out of space (or could be name xlate code)\n");
return EOUTOFMEM;
}
p += SEARCH_TOT_SIZE;
}
/* Return OK, or 'no more' */
return con->NextSearchOK ? OK : ENOMOREFILES;
if (eos)
debug0(">> Server said it was the end of the search operation\n");
return eos ? ENOMOREFILES : OK;
}
/* Public file read/write operations ============================= */
......@@ -3051,7 +3095,7 @@ retry_transact2:
/* Utility routines ============================================ */
static char *sharetype_name[4] = { "Disk", "Printer", "Comms", "IPC" };
static char *sharetype_name[4] = { "Disc", "Printer", "Comms", "IPC" };
char *SMB_GetConnInfo ( char drvletter, int infotype )
{
......@@ -3090,13 +3134,6 @@ char *SMB_GetConnInfo ( char drvletter, int infotype )
return "";
}
/* --------------------------- */
bool SMB_ConnectedTo ( char *server )
{
return (bool)( FindServer ( server ) != NULL );
}
/* Init routines ================================================ */
bool SMB_Init( void )
......
......@@ -28,16 +28,14 @@
#include <stdlib.h>
#include <ctype.h>
#include "kernel.h"
#include "stdtypes.h"
#include "swis.h"
#include "Xlate.h"
#include "attr.h"
#include "omni.h"
#include "LanMan.h"
#include "lmvars.h"
#include "SMB.h"
#include "Transact.h"
#include "NameCache.h"
#ifdef LONGNAMES
......@@ -50,13 +48,6 @@
*/
static const int deaddead = (int)0xDEADDEAD;
/* For the moment, untyped files have these invented load/exec addresses.
* They ensure that if such a file is *Load'ed or *Run'ed, then a data
* abort will occur
*/
static const int untyped_load = 0x03800000;
static const int untyped_exec = 0x03800000;
/* Macro returns non-zero if the specifiec load addressis indicative of
* a filetyped object. Rather than checking for the top 12 bits being
* set, it's much quicker to arithmetic shift it right 20 bits and test
......@@ -75,8 +66,7 @@ static const int untyped_exec = 0x03800000;
* ORR rn, rn, #0x0FF00000: MOV load,load,LSL #12:
* EOR load, type, load LSR #20: EOR load,rn,load LSL #8
*/
#define ENCODE_FILETYPE(load,type) \
(((load)|0xFFF00000)^((GET_FILETYPE(load)^(type))<<8))
#define ENCODE_FILETYPE(load,type) (((load)|0xFFF00000)^((GET_FILETYPE(load)^(type))<<8))
#endif
......@@ -157,7 +147,7 @@ void strcpyn_lower ( char *d, const char *s, int len )
/* -------------------------- */
static int daycount[13] =
static const ushort daycount[13] =
{
0,
0, /* Jan=31 */
......@@ -245,7 +235,7 @@ void Xlt_CnvDOStoRO ( DOS_ATTRIBS *pDA, RISCOS_ATTRIBS *pRA, int flags )
/* Total = (thi << 16)+tlo; */
pRA->loadaddr = 0xFFF00000 + ( (thi+ (tlo >> 16) ) >> 16) +
(Default_FileType << 8); /* Default type = 'Text' */
(LM_Vars.default_type << 8); /* Default type */
pRA->execaddr = (thi << 16) + tlo;
}
......@@ -376,27 +366,15 @@ static char Xlt_DefaultDrv = 'A';
#define CH_WILD 2
#define CH_PATH 3
#define CH_SEP 4
#define CH_DUD '_'
/* Current tables set
DOS RISCOS
# ?
$ <
% >
& +
@ =
^ ,
Illegal in RISCOS names: space * " : \ | # $ % & @ ^ DLE
Also: RISCOS { and [ map to DOS (, } and ] to ),
; and top-bit-set chars to _
/*
Illegal in DOS names: / < > ? + , ; = [ ] : * \ " | DEL
Illegal in RISCOS names: . $ % # & ^ @ : * \ " | DEL
All control characters and space are bad
All top bit set characters are swapped for _
*/
static char xlt_RO2DOS[256] =
{
CH_END, CH_ERR, CH_ERR, CH_ERR, CH_ERR, CH_ERR, CH_ERR, CH_ERR, /* 00-07 */
......@@ -417,7 +395,7 @@ static char xlt_RO2DOS[256] =
'`', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
'X', 'Y', 'Z', '(', CH_ERR, ')', '~', CH_ERR,
'X', 'Y', 'Z', '{', CH_ERR, '}', '~', CH_ERR,
CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD,
CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD,
......@@ -440,6 +418,48 @@ static char xlt_RO2DOS[256] =
CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD
};
static char xlt_DOS2RO[256] =
{
CH_END, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, /* 00-07 */
CH_DUD, CH_DUD, CH_END, CH_DUD, CH_DUD, CH_END, CH_DUD, CH_DUD, /* 08-1F */
CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, /* 10-17 */
CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, /* 17-1F */
CH_DUD, '!', CH_DUD, '?', '<', '>', '+', '\'',
'(', ')', CH_DUD, '+', ',', '-', CH_SEP, '/',
'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', CH_DUD, ';', '<', '=', '>', '?',
'=', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
'X', 'Y', 'Z', '[', CH_DUD, ']', ',', '_',
'`', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
'x', 'y', 'z', '{', CH_DUD, '}', '~', CH_DUD,
CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD,
CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD,
CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD,
CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD,
CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD,
CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD,
CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD,
CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD,
CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD,
CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD,
CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD,
CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD,
CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD,
CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD,
CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD,
CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD
};
static err_t nameROtoDOS ( char *dst, char *src )
{
......@@ -510,50 +530,6 @@ static err_t nameROtoDOS ( char *dst, char *src )
}
/* -------------------------- */
static char xlt_DOS2RO[256] =
{
CH_END, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, /* 00-07 */
CH_DUD, CH_DUD, CH_END, CH_DUD, CH_DUD, CH_END, CH_DUD, CH_DUD, /* 08-1F */
CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, /* 00-07 */
CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, /* 00-07 */
CH_DUD, '!', CH_DUD, '?', '<', '>', '+', '\'',
'(', ')', CH_DUD, '+', ',', '-', CH_SEP, '/',
'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', CH_DUD, ';', '<', '=', '>', '?',
'=', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
'X', 'Y', 'Z', '[', CH_DUD, ']', ',', '_',
'`', 'a', 'b', 'c', 'd', 'e', 'f', 'g',
'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o',
'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
'x', 'y', 'z', '{', CH_DUD, '}', '~', CH_DUD,
CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD,
CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD,
CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD,
CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD,
CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD,
CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD,
CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD,
CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD,
CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD,
CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD,
CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD,
CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD,
CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD,
CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD,
CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD,
CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD, CH_DUD
};
/* -------------------------- */
......@@ -561,7 +537,7 @@ static char xlt_DOS2RO[256] =
void Xlt_NameDOStoRO ( char *dst, char *src )
{
int i, c;
int lcl_name_mode = LM_Vars.namemode & 3;
int lcl_name_mode = LM_Vars.namemode & (NM_LOWERCASE | NM_FIRSTCAPS | NM_PRESERVED);
for ( i=0; i<12; i++ ) /* Up to 12 chars in 8.3 name */
{
......@@ -754,22 +730,18 @@ static char Xlt_ContentiousCharCheck(char e, char d)
* and that structure is updated with the real filename once a match
* has been found. The format parameter should always be 1.
*/
static err_t Xlt_NameXlateCallbackX2 ( BYTE *entry, int format, void *_dst )
static err_t Xlt_NameXlateCallbackX2 ( BYTE *entry, int format, bool *taken, void *_dst )
{
Xlt_NXCX2_Data *dst = _dst;
char *eptr = (char *) (entry + 23);
char *dptr = 1 + strrchr(dst->matchbuf, '\\');
err_t res = OK;
*taken = true;
if (dst->dstcpy[0] != '*') {
return EOUTOFMEM;
}
debug3("Xlt_NameXlateCallbackX2: checking `%s', against `%s' in `%s'\n",
(char *) entry + 23,
dptr,
dst->dstcpybuf);
for (;;) {
char e = *eptr++;
char d = *dptr++;
......@@ -820,6 +792,7 @@ static err_t Xlt_NameXlateCallbackX2 ( BYTE *entry, int format, void *_dst )
static err_t Xlt_NameROtoDOSX2_sub ( char *dst, char *src, int level )
{
static Xlt_NXCX2_Data private;
static Transact_SearchContext con;
char *inptr;
err_t status;
......@@ -835,7 +808,9 @@ static err_t Xlt_NameROtoDOSX2_sub ( char *dst, char *src, int level )
* private.dstcpy must point at the * character so that the callback
* function can write the matched target name straight in
*/
#if 0 /* No side effects */
(void) NameCache_Locate(private.matchbuf);
#endif
strcpy(private.dstcpybuf, private.matchbuf);
private.dstcpy = strrchr(private.dstcpybuf, '\\');
if (private.dstcpy) {
......@@ -905,24 +880,27 @@ static err_t Xlt_NameROtoDOSX2_sub ( char *dst, char *src, int level )
/* Repeatedly search the directory until we find a match, or there are
* no more entries to be read back
*/
con.resume_key = 0;
for (status = OK, inptr = private.dstcpybuf; status == OK; inptr = NULL) {
status = SMB_ReadDirEntries(inptr, 32, Xlt_NameXlateCallbackX2,
&private, NULL);
&private, &con);
switch (status) {
case OK:
/* More entries to read, and no match found yet */
break;
case EOUTOFMEM:
/* Found it */
strcpy(dst, private.dstcpybuf);
debug1("\n**RIGHT. Got a match: `%s'\n", dst);
debug1("**RIGHT. Got a match: `%s'\n", dst);
break;
default:
/* Definitely didn't find it - revert to original filename
* or at least filename with nasties resolved as far as possible
*/
strcpy(dst, private.matchbuf);
debug1("\n**WRONG. Not got a match. Reverting to `%s'\n", dst);
debug1("**WRONG. Not got a match. Reverting to `%s'\n", dst);
break;
}
}
......@@ -1213,8 +1191,8 @@ err_t Xlt_SplitLeafnameX2 ( char *leafname, RISCOS_ATTRIBS *pRA,
if (stricmp(leafname+1, FileString_UntypedFile) == 0)
{
debug0("File is untyped (,lxa)\n");
pRA->loadaddr = untyped_load;
pRA->execaddr = untyped_exec;
pRA->loadaddr = LM_Vars.untyped_address;
pRA->execaddr = LM_Vars.untyped_address;
*terminator = leafname;
res = OK;
}
......@@ -1282,8 +1260,8 @@ err_t Xlt_SplitLeafnameX2 ( char *leafname, RISCOS_ATTRIBS *pRA,
if (res != OK)
{
/* No ",ttt" and no mimemap lookup - mark as a Text file */
pRA->loadaddr = ENCODE_FILETYPE(pRA->loadaddr, Default_FileType);
/* No ",ttt" and no mimemap lookup - mark as default type */
pRA->loadaddr = ENCODE_FILETYPE(pRA->loadaddr, LM_Vars.default_type);
}
return res;
......@@ -1294,36 +1272,30 @@ return res;
#ifdef LONGNAMES
/* Copies the filetype information from one name to another.
* Note that the file saving routine actually uses this
* routine to strip filetype information by passing both
* parameters the same. This must continue to function.
* JB 18/12/2003 .. make sure the ,xxx is only removed IF
* both names are NOT (identical and contains .xxx)
* (function only seen in file renaming so far JB)
* Called by "rename object" and "create directory", note
* thie routine can be called with src and dst the same
* to simply remove an extension. This must continue to function.
*/
err_t Xlt_CnvRenameX2 ( char *src, char *dst )
{
RISCOS_ATTRIBS RA;
char *nterm; // *terminator
int cnvq=strcmp(src,dst); // check if just need to strip..
// if src and dst are same, check if it should have the ,xxx appended
// if so, ensure it still is...
// if(!cnvq) // just strip...
// {
// if((strlen(dst)>4) && (dst[strlen(dst)-4] == ',')) cnvq++;
// }
if (Xlt_SplitLeafnameX2 ( dst, &RA, &nterm ) != OK) {
char *terminator, *nterm;
int cnvq = strcmp( src, dst );
if (Xlt_SplitLeafnameX2( dst, &RA, &nterm ) != OK) {
/* No type information - find end of string */
nterm = strchr(dst, '\0');
}
else {
/* Strip old type information in case source didn't have any either */
/* Strip destination's type information in case source didn't have any either */
*nterm = '\0';
}
Xlt_SplitLeafnameX2 ( src, &RA, &nterm ) ; // recover source's filetype
// if not identical strings.. add type if not in dos name
if (cnvq)Xlt_AddROType (dst,RA.loadaddr);
if (Xlt_SplitLeafnameX2( src, &RA, &terminator ) && cnvq) {
/* If dst and src names truly differ apply src's type to dst */
Xlt_AddROType(dst, RA.loadaddr);
}
return OK;
}
#endif
......@@ -1332,7 +1304,7 @@ err_t Xlt_CnvRenameX2 ( char *src, char *dst )
#ifdef LONGNAMES
/* Adds the type suffix for a RISC OS filename. The type is extracted
* from the passed load address. unless DOS name is sufficient
* from the passed load address, unless DOS name is sufficient
*/
int Xlt_AddROType ( char *leafname, uint loadaddr )
{
......@@ -1353,7 +1325,7 @@ int Xlt_AddROType ( char *leafname, uint loadaddr )
sprintf(typebuf+1, "%03x", type);
}
// strip any acorn filetype suffix
/* Strip any acorn filetype suffix */
if (Xlt_SplitLeafnameX2 ( leafname, &RA, &nterm ) != OK) {
/* No type information - find end of string */
nterm = strchr(leafname, '\0');
......@@ -1362,28 +1334,27 @@ int Xlt_AddROType ( char *leafname, uint loadaddr )
/* Strip old type information in case source didn't have any either */
*nterm = '\0';
}
// check leaf for dos file type, else add acorn extra...
if (leafname[1] == ':')
{
/* Check leaf for DOS file type, else add acorn extra... */
if (leafname[1] == ':') {
term = strrchr(leafname, '.'); /* strrchr catches names like "file.tar.gz" */
}
else
{
else {
term = strrchr(leafname, '/'); /* strrchr catches names like "file/tar/gz" */
}
if(term)
{ // found a DOS type
if(!_swix(MimeMap_Translate,_INR(0,2)|_OUT(3), // so check the mimemap
MMM_TYPE_DOT_EXTN,term,
MMM_TYPE_RISCOS,&ftype))
{ // got a name valid in RISCOS
sprintf(ftypebuf,",%03x",ftype);
if(!strcmp(typebuf,ftypebuf)) return 1; // its OK.. no need to append type
if (term) {
/* Found a DOS type so check the mimemap */
if (!_swix(MimeMap_Translate, _INR(0,2)|_OUT(3),
MMM_TYPE_DOT_EXTN, term,
MMM_TYPE_RISCOS, &ftype)) {
/* Got a name valid in RISCOS */
sprintf(ftypebuf, ",%03x", ftype);
if (!strcmp(typebuf, ftypebuf)) return 1;
}
}
// Don't append ,xxx filetype if its the default
if(strcmp(typebuf,Default_FileTName))strcat(leafname, typebuf);
/* Don't append ,xxx filetype if its the default */
sprintf(ftypebuf,",%03x",LM_Vars.default_type);
if (strcmp(typebuf,ftypebuf)) strcat(leafname, typebuf);
return 1;
}
#endif
......
......@@ -102,7 +102,7 @@ command-keyword-table: LM_Command
invalid-syntax: "Syntax:\t*LMLogoff\r" ),
LMServer(min-args:1, max-args:17,
help-text: "*LMserver adds a server name and list of shared drives\r"
help-text: "*LMServer adds a server name and list of shared drives\r"
"Syntax:\t*LMServer server [sharename] [sharename] ...",
fs-command:,
invalid-syntax: "Syntax:\t*LMServer server [sharename] [sharename] ...\r", ),
......@@ -114,13 +114,6 @@ command-keyword-table: LM_Command
invalid-syntax: "Syntax:\t*LMPrinters server [printername] [printername] ...\r",
),
LMStats(min-args:0, max-args:0,
help-text: "*LMStats shows network statistics\r"
"Syntax:\t*LMStats",
fs-command:,
invalid-syntax: "Syntax:\t*LMStats",
),
FS(min-args:0, max-args:1,
help-text: "*Configure FS <name> sets the file server or domain name from "
"which LanManFS will attempt to boot\rSyntax:\t*Configure FS file-server-name",
......@@ -153,7 +146,7 @@ command-keyword-table: LM_Command
ListFS(min-args:0, max-args:1,
help-text: "*ListFS displays the servers in the current LAN workgroup or\r"
"the shares on the given server",
"the shares on the given server\rSyntax:\t*ListFS [server]",
fs-command:,
invalid-syntax: "Syntax:\t*ListFS [server]\r",
)
......
Replaced peek of 0x10C in OS workspace with call to SWI OS_MonotonicTime.
Removed a hardcoded 0x03800000 address, now calls SWI OS_Module.
Deleted "h.version" - no longer used (VersionNum included directly).
Added "smb_search.txt" to docs as it doesn't seem to be in recent CIFS specs
but we still use it.
Bizarre system variable LMDefaultType renamed to LanMan$DefaultType to match
the other similar variable names. Globals moved into LM_Vars structure.
Documentation of supported system variables:
LanMan$ScopeID <string> Sets the optional NetBIOS scope id
LanMan$NameServer <ip-addr> Sets the address of the name server
to use
LanMan$DefaultType <filetype-string> Sets a default filetype to use, when
reading an SMB share and no filetype
can be deduced this will be used, when
writing no ",xxx" extension will be
used for this type either
Replaced TIFF in the built in filetype table with JPEG, removed ARC. This
means the table now contains things that can be opened with the ROM apps only.
Removed debugging LMStats command (the stats now appear in LMInfo)
Function OmniS_FastMultiply64 was pushing LR to use as a scratch register (as
was macro FunctionEntry) with no corresponding pull. As macro Return happens
to pull LR the return address was valid but left a word on the stack for
every call to Free. This resulted in free (being the first value printed)
being correct but used and total space wildly incorrect: a 1132 terabyte
drive in my case.
Removed
FSEntry_Func_Reason_ResolveWildcard
FSEntry_Func_Reason_ReadFreeSpace
FSEntry_Func_Reason_ReadFreeSpace64
since these are only called if the FS supports image file extensions, which
LanManFS doesn't.
Minor tweaks
Marked a few tables as const, corrected some spelling mistakes.
%lx formatters changed to %x to remove a few compiler warnings.
Changed spelling of "Disk" to "Disc".
Added syntax description for ListFS to explain optional [server] parameter.
Changed print formatter for *FREE to match that of FileCore.
!MkDebug switch renamed so it assembles "s.Interface" correctly.
Rewrote directory finding routines (SMB_ReadDirEntries and its callers) as
it dealt poorly with reentrancy. This was highlighted by a desktop count
of a complex directory tree such as C:\Windows\System32 where it would
inexplicably stop part way through (on the test WinXP system about 2000 files
in) and some duff SMB responses coughed up onto the network.
This was caused by the resume value being associated with a specific
directory handle (but not being able to return both since OS_GBPB only allows
a 32 bit context to be returned in R4).
When desktop count recursed into a deeper level the top level find query
was closed, then when returning to the top level desktop count correctly
carried on from the last R4 context it had but the search went off in the
deeper (still open) find query. eg.
:
\Windows\System32 [say 1000 files total]
:
[500 normal files here]
:
\Windows\System32\SmallDir [say only 10 files]
:
[try to continue at position 502, but request it from 'SmallDir']
:
It was also mind meltingly complicated for no apparent reason.
The short filename version has been correspondingly updated, so they both now
count the same number of files. Because the short name version has a 21 byte
directory context to return in R4 a simple hash of this is used, on future
calls the search will use the last cached 21 byte context only if the
directory hasn't changed AND the context is valid AND the hash matches -
otherwise a manual search for the hash is made (which may be a bit slow but
hopefully infrequent).
Short directory find tested by setting MAX_DIALECT to 0 temporarily.
The short filenames version of Att_GetInfo was rudely stomping on the load
address, now it AND's and OR's only the nybbles it is responsible for.
Modified the short filename character translation table to allow "{}" since
these are valid in both DOS and RISC OS, whereas before they had an
asymmetrical mapping.
SMB: search
This command is used to search directories.
Client Request Description
================================== =================================
UCHAR WordCount; Count of parameter words = 2
USHORT MaxCount; Number of dir. entries to return
USHORT SearchAttributes;
USHORT ByteCount; Count of data bytes; min = 5
UCHAR BufferFormat1; 0x04 -- ASCII
UCHAR FileName[]; File name, may be null
UCHAR BufferFormat2; 0x05 -- Variable block
USHORT ResumeKeyLength; Length of resume key, may be 0
UCHAR ResumeKey[]; Resume key
FileName specifies the file to be sought. SearchAttributes indicates
the attributes that the file must have, and is described in the "File
Attribute Encoding" section of this document. If SearchAttributes is
zero then only normal files are returned. If the system file, hidden or
directory attributes are specified then the search is inclusive@both the
specified type(s) of files and normal files are returned. If the volume
label attribute is specified then the search is exclusive, and only the
volume label entry is returned.
MaxCount specifies the number of directory entries to be returned.
Server Response Description
================================== =================================
UCHAR WordCount; Count of parameter words = 1
USHORT Count; Number of entries returned
USHORT ByteCount; Count of data bytes; min = 3
UCHAR BufferFormat; 0x05 -- Variable block
USHORT DataLength; Length of data
UCHAR DirectoryInformationData[]; Data
The response will contain one or more directory entries as determined by
the Count field. No more than MaxCount entries will be returned. Only
entries that match the sought FileName and SearchAttributes combination
will be returned.
ResumeKey must be null (length = 0) on the initial search request.
Subsequent search requests intended to continue a search must contain
the ResumeKey field extracted from the last directory entry of the
previous response. ResumeKey is self-contained, for on calls containing
a non-zero ResumeKey neither the SearchAttributes or FileName fields
will be valid in the request. ResumeKey has the following format:
Resume Key Field Description
================================== =================================
UCHAR Reserved; bit 7 - consumer use
bits 5,6 - system use (must
preserve)
bits 0-4 - server use (must
preserve)
UCHAR FileName[11]; Name of the returned file
UCHAR ReservedForServer[5]; Client must not modify
UCHAR ReservedForConsumer[4]; Server must not modify
FileName is 8.3 format, with the three character extension left
justified into FileName[9-11]. If the client is prior to the LANMAN1.0
dialect, the returned FileName should be uppercased.
SMB_COM_SEARCH terminates when either the requested maximum number of
entries that match the named file are found, or the end of directory is
reached without the maximum number of matches being found. A response
containing no entries indicates that no matching entries were found
between the starting point of the search and the end of directory.
There may be multiple matching entries in response to a single request
as SMB_COM_SEARCH supports wildcards in the last component of FileName
of the initial request.
Returned directory entries in the DirectoryInformationData field of the
response each have the following format:
Directory Information Field Description
================================== =================================
SMB_RESUME_KEY ResumeKey; 00..20 Described above
UCHAR FileAttributes; 21 Attributes of the found file
SMB_TIME LastWriteTime; 22..23 Time file was last written
SMB_DATE LastWriteDate; 24..25 Date file was last written
ULONG FileSize; 26..29 Size of the file
UCHAR FileName[13]; 30..42 ASCII, space-filled null
terminated
FileName must conform to 8.3 rules, and is padded after the extension
with 0x20 characters if necessary. If the client has negotiated a
dialect prior to the LANMAN1.0 dialect, or if bit0 of the Flags2 SMB
header field of the request is clear, the returned FileName should be
uppercased.
As can be seen from the above structure, SMB_COM_SEARCH can not return
long filenames, and can not return UNICODE filenames. Files which have
a size greater than 2^32 bytes should have the least significant 32 bits
of their size returned in FileSize.
......@@ -33,6 +33,8 @@ struct LMvars
char *password_ptr; /* Default password e.g. none */
bool verbose;
int initialised; /* Initialisation state */
int default_type; /* Type for which no ",xxx" suffix will be added */
int untyped_address; /* Base of the OS ROM */
};
extern struct LMvars LM_Vars;
......@@ -27,13 +27,6 @@
#define FilingSystemName "LanMan"
#define Our_FS_Number 102
/* Default map filetype when file on server has no type info */
#define Default_File_Type_Number FileType_Text
/* Env Variable to contain replacement default type */
#define DefaultTypeEnvVar "LMDefaultType"
#define FSControl_AddFilingSystem 12
#define FSControl_SelectFilingSystem 14
#define FSControl_RemoveFilingSystem 16
......
......@@ -42,7 +42,6 @@ extern void Omni_StartUp ( void );
extern void Omni_Shutdown ( void );
extern void Omni_ClearLists ( void );
extern bool Omni_Registered;
extern void Omni_ServiceCall ( _kernel_swi_regs *R );
extern void Omni_RecheckInfo ( int flags );
......
......@@ -23,7 +23,7 @@
#define DIRENTRY_SIZE 22
typedef err_t (*ENUM_DIR_FN) ( BYTE *entry, int format, void *private );
typedef err_t (*ENUM_DIR_FN) ( BYTE *entry, int format, bool *taken, void *private );
struct disk_size_response
{
......@@ -47,9 +47,6 @@ struct disk_size_response
#define MAX_SETUPWORDS (4)
#endif
typedef union Transact_SearchContext Transact_SearchContext;
struct TransactParms
{
int parms_in_len;
......@@ -84,12 +81,7 @@ struct TransactParms
# define sizeof_TransactParms_external (sizeof(struct TransactParms))
#endif
/* Exported routines ================ */
/* Directory functions */
extern err_t SMB_MkDir ( char *path );
extern err_t SMB_RmDir ( char *path );
extern err_t SMB_Delete ( char *path );
......@@ -97,12 +89,11 @@ extern err_t SMB_Rename ( char *oldpath, char *newpath );
extern err_t SMB_GetAttribs ( char *filename, DOS_ATTRIBS *pAttr );
extern err_t SMB_SetAttribs ( char *filename, DOS_ATTRIBS *pAttr );
extern err_t SMB_ReadDirEntries ( char *path, int max_count,
ENUM_DIR_FN dirfn, void *private, Transact_SearchContext *);
ENUM_DIR_FN dirfn, void *private, void *context);
extern err_t SMB_GetFreeSpace ( char lettr, struct disk_size_response
* pDSR );
/* File functions */
extern err_t SMB_Create ( char *filename, DOS_ATTRIBS *pInAttr,
int *pOutFH );
......@@ -120,19 +111,15 @@ extern err_t SMB_Flush ( int fh ) ;
extern err_t SMB_Close ( int fh, DOS_ATTRIBS *pAttr );
/* Printer functions */
extern err_t SMB_OpenPrinter ( char drvlettr, char *printid, int *ph_out );
extern err_t SMB_WritePrinter ( int PH, BYTE *data, int datalen );
extern err_t SMB_ClosePrinter ( int PH );
/* Transaction (RPC) functions */
extern err_t SMB_Transact ( char drvlettr, char *trans_name,
struct TransactParms *pT );
/* Connect/disconnect functions ----------------------- */
/* Connect/disconnect functions */
extern err_t SMB_CreateShare ( int service_type,
int style,
char *serv_name, char *drv_name,
......@@ -241,7 +228,7 @@ extern err_t SMB_Shutdown ( void );
callbacks, SMB_EnumerateDir callbacks etc). This probably
means anything in Network, LLC, and NetBIOS.
(iii) Any other module (=C source file) may use it freely. In
(iii) Any other C source file may use it freely. In
general, it should be assumed corrupted across calls
between modules.
*/
......
......@@ -20,26 +20,22 @@
*
*/
#define SEARCH_ST_SIZE 21
typedef struct ActiveShare *hSHARE;
union Transact_SearchContext {
struct Transact1_SearchContext {
bool NextSearchOK;
BYTE SearchState[SEARCH_ST_SIZE];
hSHARE SearchDrive;
} t1;
struct Transact2_SearchContext {
struct Transact1_SearchContext t1;
#define SEARCH_ST_SIZE 21
typedef struct {
/* Common state */
hSHARE search_drive;
struct TransactParms tp;
char dir_path[DOS_NAME_LEN];
DWORD resume_key;
bool resume_key_encountered;
WORD dir_handle;
bool dir_handle_valid;
char last_filename[DOS_NAME_LEN];
} t2;
};
/* Cached state for short names */
BYTE resume_state[SEARCH_ST_SIZE];
} Transact_SearchContext;
extern void Transact_addword(struct TransactParms *TP, int value);
extern void Transact_addlong(struct TransactParms *TP, long value);
......
......@@ -31,7 +31,7 @@ extern void strcpyn_lower ( char *d, const char *s, int n );
extern void Xlt_Jumble ( char *str );
extern void Xlt_Unjumble ( char *str );
#define CNV_DEFAULT_TYPE FileType_Text
#define CNV_DATETIME 1
#define CNV_ATTRIBS 2
......@@ -49,6 +49,8 @@ extern void Xlt_NameDOStoRO ( char *riscos_dst, char *dos_src );
#define NM_PRESERVED 0
#define NM_LOWERCASE 1
#define NM_FIRSTCAPS 2
#define NM_INTERNAL 4 /* Can't be selected at the CLI */
/* Mime mappings */
#define MimeMap_Translate 0x50B00
......