SHAREing Files in DOS

Copyright 1994, All Rights Reserved Worldwide

Bob Butler and Kevin Stilwell

The explosion in peer-to-peer networks and multi-tasking environments in DOS has put DOS's file sharing systems in the spotlight. The little known and poorly documented DOS SHARE.EXE command has become the center of a number of issues in using database programs on networks and in multi-tasking environments.

The Operating System's Role in File Sharing

In operating systems such as Unix, Novell Netware, and Windows NT, file sharing services are an integral part of the operating system kernel. These functions are handled completely internally with no system setup requirements of the user.

However, in DOS, file sharing is handled by a separate component which is not part of the DOS kernel or its core components (COMMAND.COM, MSDOS.SYS, or IO.SYS). In MS-DOS 3.0 and later, file sharing is provided by the TSR program named SHARE.EXE, which must be loaded by the computer user. Most database engines depend on these DOS file sharing services to exercise their full range of file sharing capabilities.

SHARE must provide two basic services to be able to allow multiple concurrent access to files in DOS: 1) Arbitration of access requests, and 2) Updating of in-memory information that describes file status and resources. The first implication of this is that all disk File Allocation Tables (FAT) and related I/O functions must be routed through SHARE to control which files are provided these services.

A principle function of the DOS file handle (in conjunction with the File Allocation Table or FAT) is to keep track of the properties and conditions of the files on the hard disk. For each file open on the computer, DOS maintains a copy of the information about the file in the file handle. This includes both global information about the file on the disk (size, location, etc.) and local information that pertains to each open instance of that file.

When SHARE is loaded, quite a bit of work is done regarding this local file information. If a file is opened by multiple programs, and one program changes the global information about a file (e.g. changes the file size), SHARE must update the local information for all open instances of that file (i.e. update all the file handles). SHARE's main role in file sharing is to provide a mechanism for the file handles to be informed of these legitimate file changes and not to erroneously conclude that a file change is due to a file corruption.

The Basics of SHARE.EXE

Since SHARE is taking such a fundamental role in the workings of the disk I/O functions, it has some characteristics which differ from other TSRs. The following highlights these SHARE characteristics:

SHARE must be loaded in the original (i.e. permanent) system environment (this becomes an issue in Windows and other multi-tasking environments where virtual machines are possible).

Once loaded, SHARE cannot be unloaded without rebooting the computer.

SHARE uses memory, and cannot address more than one segment (64k) of memory, resulting in a fixed amount of file sharing that can be managed by SHARE.

SHARE has parameters (set by command line switches) for allocating memory for the file names that will be managed by SHARE (the Files setting - /F:) and the number of files that can be locked by SHARE (the Locks setting - /L:). The default settings for SHARE when these command line switches are not used are so low (/F:2048 /L:20), that for all practical purposes, loading SHARE without properly setting these switches will actually prevent file sharing.

SHARE parameters cannot be changed at run-time. The configurations of SHARE set when it is loaded cannot be changed without rebooting and reloading SHARE.

SHARE requires the DOS read-only attribute to be on any overlaid DOS executable program (the main EXE) or program that performs the functions of an executable (such as a Clarion 2.1 .PRO file).

SHARE and the Read-Only Attribute

Requiring the main EXE to be read-only for overlaid DOS applications is an often overlooked aspect of SHARE. Most overlay managers compiled into overlaid applications will write some of the overlaid files to the hard disk. These overlaid files can only be shared if the main EXE is set to have a read-only attribute when SHARE is loaded and data files are being shared.

If SHARE is loaded (regardless of its command line settings) and an overlaid EXE is not set to read-only, and if an attempt by another user or session is made to open any file that is already open, SHARE will immediately issue a DOS error 20h "Sharing Violation". This is the most common error reported when using database programs on a network. Using the DOS ATTRIB command as follows immediately corrects this error:

ATTRIB +R APPNAME.EXE

However, the lack of a read-only attribute is not the only cause of a Sharing Violation error. Sharing violation errors can also be caused by too low Files (/F:) and Locks (/L:) settings on the SHARE command line (another common SHARE related error is the "Access Denied" error which results specifically from the Locks setting being too low).

Sharing Violations can also result from programming errors. Programming code errors result from using the Clarion OPEN() function where SHARE() is required on a network. This programming code error is easier to make than you might think. If you are hand coding in Clarion 2.1 and you issue a file command such as SET(), PUT(), ADD(), etc. without explicitly first issuing a SHARE() instruction, the Clarion libraries will issue an OPEN() (rather than a SHARE()) automatically. This "implicit open feature" has been traced as the cause of many Sharing Violation errors over the years.

Microsoft has recently reported that Sharing Violation errors can also occur in a Windows for WorkGroups (WFW) Network (version 3.11) whenever 32 bit File Access (not Disk Access) is used. This is a known bug in WFW and has nothing to do with SHARE.

