MSDOS runs in so-called ``real mode''. This is the only mode for an 8086, but is only one of the possible modes for the 80386 or later. In real mode, addresses are 20 bit addresses, using a segmented memory architecture (see later lectures on memory). This gives an address space of 1 Mbyte only. Within this address space there is no memory protection. All of the 1M is accessible to any application. At the bottom of this memory space is MSDOS itself, so a mis-behaved application can trash the O/S code.
Windows 3.1 on a 386 or later, Windows NT, Windows 95 run in the 386 ``protected mode''. This has 32-bit addressing and memory protection mechanisms.
MSDOS, Windows 3.1 and Windows 95 all use the MSDOS file system. This has the FAT table to point to succesive blocks of a file, and directory entries which contain the 8+3 filename and information such as access mode, last modification time and file size.
Execution of INT 21H causes a general protection fault, which is caught by Windows 3.1. Since the MSDOS call runs in 16-bit real mode and the application that generated the interrupt is running in 32-bit protected mode, the role of Windows 3.1 is to switch modes, proceed with the system call and then switch back to protected mode. Thus every filesystem access is slowed down by this need to switch processor modes twice.
The new 32-bit code is designed to handle multi-tasking access to the filesystem. It is ``re-entrant'' so that it can be interrupted and called again. It has a shorter ``critical section'' so that access by processes to the disk is not locked out for so long.
A standard C function call interface to this code is available through the Win 32 API. It can also be accessed by INT 21H, for Windows 3.1 and MSDOS applications to run unchanged. When an INT 21H occurs, there is no call to the old MSDOS file handling code - this is not in Windows 95. Instead a call to the new code is made. No processor mode switch to real mode is made - unless the only device driver available is an old Windows 3.1 driver that runs in real mode.
Windows 95 has removed one of the problems of the MSDOS filesystem which is the 8+3 filename restriction. Filenames can be upto 255 characters in length, with a wider set of characters allowed. This is done without serious change to the MSDOS filesystem. Just as before, the directory holds the filename (unlike Unix). In a directory entry is the old ``short'' 8+3 filename, plus file attributes: read_only, archived, etc.
The file attributes part is the key (sorry, kludge) to the new ``long'' names. Certain attributes are ``illegal'' and cannot occur. Applications that check and maintain the filesystem (such as chkdisk look for such illegal combinations and fix illegal directory entries. There are however, some combinations that are not only illegal but also cannot be fixed because they ban modifications! All of the file system utilities tested by Microsoft could not ``fix'' such illegal combinations.
A long filename is stored as a regular directory entry with a short filename constructed by some algorithm from the long name. Following this are a series of extra directory entries which hold the long filename, all with one of the illegal attributes, which now means ``component of long filename''.
There are a number of checks to ensure that the short name remains consistent with the long name (e.g. using rename on a floppy disk copy). To guard against untested utilities not realising the new system and altering ``illegal'' directory attributes, a new MSDOS system call is invented to protect direct filesystem access.
BOOL CreateDirectory(LPTSTR dirName, LPSECURITY_ATTRIBUTES security); BOOL RemoveDirectory(LPTSTR dirName); HANDLE FindFirstFileLPTSTR searchFile, LPWIN32_FIND_DATA findData); BOOL FindNextFile(HANDLE findFile, LPWIN32_FIND_DATA finData); BOOL FindClose(HANDLE findFile); BOOL SetCurrentDirectory(LPTSTR newDir); DWORD GetCurrentDirectory(DWORD bufSize, LPTSTR buffer);
The function returns a pointer to a structure
typedef struct _WIN32_FIND_DATA { DWORD dwFileAttributes; FILETIME ftCreationTime; FILETIME ftLastAccessTime; FILETIME ftLastWriteTime; DWORD nFileSizeHigh; DWORD nFileSizeLow; DWORD dwReserved0; DWORD dwReserved1; TCHAR cFileName[MAX_PATH]; TCHAR cAlternateFileName[14]; } WIN32_FIND_DATA;A program to print the C files in the current directory is
#include <iostream.h> #include <windows.h> int main(int argc, char *argv[]) { WIN32_FIND_DATA findData; HANDLE fileHandle; fileHandle = FindFirstFile("*.c", &findData); while (fileHandle != INVALID_FILE_HANDLE) { cout << findData.cFileName << endl; fileHandle = FindNExtFile(fileHandle, &findData); } FindClose(fileHandle); exit(0); return(0); }
BOOL GetVolumeInformation(...); // volume name etc UINT GetDriveType(LPTSTR rootName); // e.g is it a CDROM BOOL GetFreeDiskSpace(...); DWORD GetLogicalDrives(void); DWORD GetLogicalDriveStrings(...); // e.g. "C" BOOL SetVolumeLable(...);