System Software Directories - Win32 API

Contents

More on DOS, Windows 3.1 and Windows95
Windows 3.1
Windows 95
Win32 API
Directory Traversal
Drives
Conclusion

Win32 Directory API

More on DOS, Windows 3.1 and Windows95

The underlying way of making system calls to MSDOS is via interrupt 21H. Each MSDOS system call is numbered, and expects certain parameters in registers. So a system call is made by loading the registers and calling interrupt 21H. MSDOS examines the registers and takes action accordingly.

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.

Windows 3.1

Windows 3.1 relies on INT 21H calls to access the filesystem. That is, any Windows 3.1 program that wishes to, say, read or write to a file must load registers and call INT 21H. The mechanism may be hidden as a C function call perhaps, but the C function call will do this stuff.

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.

Windows 95

Windows 95 uses the same filesystem by default. This is to cope with ``legacy'' applications such as Norton Utilities that assume this filesystem. There is new 32-bit code to handle this filesystem though.

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.

Win32 API

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);

Directory Traversal

The FindFirstFile() opens as directory for reading and returns the first file that matches the dirName parameter. This parameter is a string that may contain wildcard patterns for file names.

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);
}

Drives

The MSDOS file system has the the concept of drives in addition to directories and files. There is a set of functions to get and set drive volume information
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(...);

Conclusion

The generic directory operations can be done by a set of Win32 functions for any file system supported by Win32, such as the MSDOS file system and the Windows NT file system.