The requirement that the main EXE be read-only can be problematic in the real world when sending out new updated versions of your application. Your update install program may be unable to overwrite the existing main EXE due to its read-only status. The Clarion Software Distribution Kit (SDK), and most install programs, give you no notice of this problem, and in fact all appearances suggest that the EXE has been updated. Then your install program would typically run Clarion's Filer Utility at the conclusion of the installation to update the existing data. However, since this main EXE was not really updated with the new one, the updated data and old program are no longer matched, resulting in an Invalid Record Declaration error.

No matter how many times you give instructions to the installer to remove the read-only attribute, it often does not get done. The installer may also fail to re-set the read-only attribute after the installation causing a Sharing Violation error. This was one of the reasons we switched from the Clarion SDK to using EZ-Install (303-674-9430). We were able to modify EZ-Install to remove and replace the read-only attribute on the main EXE automatically as part of the installation of an update.

SHARE Files and Locks Command Line Settings

The default settings for SHARE are /F:2048 and /L:20. In other words, if you do not specify any command line settings for SHARE, Files is set to 2048 and Locks is set to 20. Share uses 6.1K of memory at these settings and this is the minimum memory requirement to load SHARE. SHARE can only address one segment of memory, which effectively limits the maximum amount of memory SHARE can use to 64K. This has the effect of placing an absolute limit on the number of files that can be shared when SHARE is loaded. These limits are very important for the use of Database applications on networks where SHARE is loaded.

If you set the Files and Locks settings such that more than 64K is required, SHARE will not load and issues a rather cryptic message: "insufficient memory" ("not enough memory" in IBM DOS). It doesn't say anything about the insufficient memory being related to an attempt to load SHARE. All you see when the AUTOEXEC.BAT is loading is the insufficient memory message, with no indication that SHARE did not load. This can make troubleshooting difficult if you think SHARE is loading, but it's not, due to excessively high Files and Locks settings.

The amount of memory used by the Files setting is exactly equal to the files setting itself. If Files is set to 2048, then 2048 bytes of memory are being contributed to SHARE's memory use by this setting. Each Lock "officially" uses 16 bytes of memory, but 20 bytes is realistic in the real world of memory mapping and memory boundaries.

The number of bytes to allocate for each file for the Files setting is determined by the number of characters in the full path name of the file. Microsoft believes the average file path name is 20 bytes long (page 565 of MS-DOS 5.0 manual). Therefore, Files setting needs to be 20 bytes for each file opened for each simultaneous user. We like to use 24 bytes because the paths are typically longer in database applications (and it helps with the math later on). Therefore, the Files component of SHARE requires 24 bytes of memory for each file, for each simultaneous user of the application.

DOS requires 1 lock for each shared file. However, most peer-to-peer networks have a related file playing a role in record locking, and 2 Locks per file is usually recommended. As mentioned above, each Lock is supposed to require 16 bytes of memory, but we recommend using 20 bytes for these calculations. Therefore, Locks typically require 40 bytes per open file, per simultaneous user of the application.

As a result, 64 bytes (24 for Files and 40 for Locks) of memory is required for each file for each simultaneous user. If you divide 64,000 bytes (SHARE memory maximum) by 64 bytes (required for each open file), you get 1,000, which is a good approximation of the total number of files that can be opened when SHARE is loaded.

There is a relationship between the Files and Locks settings based on these file path sizes and network software recommendations. Essentially this is /F:24 and /L:2 for each open file on the system, for each simultaneous user sharing the main EXE. This reduces to a good rule of thumb, set 12 files for every lock and set 2 locks for every file, for every user. The following summarizes this formula:

Files= (No. of simultaneous Users) * (Total No. of Open Files) * 24

Locks= (No. of simultaneous Users) * (Total No. of Open Files) * 2

Remember, if you have long path names or the computer system opens many files in addition to those used by your application, you may need to increase these numbers.

For an application that opens 60 files (including system files) and expects a maximum of 10 simultaneous users, the SHARE settings would be /F:14400 /L:1200. This would use about 62K of memory, which is about the limit for SHARE. Therefore, the largest number of simultaneous users able to simultaneously use an application that opens 60 files when SHARE is loaded is 10 users. In spite of the fact that peer-to-peer networks sell licenses up to 250 users, for a typical Database application, the number of users is in reality limited to a much smaller number.

In fact, with Novell Lite and Personal Netware, the number of files that can be shared is actually less than determined by SHARE. With Netware Lite, you cannot exceed the DOS limitation of FILES=255 in the CONFIG.SYS, which effectively limits you to 4 simultaneous users on our typical 60 file database Application. With Personal Netware (and the Networking included with Novell DOS 7), the DOS files limit has been extended to FILES=1000, bringing you close to the limits imposed by SHARE for a typical database application.

Lantastic allows you to set the FILES setting on the server up to the limits of SHARE. However, the default setup for the Lantastic Server after installation is "as per CONFIG.SYS" for the FILES setting. This has the practical effect of also limiting Lantastic, unless the default setup is modified. You must go to Lantastic's Server Start up Parameter settings and enter the number of Files you will need.

