Oh dear! It’s RISC OS!

I can tell that I’m debugging British code (RISC OS SMB client) because of the phrasing of some of the debug comments:

"Oh dear - client ran out of buffer space!\n"

/* Oh dear - looks likely the create would fail anyway! */

case UFORMAT_FRMR: /* Oh dear */

/* FindNBNSName decodes the encoded name representation in NBNS packets (dear Anne, why oh why…?) and searches the name table for a match.

I don’t know who Anne is, but I agree that the NBNS name encoding is very odd. Thankfully, DNS is the preferred method for looking up local SMB servers, but the old NetBIOS Name Service works well enough for LANs, and for my testing purposes.

I’m currently fixing the bug that emitted the “Oh dear – client ran out of buffer space!” message, along with a much more worrisome “WriteEntry detects a buffer overflow (%d > %d)\n” message. It turns out that with long filenames, a directory listing can quite easily fill up a 512 byte buffer before getting to the 18 names requested. The proper thing to do, which the current code isn’t doing, is to return to the caller the number of directory entries that did fit completely in the buffer, so that they can request another 18 names starting from the next index.

Here’s how to write a filesystem in RISC OS. It’s amusingly old-school. This is one of the areas of the programmer’s reference manual that hasn’t been updated for RISC OS 5, but it had everything that I needed to know. I recently found my receipt for my order of the 16GB ePic card (£50) on July 2021. Without the software on that card, and the hundreds of hours I spent in 2021 messing around with RISC OS, I’d be in no position to work on what I’m working on.

I need to rant about Microsoft’s bizarre SMB1 (the obsolete protocol from pre-2008) protocol. There are these RAW_READ and RAW_WRITE commands defined in the CIFS (SMB 1.0) spec that had been deprecated in favor of some “AndX” commands (a way to chain some SMB1 commands, but not others) that there’s no need for me to waste time implementing.

The current RISC OS client tried to use these raw read/write commands (where the response/request isn’t formatted like a normal SMB packet and so requires special processing) for any reads/writes over 4K, but it turns out Samba doesn’t implement the protocol the way it’s described, so I can’t get either reads or writes to work without getting out of sync with the server.

Here’s where Microsoft gets extra credit for out-Microsofting themselves with a ridiculous v1 spec. There’s a capability bit returned in the initial SMB negotiation that says whether or not the RAW_READ and RAW_WRITE commands are supported. Both Samba and Windows Vista say that they support the feature, but Windows (Vista / Server 2008 or later) will close the connection if you try to use either of them. I haven’t checked if newer versions of Windows turned off that capability bit, but I bet there’s some bug compatibility reason they have to not change that field without breaking some other buggy server/client.

Since SMB1 is the old protocol, I #ifdef’d out the “raw” read/write code altogether, since 4KB reads/writes that work are far superior to 32KB ones that don’t.

Thankfully, the rest of the job involves the sensibly-designed SMB 2.1 and not the bizarro spaghetti mess of SMB 1.0. The Microsoft of the Ballmer years were light-years ahead of Bill Gates’s Microsoft in terms of design docs and code quality. I attribute the greater professionalism to a relative lack of sleep deprivation and crunch mode mentality. Why do people have nostalgia for 1990’s Microsoft stuff?

If you’re wondering what SMB 2 does for performance, there’s a sliding window of asynchronous requests, which is determined by the server, which the client has to request “credits” from, one credit for each message or for each 64KB, whichever is greater. The reason I have a Vista VM in particular is it has an early SMB 2.0.2 protocol version that doesn’t use the credits field, so I want to test both.

RISC OS is extremely polling-based, which gives me an uneasy feeling of wasted cycles, compared to any OS that was designed for preemptive multitasking. Having a message loop in every GUI app, and even inside of the file sharing client, feels very “Windows 3.1” to me, but, now that I think about it, RISC OS is far nicer than Windows 3.1. There was an extreme lack of artistic merit to Microsoft’s products.

Since there’s a polling loop inside the filesystem module, it’s no problem for me to handle any size of read or write by sending as many outstanding requests on the TCP connection as the server-allocated quota scheme will let me, and the polling loop exits when it’s time to return to the caller of the filesystem. Unlike the Amiga, you can’t really multitask properly when this activity is going on. The mouse pointer still moves because it’s on an interrupt, but at least for doing the SMB2 file transfers, I have the single ARM core that RISC OS supports (no SMP!) to myself.






Leave a Reply

Your email address will not be published. Required fields are marked *