The error that is issued by the peer-to-peer networks for the FILES= setting being too low in the CONFIG.SYS is "Unable to Share files" (or Cannot Share Files). This is often mistaken for a Sharing Violation Error caused by SHARE.

The number of Files opened by an application becomes an important program design issue for the programmer, if you expect that your application will be used on a peer-to-peer network or will be background processing in a multi-tasking environment. The data file design regarding number of keys and database engine chosen can dramatically affect the number of files opened on a network. Clarion, Paradox, Access, and most XBase database engines all create a separate DOS file for each key (permanent index) specified in the data file. Therefore, if you create a customer file with 3 keys (such as last name, customer number, and ZIP code), you would be creating 4 DOS files (with the Clarion 2.1 database engine; CUSTOMER.DAT, plus CUSTOMER.K01, CUSTOMER.K02, and CUSTOMER.K03).

Also, many Clarion programmers, due to the ease of using the Data Dictionary, often create many keys to anticipate all possible future presentations of the data. Although there is nothing wrong with this from the programming point of view, the impact on the number of DOS files and the inherent limitations of SHARE should be considered when specifying keys (when using database engines that have separate key files).

The Files issue can actually influence your choice of database engine (i.e. data file driver). For example, Btrieve does not create a separate DOS File for every key created. This can dramatically reduce the number of DOS Files opened by an application, greatly increasing the number of simultaneous users that could use an application before the limits imposed by SHARE come into play. Although the Clarion file driver has not yet been released, C-tree has an option called super-file, that places everything in one DOS file for each data type (no word on whether this feature will be supported by the Clarion C-tree driver). The new Clarion TopSpeed Driver is also rumored to not have separate key files.

A final point about Files. If your application (in combination with system files) will open more than 40 files, you will be constantly getting calls about "Too Many Open Files" errors on Novell Netware Networks. In addition to the FILES= statement required by DOS in the CONFIG.SYS, Netware requires you to specify the number of File Handles to set aside for Novell's File Sharing activities. This is normally done with a FILE HANDLES=## statement, (where ## is the total number of Files that will be opened on the workstation), in an ordinary ASCII text file named SHELL.CFG (or NET.CFG in Novell 3.1x).

This SHELL.CFG (NET.CFG) file must be in the same directory as the Novell Network files (IPX/NETX) that are actually being used to boot the workstation (usually the root directory of the boot disk). If the Novell Server detects a workstation logging in without a SHELL.CFG, it automatically creates a run-time version of SHELL.CFG. However, the default setup for most Novell Servers is to create a run-time SHELL.CFG with FILE HANDLES=40, which may not be enough for your application.

In this case, you will need to either have the user create a SHELL.CFG file in the root directory of the boot drive on the workstation, or bring in a Novell technician to reconfigure the server to create run-time SHELL.CFGs with higher File Handles settings. Increasing the FILES= statements on the workstations CONFIG.SYS will not help. If you can keep your applications file requirements under 40 (allowing for system files), you can avoid this problem altogether on Novell Networks.

SHARE and Memory Management

In addition to the issue of memory used by Files and Locks settings, the fact that SHARE can use up a considerable amount of precious conventional memory (up to 64K) is also an important issue. The memory impact of SHARE is lessened by the fact that SHARE can be loaded into upper memory on 368 and later computers. Generally SHARE works well in upper memory, but there have been some reported problems. For example, early releases of Microsoft Word for Windows 6 would not save a file if SHARE was loaded in upper memory.

A more frequent problem is that as SHARE requirements approach 64K, there is often not enough upper memory left to load SHARE. Your total upper memory might be sufficient, but there must be one contiguous memory area available to load SHARE into upper memory. When using DOS memory managers such as EMM368.EXE and MEMMAKER, particularly with many device drivers in the CONFIG.SYS, there is seldom one continuous 64K block of memory available (this has become a real problem in the days of multi-media and SCSI devices). QEMM does a much better job of opening larger blocks of upper memory (even without using their Stealth technology), but QEMM is not always available at customer sites.

If DOS MEMMAKER or QEMM Optimize is not available, such as with MS-DOS 5.0, one solution is to use the NOEMS command for EMM386 and to load SHARE as soon as possible in the boot cycle. In fact, this is often the argument for loading SHARE in the CONFIG.SYS using the INSTALL= command. The sooner SHARE is loaded, the more likely it is to find one contiguous block of upper memory when loading SHARE high. It is always a good idea to load SHARE early in your AUTOEXEC.BAT in case any other TSRs are fooling with disk I/Os or interrupts that affect SHARE.

Normally, SHARE should be loaded in the AUTOEXEC.BAT just after any SCSI API or MSCDEX drivers, and NET BIOS TSRs (such as Novell IPX/NETX or Lantastic's AILANBIO/AE2), but before other I/O related TSRs such as mouse drivers, print spoolers, disk caching, etc.). Lantastic likes to see SHARE loaded just before their SERVER.EXE command. Although SHARE can be loaded at any time (in the original environment) from the command prompt or a batch file such as using Lantastic's STARTNET.BAT, this is less desirable than loading SHARE at start up in the CONFIG.SYS or AUTOEXEC.BAT.

Running DOS MEMMAKER (available in DOS 6.x and later) or QEMM Optimize will usually place SHARE in upper memory, particularly if SHARE is at a lower memory requirement and SHARE is in the CONFIG.SYS or early in the AUTOEXEC.BAT. However, if you increase the Files and Locks settings, you must remember to re-run MEMMAKER or Optimize. The higher settings will often exceed the memory area to which SHARE is originally assigned, causing SHARE to "load low" in conventional memory. This can cause a sudden reduction of conventional memory that causes problems with available memory for your applications.

If you think the Files and Locks settings may have to be increased at the site and/or Files and Locks settings are already near the maximum, it is advisable to set aside a dedicated 64K block of upper memory for SHARE. This can be done by excluding a 64K block of memory on the memory manager command line, before running MEMMAKER or Optimize to make sure there is a 64K block of memory available for SHARE. Typical 64K blocks to try for the exclude are A000-AFFF, B000-BFFF, C000-CFFF, D000-DFFF, and E000-EFFF (keep in mind that other devices may already have staked a claim to these areas even if you exclude the region from the memory manager).

After running MEMMAKER or Optimize remove the excluded region from the memory manager's command line and SHARE should load into this high memory area (with the proper loadhi commands). This way if you have to increase the Files and Locks setting later on, you will not have to re-run MEMMAKER and Optimize (not always easy to do over the phone on a tech support call).

When does SHARE have to be Loaded

SHARE must be loaded whenever a Clarion program (and programs from most other relational database development systems), including those using the database file drivers available to Clarion 3.0, has the possibility of its data files being opened and changed by more than one user (or session) at the same time. This can occur both in networks and in multi-tasking environments.

Network Environments

Any network that relies on the file sharing capabilities built into DOS, must have SHARE loaded to safely share files. This includes just about all of the peer-to-peer networks, such as Lantastic, Novell Lite, Personal Netware, Windows for WorkGroups, PowerLan (but not PowerLan's PowerServer), InvisibleNet, Alloy Network, etc. Lantastic version 6.x includes a Server setup option that can use an "Internal SHARE" eliminating the requirement to load SHARE separately. SHARE does not have to be loaded on Novell Netware, Banyan Vines, and Windows NT Advanced Server.

However, on Netware or Banyan, if SHARE is loaded on the server for any reason, then all the rules of SHARE also apply to these networks. The support for 16bit DOS and Windows 3.x applications provided by Windows NT includes file sharing as part of the main operating system kernel. Therefore, you do not have to load SHARE on Windows NT. Interestingly, the Windows NT DOS support includes a "dummy" SHARE.EXE to satisfy programs that require and check for SHARE to be loaded (this cannot be separately removed from the DOS support). However, the existence of this dummy SHARE in Windows NT does not trigger the requirement for the main EXE to be read-only or to set Files or Locks settings for SHARE.

What about networks that are not mentioned here. The general rule is that if you are installing a DOS-based network (i.e not OS/2, Windows NT, or other 32bit bases system) where you do not have to reformat the hard drive for the new network operating system, then SHARE probably will have to be loaded on this network.

SHARE only has to be loaded on the computer providing server services in a typical peer-to-peer network environment.

Multi-Tasking Environments

In a multi-tasking environment, such as Windows, DesqView, Novell DOS 7, etc, if it is likely a multiple session of the program (particularly with background processing) involves files that might be opened and changed from another session, SHARE should be loaded.

A multi-tasking environment allows you to start your Clarion application and open files in a "virtual machine" (also known as a DOS window) then start the application in another DOS window and access the same files. Many users get away without loading SHARE in these environments because, unlike a network, it is less likely that simultaneous file activity will occur as you switch from one session of the application to another session. But it is entirely possible, particularly when running reports and queries in background, that you could simultaneously access multiple concurrent instances of the same files, such as those involved in the report or query. This can corrupt a file if SHARE is not loaded.

Also, if SHARE is loaded in a multi-tasking environment, you can get a Sharing Violation error without the main EXE being read-only or if Files and Locks settings are not adequate (and the Access Denied due to too low Lock settings), just as in a network.

If the workstation has a multi-tasking system such as Windows, in a network environment, the rules for SHARE for multi-tasking will apply regarding the workstation and the rules for SHARE regarding the network will apply on the server computer.

SHARE, the Database Engine, and File Locking

File locking is an important service performed by most database engines (i.e. data file drivers) that allows more than one person to be in the same file at the same time. File locking allows one user to view a record while another user is changing the record. Since the database engine provides record locking services and control of these locking services is often the programmer's responsibility, they often assume that all record locking is done solely by the database engine.

However, some aspects of record locking, such as locking a region of a file to allow partial use while changes are being made to another region of a file, rely on certain interrupt calls made by the database engine through DOS. These calls, such as Interrupt 24Fh, Function 5Ch to lock a region of a file, are only available when SHARE is loaded (in fact, this is one means of testing if SHARE is loaded). Therefore, the programmer could be issuing instructions through the code to the database engine that requires a call to Interrupt 24Fh, Function 5Ch, but that service is not being provided by DOS since SHARE is not loaded.

Programmers often argue that they have had no problem with multiple users of their application on peer-to-peer networks without SHARE being loaded. Certain file locking, such as denying access to the entire file, can be controlled by the database engine through interrupts that are available whether or not SHARE is loaded. Also, if the usage pattern for the application is such that the same files are not opened and thereby do not require specific regions of the files to be locked, then the unavailability of these special interrupt calls does not present a problem.

For example, there can be situations where one user is always making entries in one part of the application (e.g. entering dues payments in the bookkeeping records), while the other user is always making entries in another part of the application (e.g. updating membership records). However, if the users change their usage pattern and open files such that the file region locks are required to prevent file corruption, without SHARE there is nothing to prevent this file corruption. It would be very bad programming practice to allow for file corruption by a simple change in the application's usage pattern.

This situation is not unique to Clarion. The Microsoft Access documentation states; "You can run Access without SHARE.EXE being loaded, but Microsoft does not recommend it. In fact, it goes so far as to say; "The only time you do not have to use SHARE.EXE is when you run Microsoft Windows for Workgroups in Enhanced mode. Microsoft Windows for Workgroups in Enhanced mode loads and uses a file-sharing program called VSHARE.386, which is a replacement for SHARE" (see "INF: Using SHARE.EXE and VSHARE.386 with Microsoft Access", Microsoft Developers Network CD, Volume 6).

Of course, you could design your program so that files are not shared. Therefore, Clarion and most database engines do not require you to load SHARE and do not check for it at run-time. Some databases will actually require you to load SHARE and check for it, such as Windows applications using the Paradox engine. Alpha 4 goes even further and demands SHARE be loaded any time NETBIOS is detected, whether or not you are planning on using the network to share files. Clarion, like Visual Basic, FoxPro, Access, and most Xbase database engines, leaves it to the programmer to make sure that the user loads SHARE where required.

Checking the status of SHARE

How does the programmer insure that SHARE is loaded and properly configured by the user? As discussed earlier, there are two things you need to safely share database files 1) is SHARE loaded and 2) is the main EXE that is sharing the files set to the DOS read-only attribute. Therefore, it becomes important for the user to have an easy method of determining if SHARE is loaded (and that the main EXE is set to read-only).

Anyone who says, "just have the user look at their AUTOEXEC.BAT to see if SHARE is there" hasn't done much telephone tech support. Further, the standard install setup for Lantastic and Novell Lite both use a STARTNET.BAT file to load SHARE and other network files and "CALL" this batch file from the AUTOEXEC.BAT. Therefore, SHARE might be loaded in a batch file that might be in another directory. (We don't like this practice since it often loads SHARE late in the start up cycle. Also, QEMM Optimize (before 7.03) and DOS MEMMAKER (before 6.2) do not load TSRs into high memory when they are CALL'ed from another batch file.)

What is needed is a simple command line or program function that can determine if SHARE is already installed. This turns out to be more complicated than it first appears.

The intentions of the designers of DOS were that if SHARE was already loaded, you would get a "Share is already loaded" message upon attempting to load SHARE again. This is a relatively crude method of determination, since if you typed SHARE to test if it was loaded and if SHARE was not loaded, it would be loaded after the test (forcing a reboot to remove SHARE).

Things get more complicated when multi-tasking environments are considered. In multi-tasking environments, SHARE must be loaded in the "original" (i.e. the first permanent environment) to be assured direct control of the file I/O. The system becomes unstable and will crash if SHARE is loaded in a second run-time environment. SHARE should never be loaded from any run-time environment.

Most multi-tasking, task-swapping, or shell to DOS environments will hook Interrupt 2Fh to prevent SHARE from being loaded again (Novell DOS 7 fails to do this properly and will allow you to load SHARE in a run-time environment, immediately crashing the system).

In Windows 3.x, if you "go to DOS" and type SHARE, it will always just say "Share is already loaded" (which it may or may not be) since Windows traps the interrupt 2Fh when it starts. If you "Go to DOS" or "Go to Shell" from WordPerfect, Quattro Pro, etc. and attempt to load SHARE, these programs also check for Interrupt 2Fh, and check the registers to issue a slightly more accurate statement than "Share already installed". These return "Unable to load Share" if SHARE is not installed but you are in a run-time environment. This doesn't say anything about whether SHARE is loaded or not, just that you can't load it now. If SHARE is installed, they report "Share is already installed".

The Clarion 2.1 RUN() statement loads a new run-time environment. The Clarion Libraries will prevent you from attempting to load SHARE using a RUN() statement and will issue a "Bad Command Given to RUN()" error. However, the RUNSMALL() command will let you load SHARE in a run-time environment. SHARE will be installed by RUNSMALL() and indicates a successful installation by returning "Share Installed". The system will then immediately crash, usually issuing an "Unable to Allocate File Table" error.

When SHARE.EXE is loaded it uses only one interrupt, Interrupt 2Fh, the so called Multiplex Interrupt. This is the interrupt that provides operating system extensions to DOS. These extensions include the DOS PRINT command, CD-ROM extensions (MSCDEX.EXE), Extended Memory (XMS as implemented by HIMEM), DOS Protected Mode Interface (DPMI), and Windows 3.x.

Keeping in mind which interrupt is being used by SHARE can be helpful in diagnosing problems. For example, programs that use the DOS PRINT command in a Lantastic environment can get a Sharing Violation error during report printing if the Lantastic NET LPT TIMEOUT command is not used. Without the TIMEOUT, the interrupt is tied up and this can interfere with file sharing elsewhere in the application.

You could determine if SHARE is loaded the same way SHARE and most Shell to DOS routines do, by making a call to Interrupt 2Fh (see "INF: How to Detect if SHARE.EXE Is Present" Microsoft Developer Network CD, Volume 6). Specifically you can call Interrupt 2Fh, Function 1000h and check the value of the AH and AL registers. This could be called an "Interrupt Only" check for SHARE. The following results from checking the registers after a call Interrupt 2Fh, Function 1000h:

00H	-	Share Not Installed, OK to install

01H	-	Share Not Installed, not OK to install

FFH	-	Share Already Installed

However, this does not work under Microsoft Windows 3.x. Windows takes control of Interrupt 2Fh and always returns FFh on any Function 1000h call. This was done to prevent SHARE from being installed in a Windows virtual machine which would cause the system to become unstable and might corrupt data on the hard drive. Therefore, another method has to be developed to detect if SHARE is loaded when Windows is running in enhanced mode.

Another method to check for SHARE involves creating a temporary file, then calling Interrupt 21h, Function 5Ch to lock a region of that file (see "INF: Determining that SHARE is loaded under Microsoft Windows", Microsoft Developers CD, Volume 6). Function 5Ch is only available when SHARE is loaded. Therefore, Function 5Ch always fails with invalid function (error 1) if SHARE is not loaded. This could be called a "Lock Temp File" check. This check is performed as follows:

1)	Create a temporary file using MS-DOS Interrupt 21h, Function 5Ah.

2)	Lock a region of the temporary file using MS-DOS Interrupt 21h, Function 5Ch. Set registers as follows: AL = CX = DX = SI = 0 and DI = 1.

3)	If step 2 returns with the carry flag set and AX = 1, SHARE is not loaded. Go to step 5.

4)	If step 3 is not valid, SHARE is loaded. Unlock the region of the temporary file using MS-DOS Interrupt 21h, Function 5Ch and set CX = DX = SI = 0 and AL = DI = 1.

5)	Close the temporary file using MS-DOS Interrupt 21h, Function 3Eh.

6)	Delete the temporary file using MS-DOS Interrupt 21h, Function 41h.

The potential problem with the Lock Temp File check is that you cannot always be certain that a temporary file can be created. For example, the procedure to check SHARE is likely to reside in a program directory, to which many networks do not grant users full rights (to protect the program files). Effective checking of the status of SHARE should be able to use both the Interrupt Only and Lock Temp File approaches.

Any relational database program, that will be operated in a network or multi-tasking environment, should have the capability to detect if SHARE is loaded and determine the attribute of the main EXE file. There are a number of programming approaches to SHARE checking ranging from separate utility programs to incorporating SHARE checking into your program.

In this Article, we will look at four approaches to checking SHARE. Approach 1 is a simple COM program developed using DOS's DEBUG and the ERRORLEVEL checking capabilities of batch files. Approach 2 is a more sophisticated C++ program that can be run at the DOS prompt or incorporated into a Clarion program using the RUN() function. Approach 3 is a small Clarion 2.1 LEM that allows you to incorporate SHARE checking into your Application. Approach 4 uses Clarion code to check SHARE from within a Clarion 3.0 program (see sidebar for Randy Goodhew's approach to integrating Share detection into a Clarion 3.0 program).

Approach 1 - Simple COM Utility Using DEBUG

A simple COM (named CHKSHARE.COM) program used with a batch file can be used to check if SHARE is loaded using the "Interrupt Only" methodology described above (remember this check will not work for Windows).

Create a DOS DEBUG script using your Clarion editor as follows (see "Questions & Answers Windows" by Fran Finnegan, Microsoft Developer Network CD Volume 6):

N CHKSHARE.COM

A 100

MOV	AX,1000

INT	2F

MOV	AH,4C

INT 21

<Leave blank line here!>

R CX

9

W

Q

Name the file CHKSHARE.DBG and save it.

Type: DEBUG < CHKSHARE.DBG. This will create a program named CHKSHARE.COM. You can include CHKSHARE and an attribute check in a batch file. Create the following batch file:

@ECHO OFF

ECHO.

CHKSHARE.COM

IF ERRORLEVEL=0 ECHO SHARE is not installed

IF ERRORLEVEL=255 ECHO SHARE is already installed

ECHO.

ATTRIB APPNAME.EXE

ECHO.

PAUSE

This batch file can be run from a menu within your application using a RUN() Function. The main deficiency in the CHKSHARE.COM program is that it doesn't work in Windows. In Windows, it will always show SHARE is loaded whether it is or not.

Approach 2 - Advanced CHKSHARE.EXE Utility

Therefore, another more sophisticated program has been developed using C-C++ named CHKSHARE.EXE (see sidebar for source code - CHKSHARE.EXE and other programs mentioned in this Article will be on the CTJ utilities disk). This program includes Clear Screen and PAUSE statements to facilitate using a Clarion RUN() function. This program also includes command line options for checking SHARE using the Interrupt Only, Lock Temp File , or both approaches, plus optional main EXE attribute checking.

The command line switches for CHKSHARE.EXE are as follows:

/B-Both modes - Use both Interrupt and File Lock modes (default)

/I-Interrupt Only mode - Uses INT 2Fh. DOS only, not reliable in Windows.

/L- Locked File mode - Test locks temp file. Reliable in DOS and Windows.

/F=APPNAME.EXE - Check for read-only attribute of the specified file name.

Therefore you could use the following as a menu item in a utility menu:

RUN('CHKSHARE.EXE /L /F=APPNAME.EXE')

The question may arise why to include an attribute check when this can be easily done with the DOS ATTRIB command. In the world of telephone tech support, particularly on advanced Networks such as Novell, Banyan, Windows NT, etc., simple DOS commands are often not available to most users.

In addition to a separate program and command line approach, you may want to include SHARE checking in your program. That way you can open informative screens to provide additional instructions based on the results of the check.

(Place CHKSHARE.CPP Source Code Here)

Approach 3 - Clarion 2.1 LEMs

There are three Clarion 2.1 LEMS provided here to include SHARE checking into your Clarion 2.1 Applications: 1) CHKSHARE checks using the Interrupt Only mode, 2) WINSHARE checks using Lock File mode, and 3) CHKWIN checks to see if Windows is running to help you decide which approach to use (see sidebar by Randy Goodhew for another means of checking if Windows is running).

The following is a simple example of how to integrate these LEMS into a Clarion 2.1 application. First make sure the files CHKSHARE.BIN, WINSHARE.BIN, and CHKWIN.BIN are in your Clarion directory (or the directory where the applications source code is kept).

If you use Clarion 2.1 Designer, add an "OTHER" procedure named CHKSHARE. Make sure you set the procedure name to CHKSHARE also, and set "Returns Value" to "YES" and "Type" to "Long" on the Other Procedure Screen. Then go to Editor and create CHKSHARE.CLA as follows:

MEMBER('APPNAME')

CHKSHARE	PROCEDURE ! Clarion Designer Other Procedure to check SHARE

READ_ONLY	BYTE	! Declares Variable

CODE

READ_ONLY = CHKATTR('APPNAME.EXE')

IF ERRORCODE() = 2 TYPE (APPNAME.EXE Not Found' & @LF)

IF READ_ONLY = 0

TYPE('APPNAME.EXE is not read-only' & @LF )

ELSE

TYPE('APPNAME.EXE is read-only' & @LF)

END

IF CHKSHARE()	!Check SHARE using Interrupt Only mode

TYPE('SHARE is already loaded - Check not reliable in Windows'& @LF)

ELSE

TYPE('SHARE is not loaded - Check not reliable in Windows' & @LF)

END

IF WINSHARE()	! Check SHARE using Lock File mode

TYPE('SHARE or VSHARE is loaded - Check reliable in DOS and Windows' & @LF )

ELSE

TYPE('SHARE or VSHARE is not loaded - Check reliable in DOS and Windows' & @LF )

END

IF CHKWIN()	! Check if Windows is running

TYPE('Windows is currently running' & @LF )

ELSE

TYPE('Windows is not running' & @LF )

END

If you are hand coding, make sure you remember to add the following to your MAP.

MAP

MODULE('CHKATTR'),BINARY

FUNC(CHKATTR),LONG

END

MODULE('CHKSHARE'),BINARY

FUNC(CHKSHARE),LONG

END

MODULE('WINSHARE'),BINARY

FUNC(WINSHARE),LONG

END

MODULE('CHKWIN'),BINARY

FUNC(CHKWIN),LONG

END

END

The following is the source code for the preceding 4 LEMs for any readers that are assembler programmers:

CHKATTR.ASM

(Place CHKATTR.ASM Source Code Here)

CHKSHARE.ASM

(Place CHKSHARE.ASM Source Code Here)

WINSHARE.ASM

(Place WINSHARE.ASM Source Code Here)

CHKWIN.ASM

(Place CHKWIN.ASM Source Code Here)

Approach 4 - Clarion 3.0 Code

(Randy's Text and Code here)

VSHARE.386, The New Share for Windows

Microsoft has finally improved SHARE to address some of the file and memory limitations of SHARE. However, these improvements are only available in Windows (including DOS programs running in a DOS window). The new SHARE is called VSHARE.386 and is one of the new "Windows TSRs" known as Virtual Device Drivers (VxD), which you'll be hearing a lot about in Windows 32 (Chicago & Windows NT). Although Windows NT provides true file sharing in the operating system kernel, it is believed that Windows 4.0 will handle file sharing the same as Windows for WorkGroups 3.11.

VSHARE's main advantage is that, unlike SHARE which can only access one segment (64K) of CONVENTIONAL memory, VSHARE can access large amounts of EXTENDED memory. This dramatically increases the number of Files that can be shared and the number of simultaneous users of a database application (if set up properly and the memory is available). If you are only going to run your application in Windows 3.1, you can save up to 64K of conventional memory for your DOS applications by not loading SHARE and letting VSHARE control file sharing. Of course, VSHARE provides no services unless Windows 3.1 is running in enhanced mode.

As a TSR, SHARE requires you to load "all the Locks you're ever going to need" when you load SHARE. VSHARE dynamically allocates and de-allocates Files and Locks as needed. Therefore, VSHARE does not use more memory than is required, does not require messy memory management to load into upper memory, and does not require Files and Locks settings. Keep in mind, that on computers with very little installed extended memory, the Files and Locks requirements of your network can exceed the available memory, even if the memory is dynamically allocated.

VSHARE also relaxes SHARE's prohibition against opening files in "compatibility mode" when other files are opened in sharing mode. Depending on the design of the overlay manager linked into a DOS overlaid program, this usually means that the main EXE does not have to be set to a read-only attribute when VSHARE is loaded (we have tested this for Clarion 2.1 programs linked using Warplink and LPMLink).

VSHARE is a SHARE replacement that is loaded in the SYSTEM.INI. If SHARE has been loaded in the AUTOEXEC.BAT, all SHARE functions are taken over by VSHARE (which could include providing higher File and Lock settings than those loaded with SHARE). However, SHARE does not have to be loaded for VSHARE to work (except in Novell DOS 7 and this is considered a bug rather than intentional, see PC Week, April 12, 1992, page 42).

There are actually two versions of VSHARE (see InfoWorld, April 18, 1994, page 30), both named VSHARE.386. There is the version that comes with Windows for WorkGroups 3.11, which provides VSHARE capabilities only when Windows for WorkGroups is active, and the so called version 3.11.0.401 which comes with Word for Windows 6.0. You can't simply copy the version that comes with Windows for WorkGroups and use it in Windows 3.1. If you don't have Word for Windows 6.0 or Windows for Workgroups 3.11, and you want to use VSHARE in Windows 3.1 in enhanced mode, you can download the version for Windows 3.1 only by calling the Microsoft Download Service BBS at (206)936-6735. VSHARE is contained in a self-extracting EXE file named WW1000.EXE.

All versions of VSHARE are loaded in the 386 enhanced [386Enh] section of the SYSTEM.INI using the following:

DEVICE=VSHARE.386

There are no "command line switches" for VSHARE. VSHARE is loaded automatically during the installation of Microsoft Word for Windows 6.0 (and Windows for Workgroups 3.11). This is why many people now claim they don't need SHARE loaded to run their database programs in Windows. They don't realize that VSHARE has taken over the duties of SHARE.

The checks for SHARE discussed earlier that work in Windows (i.e. the Locked File mode of CHKSHARE.EXE) will detect VSHARE just as if it were SHARE, whether or not SHARE was actually loaded before Windows was started.

Conclusions

It's amazing that the DOS reference manuals, DOS programmer's references, most peer-to-peer network manuals, and the manuals that come with multi-tasking environments rarely have more than a paragraph or two on SHARE or VSHARE. We hope it is apparent from this article that there is more to SHAREing database files in DOS than these references would lead you to believe. As we like to say on the Clarion Forum on CompuServ; "HTH" (Hope This Helps).

About the Authors

Robert Butler and Kevin Stilwell are the lead Programmers for DATA.TXT Corporation in Coral Gables, Florida. DATA.TXT developed and markets nationwide a shrink-wrapped Clarion 2.1/C++ Law Office Calendar, Docket, and Case Management program named Time Matters (R). Robert Butler is the founder of the Miami Clarion User's Group and the head of the South Florida Database Developers C-C++ Special Interest Group. He is also a frequent speaker at Clarion's annual DEVCON meeting. The Authors can be reached through CompuServ at 76660,1514.