═══ 1. Copyrights and Notices ═══ Various trademarks used in this document are the properties of their respective owners. There are so many in computing these days, I cannot keep track of them all. ═══ 1.1. OS/2 VDM Utility Subroutines ═══ COPYRIGHT AND LICENSING INFORMATION This suite of programs and subroutines is freeware, distributed as is, without any warranty of its usefulness for any purpose. You may use it freely. You may also redistribute it, provided no charge is levied beyond the price of its distribution medium. However, the author retains all intellectual property rights. Copyright (C) David W. Noon, 1995, 1997 OBTAINING TECHNICAL SUPPORT You can obtain technical support via Internet e-mail, Compuserve or FidoNet Netmail. My addresses are as follows. Internet: david_noon@donor2.demon.co.uk dwnoon@ibm.net dnoon@acm.org Compuserve: 72172,431 FidoNet: David Noon 2:440/4 The FidoNet mailbox and the first listed Internet mailbox, which are the same place, I check almost every day. The others are checked less frequently, such as every third day or so. Turn-around time on problems might not be spectacular, especially if I have other issues to handle. This is freeware and you should expect no more than you pay for. ═══ 1.2. ACKNOWLEDGEMENT ═══ This library would not have been possible without the information supplied by George Fulk of IBM Personal Software Products in Austin, TX. George provided me with the details of the various register conventions used to pass parameters and receive results. Had it not been for his assistance I would still be groping around with DEBUG.COM and reading hex. ═══ 2. The Definitive Source for the Usage of the OS/2 API ═══ DISCLAIMER (Cop Out) This file is not it! Complete documentation of the API is beyond the scope of this file. Read on to find out where you should really look. ═══ 2.1. The Base API Documentation ═══ All the API calls implemented in this library are part of the Base API of OS/2. Some of the functions are 16-bit and others are 32-bit, even though all are to be called by 16-bit code running in Virtual 8086 mode inside a Virtual DOS Machine (this support is not available in a Virtual Machine Boot, or VMB, session). As a result, you will need the OS/2 Developer's Toolkit 1.3 and the OS/2 Developer's Toolkit 2.1 (or later). Both of these are supplied on the OS/2 Developer Connection CD subscription, and are reputedly downloadble from http://www.developer.ibm.com/devcon/. The API calls that can be accessed via this library are documented in the respective Control Program Reference books. The soft-copy versions have the following definitions in my CONFIG.SYS file: SET PROGREF13=PRCP.INF+PRWINFN.INF+PRGPIFN.INF+PRDATA.INF+PRINTRO.INF SET PROGREF21=CPGREF1.INF+CPGREF2.INF+CPGREF3.INF I strongly suggest you obtain both of these reference manuals, at least in soft-copy form, before undertaking API-programming. Even the CD subscription is not that expensive. My intention here is to provide you with the syntax to call each subroutine I have written and to tell you in which IBM publication to look for the semantics involved in calling it. Thus, you should not expect too much detail from this file. One thing to be aware of is that the return code supplied by the DOS interrupt is not always the same as a direct call to the API will yield under identical circumstances. Quite often, the result in a VDM is simply: zero means it worked and one means something went wrong. This seems particularly to be the case with the 32-bit API calls. The older API's usually supply the same return codes as in the OS/2 1.x documentation. ═══ 3. Supported Languages and Compilers ═══ The OS/2 API is language-neutral. Thus, any language that can produce object code can use the API. However, I don't have all that many DOS compilers, so I can only offer here advice on the ones I have used. Your mileage might vary with other compilers. If you are using assembler, you can plagiarise the source code of the library and issue the interrupts directly. I have assembled the code with MASM [6.11], TASM and WASM. All produced excellent results. I have kept the syntax compatible with MASM 5.x, since TASM and WASM do not fully support MASM 6.x syntax. ═══ 3.1. C/C++ ═══ The code provided in this suite was prepared using Watcom C/C++ 10.6 and WASM, the Watcom assembler. When used with this compiler the object code will be generated in-line, giving very efficient results, since there is then no need to call the external library. This is the compiler that has been most thoroughly used during testing. I also tested the code with Borland C/C++ with Application Frameworks 3.1, or BCAF 3.1, and its assembler, TASM. You will need to define a macro called __DOS__ for successful compilation; I do this as part of the project definition. This compiler has also produced satisfactory results, but has fallen into disuse on my system. ═══ 3.2. Pascal ═══ I have done a very small amount of testing with IBM Pascal/2, a thinly disguised copy of Microsoft QuickPascal. It seems to work. Users of other Pascal compilers will notice some very idiosyncratic syntax for pointers in this dialect of Pascal. Sorry, but I didn't write that compiler; blame Microsoft. I would be interested in hearing from people who use these routines with a more mainstream Pascal compiler, such as Borland/Turbo or TopSpeed, as I would like to include a more widely useful set of Pascal declarations than the ones I am using here. It would be a nice gesture if somebody using a better Pascal compiler could supply me with same. ═══ 3.3. FORTRAN 77 ═══ Coming soon! I have not had time to give Microsoft FORTRAN 5.1 a run with this yet. I will also give Watcom FORTRAN 77 a run when I get a copy. ═══ 3.4. DOS Extenders ═══ The OS/2 VDM support has a DPMI extender built in. By and large it is a very good one. However, it does not map all the real (actually V86) mode DOS interrupts into its protected mode interrupt vector. Most notably, it does not have these interrupt functions avilable. Thus, you cannot use these functions unless your DPMI code switches the machine back to V86 mode. ═══ 4. Naming Conventions ═══ Where the subroutine I have written front-ends a standard OS/2 API, I have given it a name that is simply the API name with the Dos prefix replaced by Dwn. In the case of those API's that only have meaning from within a VDM, and consequently have no name in the full OS/2 context, I have assigned a name that I feel is consonant with the "orthognoal" naming convention of OS/2. ═══ 5. The Subroutines and Functions ═══ All the sample syntax is in C. It should not be too difficult to interpret this code in Pascal (or any other ALGOL 60 derived language) or FORTRAN. On the other hand, COBOL could be a bit of a challenge. ═══ 5.1. DwnExitVDM ═══ This API call shuts down the VDM session. It has no use outside of a VDM. Syntax Parameters Remarks ═══ DwnExitVDM syntax ═══ int VDM_LINKAGE DwnExitVDM(void); rc = DwnExitVDM(); /* Shut down DOS session */ ═══ DwnExitVDM parameters ═══ This API takes no parameters. It can return an integer result, but only if the call fails. This seldom happens. ═══ DwnExitVDM remarks ═══ This shuts down the address space for the VDM session. It is fatal for all programs that might be running in that session. Ensure all resources have been cleaned up, where necessary, before calling this API. This is the only one of these API's that seems to work in a VMB session. ═══ 5.2. DwnReleaseTimeSlice ═══ This API call releases the current timeslice from the VDM session. Syntax Parameters Remarks ═══ DwnReleaseTimeSlice syntax ═══ void VDM_LINKAGE DwnReleaseTimeSlice(void); DwnReleaseTimeSlice(); /* Let someone else use the CPU */ ═══ DwnReleaseTimeSlice parameters ═══ This API takes no parameters and returns no result. ═══ DwnReleaseTimeSlice remarks ═══ This makes the overall system more responsive when a DOS program has to poll a resource. Any poll that fails to obtain the resource should release its timeslice so that OS/2 can allow other programs to run. Its nearest relative in the native API is DosSleep(). Indeed, it is the code for the DosSleep() API that provides support for this function. With Warp 4, there have been some problems with VDM sessions not releasing timeslices, even though they were coded to do this. After some informal experimentation with my system at Fixpack #1 level, I have found that INT 28H appears to work, but the mutliplex interrupt, INT 2FH function 1680H, is still broken. Thus, this release uses the DOS idle interrupt rather than the more timeslice-oriented multiplex interrupt. ═══ 5.3. DwnSetSessionTitle ═══ This API call sets the title bar text on a windowed VDM session. It has no use outside of a VDM, nor in a full-screen session. Syntax Parameters Remarks Related API ═══ DwnSetSessionTitle syntax ═══ void VDM_LINKAGE DwnSetSessionTitle(PCSZ Session_title); DwnSetSessionTitle("Running a DOS program"); ═══ DwnSetSessionTitle parameters ═══ This API takes a single ASCIIZ character string as input and returns no result. const char [] (PCSZ) Any zero-delimited ASCII string constant or variable. Used for input only. ═══ DwnSetSessionTitle remarks ═══ The title bar is largely of of interest for looking at the WorkPlace Shell task list. The text you set here will appear in that list, corresponding to the current VDM session. It seems that the length limit is 19 bytes, including the trailing null. Superfluous bytes are ignored. ═══ DwnSetSessionTitle related API calls ═══ The only API call related to this is: DwnQuerySessionTitle ═══ 5.4. DwnQuerySessionTitle ═══ This API call obtains a copy of the title bar text on a windowed VDM session. It has no use outside of a VDM, nor in a full-screen session. Syntax Parameters Remarks Related API ═══ DwnQuerySessionTitle syntax ═══ void VDM_LINKAGE DwnQuerySessionTitle(PSZ Session_title); char Session_title[20]; DwnQuerySessionTitle(Session_title); puts("The current VDM session has title "); puts(Session_title); ═══ DwnQuerySessionTitle parameters ═══ This API takes a single ASCIIZ character string variable as its output area and returns no result. char [] (PSZ) An area to receive the title string. The minimum safe size of the receiving field is 19 bytes. ═══ DwnQuerySessionTitle remarks ═══ This API will retrieve whatever title the VDM session has currently. Do NOT depend on it being what your program set earlier. Any program in the address space can issue the interrupt, and window messages can be sent from outside the address space to change the title. ═══ DwnQuerySessionTitle related API calls ═══ The only API call related to this is: DwnSetSessionTitle ═══ 5.5. DwnQFileInfo ═══ This API call obtains the attributes of a file for which your program currently has an open file handle. Syntax Parameters Remarks Related API's ═══ DwnQFileInfo syntax ═══ USHORT VDM_LINKAGE DwnQFileInfo(HFILE FileHandle, USHORT FileInfoLevel, PVOID FileInfoBuf, USHORT FileInfoBufSize); USHORT rc; HFILE Input_file; FILESTATUS Attribute_buffer; rc = DwnQFileInfo(Input_file, FIL_STANDARD, &Attribute_buffer, sizeof(Attribute_buffer)); ═══ DwnQFileInfo parameters ═══ HFILE The file handle of an open file. It can be open for read-only or for write too. USHORT An integer that defines the level of detail required. See Control Program Reference for details. PVOID The address of a buffer area to receive the file's attributes. There are pre-defined structures for various levels of detail. See Control Program Reference for details. USHORT An integer that tells the API how large the buffer area is. ═══ DwnQFileInfo remarks ═══ This API can retrieve the base attributes of a file, or its extended attribute structure. It appears to use the 16-bit interface of OS/2 1.x. Thus, you should read the older Control Program Reference for the detailed documentation of this function. ═══ DwnQFileInfo related API calls ═══ DwnQPathInfo DwnSetFileInfo DwnSetPathInfo ═══ 5.6. DwnSetFileInfo ═══ This API call modifies the attributes of a file for which your program currently has an open file handle. Syntax Parameters Remarks Related API's ═══ DwnSetFileInfo syntax ═══ USHORT VDM_LINKAGE DwnSetFileInfo(HFILE FileHandle, USHORT FileInfoLevel, PVOID FileInfoBuf, USHORT FileInfoBufSize); USHORT rc; HFILE Input_file; FILESTATUS Attribute_buffer; rc = DwnSetFileInfo(Input_file, FIL_STANDARD, &Attribute_buffer, sizeof(Attribute_buffer)); ═══ DwnSetFileInfo parameters ═══ HFILE The file handle of an open file. It must be open for write access. USHORT An integer that defines the level of detail supplied. See Control Program Reference for details. PVOID The address of a buffer area to supply the file's attributes. There are pre-defined structures for various levels of detail. See Control Program Reference for details. USHORT An integer that tells the API how large the buffer area is. ═══ DwnSetFileInfo remarks ═══ This API can modify the base attributes of a file, or its extended attribute structure. It appears to use the 16-bit interface of OS/2 1.x. Thus, you should read the older Control Program Reference for the detailed documentation of this function. ═══ DwnSetFileInfo related API calls ═══ DwnSetPathInfo DwnQFileInfo DwnQPathInfo ═══ 5.7. DwnQPathInfo ═══ This API call obtains the attributes of a file or directory named in its parameter list. Syntax Parameters Remarks Related API's ═══ DwnQPathInfo syntax ═══ USHORT VDM_LINKAGE DwnQPathInfo(PCSZ PathName, USHORT PathInfoLevel, PVOID PathInfoBuf, USHORT PathInfoBufSize); USHORT rc; const char Directory_name[] = "D:\\DATA\\SUBDIR"; FILESTATUS Attribute_buffer; rc = DwnQPathInfo(Directory_name, FIL_STANDARD, &Attribute_buffer, sizeof(Attribute_buffer)); ═══ DwnQPathInfo parameters ═══ PCSZ An ASCIIZ string constant or variable that supplies the path/filename of the file or directory whose attributes are to be retrieved. USHORT An integer that defines the level of detail required. See Control Program Reference for details. PVOID The address of a buffer area to receive the file's attributes. There are pre-defined structures for various levels of detail. See Control Program Reference for details. USHORT An integer that tells the API how large the buffer area is. ═══ DwnQPathInfo remarks ═══ This API can retrieve the base attributes of a file or directory, or its extended attribute structure. It appears to use the 16-bit interface of OS/2 1.x. Thus, you should read the older Control Program Reference for the detailed documentation of this function. ═══ DwnQPathInfo related API calls ═══ DwnQFileInfo DwnSetFileInfo DwnSetPathInfo ═══ 5.8. DwnSetPathInfo ═══ This API call modifies the attributes of a file or directory named in its parameter list. Syntax Parameters Remarks Related API's ═══ DwnSetPathInfo syntax ═══ USHORT VDM_LINKAGE DwnSetPathInfo(PCSZ PathName, USHORT PathInfoLevel, PVOID PathInfoBuf, USHORT PathInfoBufSize); USHORT rc; const char Directory_name[] = "D:\\DATA\\SUBDIR"; FILESTATUS Attribute_buffer; rc = DwnSetPathInfo(Directory_name, FIL_STANDARD, &Attribute_buffer, sizeof(Attribute_buffer)); ═══ DwnSetPathInfo parameters ═══ PCSZ An ASCIIZ string constant or variable that supplies the path/filename of the file or directory whose attributes are to be modified. USHORT An integer that defines the level of detail supplied. See Control Program Reference for details. PVOID The address of a buffer area to supply the file's attributes. There are pre-defined structures for various levels of detail. See Control Program Reference for details. USHORT An integer that tells the API how large the buffer area is. ═══ DwnSetPathInfo remarks ═══ This API can modify the base attributes of a file or directory, or its extended attribute structure. It appears to use the 16-bit interface of OS/2 1.x. Thus, you should read the older Control Program Reference for the detailed documentation of this function. ═══ DwnSetPathInfo related API calls ═══ DwnSetFileInfo DwnQPathInfo DwnQFileInfo ═══ 5.9. DwnCreateEventSem ═══ This API call creates an event semaphore and, optionally, posts it. Syntax Parameters Remarks Related API's ═══ DwnCreateEventSem syntax ═══ USHORT VDM_LINKAGE DwnCreateEventSem(PCSZ SemName, PHEV SemHandle, USHORT Attr, BOOL State); USHORT rc; const char Sem_name[] = "\\SEM32\\It_happened"; HEV It_happened; rc = DwnCreateEventSem(Sem_name, &It_happened, DC_SEM_SHARED, FALSE); ═══ DwnCreateEventSem parameters ═══ PCSZ An ASCIIZ string constant or variable that supplies the name of the semaphore tp be created. All semaphores created using the 32-bit API must start with SEM32 as their apparent directory. If this parameter is NULL, a private semaphore is created, that can be used only within the address space that created it. PHEV The address of an event semaphore handle area. This will be filled by the API with the handle of the semaphore created. USHORT The attributes of the semaphore. The only non-default attribute a named sempahore can have is DC_SEM_SHARED. Unnamed semaphores cannot have any attribute and this parameter must then be zero. BOOL The state of the event semaphore when created. Zero (FALSE) means cleared and non-zero (TRUE) means posted. ═══ DwnCreateEventSem remarks ═══ This API is a 32-bit function, so the newer (2.x and later) Control Program Reference should be read for details of this function. ═══ DwnCreateEventSem related API calls ═══ DwnOpenEventSem DwnWaitEventSem DwnPostEventSem DwnCloseEventSem DwnQueryEventSem DwnResetEventSem ═══ 5.10. DwnOpenEventSem ═══ This API call opens an already created event semaphore. Syntax Parameters Remarks Related API's ═══ DwnOpenEventSem syntax ═══ USHORT VDM_LINKAGE DwnOpenEventSem(PCSZ SemName, PHEV SemHandle); USHORT rc; const char Sem_name[] = "\\SEM32\\It_happened"; HEV It_happened; rc = DwnOpenEventSem(Sem_name, &It_happened); ═══ DwnOpenEventSem parameters ═══ PCSZ An ASCIIZ string constant or variable that supplies the name of the semaphore tp be opened. All semaphores created using the 32-bit API must start with SEM32 as their apparent directory. PHEV The address of an event semaphore handle area. This will be filled by the API with the handle of the semaphore opened. ═══ DwnOpenEventSem remarks ═══ This API is a 32-bit function, so the newer (2.x and later) Control Program Reference should be read for details of this function. ═══ DwnOpenEventSem related API calls ═══ DwnCreateEventSem DwnWaitEventSem DwnPostEventSem DwnCloseEventSem DwnQueryEventSem DwnResetEventSem ═══ 5.11. DwnWaitEventSem ═══ This API call suspends execution of the current thread until the event semaphore has been posted. Syntax Parameters Remarks Related API's ═══ DwnWaitEventSem syntax ═══ USHORT VDM_LINKAGE DwnWaitEventSem(HEV SemHandle, long Timeout); USHORT rc; HEV It_happened; rc = DwnWaitEventSem(It_happened, SEM_INDEFINITE_WAIT); ═══ DwnWaitEventSem parameters ═══ HEV The event semaphore handle. long The maximum time, in millseconds, the thread should be suspended. ═══ DwnWaitEventSem remarks ═══ This API call suspends execution of the current thread until the event semaphore has been posted or the time-out value has elapsed. If it has already been posted, the post count is decremented and control returns immediately. This API is a 32-bit function, so the newer (2.x and later) Control Program Reference should be read for details of this function. ═══ DwnWaitEventSem related API calls ═══ DwnCreateEventSem DwnOpenEventSem DwnPostEventSem DwnCloseEventSem DwnQueryEventSem DwnResetEventSem ═══ 5.12. DwnPostEventSem ═══ This API call allows execution of the any thread waiting on the event semaphore to be resumed. Syntax Parameters Remarks Related API's ═══ DwnPostEventSem syntax ═══ USHORT VDM_LINKAGE DwnPostEventSem(HEV SemHandle); USHORT rc; HEV It_happened; rc = DwnPostEventSem(It_happened); ═══ DwnPostEventSem parameters ═══ HEV The event semaphore handle. ═══ DwnPostEventSem remarks ═══ This API call allows execution of the any thread waiting on the event semaphore to be resumed. If no thread is waiting, the semaphore's post count is incremented. This API is a 32-bit function, so the newer (2.x and later) Control Program Reference should be read for details of this function. ═══ DwnPostEventSem related API calls ═══ DwnCreateEventSem DwnOpenEventSem DwnWaitEventSem DwnCloseEventSem DwnQueryEventSem DwnResetEventSem ═══ 5.13. DwnCloseEventSem ═══ This API call closes the current thread's handle on the semaphore. Syntax Parameters Remarks Related API's ═══ DwnCloseEventSem syntax ═══ USHORT VDM_LINKAGE DwnCloseEventSem(HEV SemHandle); USHORT rc; HEV It_happened; rc = DwnCloseEventSem(It_happened); ═══ DwnCloseEventSem parameters ═══ HEV The event semaphore handle. ═══ DwnCloseEventSem remarks ═══ This API call closes the current thread's handle on the semaphore. If it is the last handle on that semaphore, the semaphore is deleted. This API is a 32-bit function, so the newer (2.x and later) Control Program Reference should be read for details of this function. ═══ DwnCloseEventSem related API calls ═══ DwnCreateEventSem DwnOpenEventSem DwnWaitEventSem DwnPostEventSem DwnQueryEventSem DwnResetEventSem ═══ 5.14. DwnQueryEventSem ═══ This API retrieves the count of posts that have not been waited on yet for the event semaphore. Syntax Parameters Remarks Related API's ═══ DwnQueryEventSem syntax ═══ USHORT VDM_LINKAGE DwnQueryEventSem(HEV SemHandle, PULONG PostCount); USHORT rc; HEV It_happened; ULONG Times_posted; rc = DwnQueryEventSem(It_happened, &Times_posted); ═══ DwnQueryEventSem parameters ═══ HEV The event semaphore handle. PULONG The address of an unsigned long integer that will receive the count. ═══ DwnQueryEventSem remarks ═══ This API is a 32-bit function, so the newer (2.x and later) Control Program Reference should be read for details of this function. ═══ DwnQueryEventSem related API calls ═══ DwnCreateEventSem DwnOpenEventSem DwnWaitEventSem DwnPostEventSem DwnCloseEventSem DwnResetEventSem ═══ 5.15. DwnResetEventSem ═══ This API retrieves the count of posts that have not been waited on yet for the event semaphore and sets that count to zero. Syntax Parameters Remarks Related API's ═══ DwnResetEventSem syntax ═══ USHORT VDM_LINKAGE DwnResetEventSem(HEV SemHandle, PULONG PostCount); USHORT rc; HEV It_happened; ULONG Times_posted; Times_posted = 0UL; rc = DwnResetEventSem(It_happened, &Times_posted); ═══ DwnResetEventSem parameters ═══ HEV The event semaphore handle. PULONG The address of an unsigned long integer that will receive the count. ═══ DwnResetEventSem remarks ═══ This API retrieves the count of posts that have not been waited on yet for the event semaphore. It also sets that count to zero within the semaphore, thus causing all threads that call DosWaitEventSem() to be blocked until another call to DosPostEventSem() on that semaphore. This API is a 32-bit function, so the newer (2.x and later) Control Program Reference should be read for details of this function. ═══ DwnResetEventSem related API calls ═══ DwnCreateEventSem DwnOpenEventSem DwnWaitEventSem DwnPostEventSem DwnCloseEventSem DwnQueryEventSem ═══ 5.16. DwnCreateMutexSem ═══ This API call creates a mutual exclusion (mutex) semaphore and, optionally, acquires control of it. Syntax Parameters Remarks Related API's ═══ DwnCreateMutexSem syntax ═══ USHORT VDM_LINKAGE DwnCreateMutexSem(PCSZ SemName, PHMTX SemHandle, USHORT Attr, BOOL State); USHORT rc; const char Sem_name[] = "\\SEM32\\My_resource"; HMTX My_resource; rc = DwnCreateMutexSem(Sem_name, &My_resource, DC_SEM_SHARED, TRUE); ═══ DwnCreateMutexSem parameters ═══ PCSZ An ASCIIZ string constant or variable that supplies the name of the semaphore tp be created. All semaphores created using the 32-bit API must start with SEM32 as their apparent directory. If this parameter is NULL, a private semaphore is created, that can be used only within the address space that created it. PHMTX The address of a mutex semaphore handle area. This will be filled by the API with the handle of the semaphore created. USHORT The attributes of the semaphore. The only non-default attribute a named sempahore can have is DC_SEM_SHARED. Unnamed semaphores cannot have any attribute and this parameter must then be zero. BOOL The state of the mutex semaphore when created. Zero (FALSE) means available for other trheads to request and non-zero (TRUE) means controlled by the creating thread. ═══ DwnCreateMutexSem remarks ═══ This API is a 32-bit function, so the newer (2.x and later) Control Program Reference should be read for details of this function. ═══ DwnCreateMutexSem related API calls ═══ DwnOpenMutexSem DwnRequestMutexSem DwnReleaseMutexSem DwnCloseMutexSem DwnQueryMutexSem ═══ 5.17. DwnOpenMutexSem ═══ This API call opens an already created mutex semaphore. Syntax Parameters Remarks Related API's ═══ DwnOpenMutexSem syntax ═══ USHORT VDM_LINKAGE DwnOpenMutexSem(PCSZ SemName, PHMTX SemHandle); USHORT rc; const char Sem_name[] = "\\SEM32\\My_resource"; HMTX My_resource; rc = DwnOpenMutexSem(Sem_name, &My_resource); ═══ DwnOpenMutexSem parameters ═══ PCSZ An ASCIIZ string constant or variable that supplies the name of the semaphore tp be opened. All semaphores created using the 32-bit API must start with SEM32 as their apparent directory. PHMTX The address of a mutex semaphore handle area. This will be filled by the API with the handle of the semaphore opened. ═══ DwnOpenMutexSem remarks ═══ This API is a 32-bit function, so the newer (2.x and later) Control Program Reference should be read for details of this function. ═══ DwnOpenMutexSem related API calls ═══ DwnCreateMutexSem DwnRequestMutexSem DwnReleaseMutexSem DwnCloseMutexSem DwnQueryMutexSem ═══ 5.18. DwnRequestMutexSem ═══ This API call suspends execution of the current thread until the mutex semaphore has been acquired. Syntax Parameters Remarks Related API's ═══ DwnRequestMutexSem syntax ═══ USHORT VDM_LINKAGE DwnRequestMutexSem(HMTX SemHandle, long Timeout); USHORT rc; HMTX My_resource; rc = DwnRequestMutexSem(My_resource, SEM_INDEFINITE_WAIT); ═══ DwnRequestMutexSem parameters ═══ HMTX The mutex semaphore handle. long The maximum time, in millseconds, the thread should be suspended. ═══ DwnRequestMutexSem remarks ═══ This API call suspends execution of the current thread until the mutex semaphore has been acquired or the time-out value has elapsed. If it is already avaliable control returns immediately. This API is a 32-bit function, so the newer (2.x and later) Control Program Reference should be read for details of this function. ═══ DwnRequestMutexSem related API calls ═══ DwnCreateMutexSem DwnOpenMutexSem DwnReleaseMutexSem DwnCloseMutexSem DwnQueryMutexSem ═══ 5.19. DwnReleaseMutexSem ═══ This API call allows execution of the any thread waiting on the mutex semaphore to be resumed. Syntax Parameters Remarks Related API's ═══ DwnReleaseMutexSem syntax ═══ USHORT VDM_LINKAGE DwnReleaseMutexSem(HMTX SemHandle); USHORT rc; HMTX My_resource; rc = DwnReleaseMutexSem(My_resource); ═══ DwnReleaseMutexSem parameters ═══ HMTX The mutex semaphore handle. ═══ DwnReleaseMutexSem remarks ═══ This API call allows execution of the any thread waiting on the mutex semaphore to be resumed. It can only be issued by the thread that currently owns the mutex semaphore. This API is a 32-bit function, so the newer (2.x and later) Control Program Reference should be read for details of this function. ═══ DwnReleaseMutexSem related API calls ═══ DwnCreateMutexSem DwnOpenMutexSem DwnRequestMutexSem DwnCloseMutexSem DwnQueryMutexSem ═══ 5.20. DwnCloseMutexSem ═══ This API call closes the current thread's handle on the semaphore. Syntax Parameters Remarks Related API's ═══ DwnCloseMutexSem syntax ═══ USHORT VDM_LINKAGE DwnCloseMutexSem(HMTX SemHandle); USHORT rc; HMTX My_resource; rc = DwnCloseMutexSem(My_resource); ═══ DwnCloseMutexSem parameters ═══ HMTX The mutex semaphore handle. ═══ DwnCloseMutexSem remarks ═══ This API call closes the current thread's handle on the semaphore. If it is the last handle on that semaphore, the semaphore is deleted. This API is a 32-bit function, so the newer (2.x and later) Control Program Reference should be read for details of this function. ═══ DwnCloseMutexSem related API calls ═══ DwnCreateMutexSem DwnOpenMutexSem DwnRequestMutexSem DwnReleaseMutexSem DwnQueryMutexSem ═══ 5.21. DwnQueryMutexSem ═══ This API retrieves the count of posts that have not been waited on yet for the mutex semaphore. Syntax Parameters Remarks Related API's ═══ DwnQueryMutexSem syntax ═══ USHORT VDM_LINKAGE DwnQueryMutexSem(HMTX SemHandle, PPID OwnerProcess, PTID OwnerThread, PULONG RequestCount); USHORT rc; HMTX My_resource; PID Owner_process; TID Owner_thread; ULONG Waiting_threads; rc = DwnQueryMutexSem(My_resource, &Owner_process, &Owner_thread, &Waiting_threads); ═══ DwnQueryMutexSem parameters ═══ HMTX The mutex semaphore handle. PPID The address of a PID that will receive the process id. of the owning process. PTID The address of a TID that will receive the thread id. of the owning thread. PULONG The address of an unsigned long integer that will receive the count of waiting threads. ═══ DwnQueryMutexSem remarks ═══ This API does not work in a VDM session. Do not use it. This API is a 32-bit function, so the newer (2.x and later) Control Program Reference should be read for details of this function. ═══ DwnQueryMutexSem related API calls ═══ DwnCreateMutexSem DwnOpenMutexSem DwnRequestMutexSem DwnReleaseMutexSem DwnCloseMutexSem ═══ 5.22. DwnStartSession ═══ This API call starts another address space. Syntax Parameters Remarks ═══ DwnStartSession syntax ═══ USHORT VDM_LINKAGE DwnStartSession(PSTARTDATA StartData); USHORT rc; STARTDATA Session_info; memset(&Session_info,0x00,sizeof(STARTDATA)); Session_info.Length = sizeof(STARTDATA); Session_info.FgBg = SSF_FGBG_BACK; Session_info.PgmTitle = "CMD.EXE"; Session_info.PgmInputs = "/C BLOBBO.CMD INFILE.DAT"; Session_info.SessionType = SSF_TYPE_WINDOWABLEVIO; rc = DwnStartSession(&Session_info); ═══ DwnStartSession parameters ═══ PSTARTDATA The address of a STARTDATA structure describing the session to be started. ═══ DwnStartSession remarks ═══ This API is a 32-bit function, so the newer (2.x and later) Control Program Reference should be read for details of this function. ═══ 6. Data Structures ═══ The following data structures are used in this documentations. Please refer to the formal IBM documentation for others, particularly regarding extended attribute handling. ═══ 6.1. FDATE ═══ typedef struct _FDATE { /* fdate */ unsigned day : 5; /* binary day for directory entry */ unsigned month : 4; /* binary month for directory entry */ unsigned year : 7; /* binary year for directory entry, offset from 1980 */ } FDATE; typedef FDATE FAR *PFDATE; ═══ 6.2. FTIME ═══ typedef struct _FTIME { /* ftime */ unsigned twosecs : 5; /* binary number of two-second increments */ unsigned minutes : 6; /* binary number of minutes */ unsigned hours : 5; /* binary number of hours */ } FTIME; typedef FTIME FAR *PFTIME; ═══ 6.3. FILESTATUS ═══ typedef struct _FILESTATUS { /* fsts */ FDATE fdateCreation; /* date of file creation */ FTIME ftimeCreation; /* time of file creation */ FDATE fdateLastAccess; /* date of last access */ FTIME ftimeLastAccess; /* time of last access */ FDATE fdateLastWrite; /* date of last write */ FTIME ftimeLastWrite; /* time of last write */ ULONG cbFile; /* file size (end of data) */ ULONG cbFileAlloc; /* file allocated size */ USHORT attrFile; /* attributes of the file */ ULONG cbList; /* length of EA structure */ } FILESTATUS; typedef FILESTATUS FAR *PFILESTATUS; Note: This structure must be byte packed. The ULONG at the end will be out of place of it is allowed to assume WORD or DWORD alignment. ═══ 6.4. STARTDATA ═══ /* The following typedef has been plagiarised from the OS/2 Warp Developer's Toolkit 4.0 */ typedef struct _STARTDATA { USHORT Length; /* The length of the data structure, in bytes, including Length itself. */ USHORT Related; /* An indicator which specifies whether the session created is related to the calling session. */ USHORT FgBg; /* An indicator which specifies whether the new session should be started in the foreground or background. */ USHORT TraceOpt; /* An indicator which specifies whether the program started in the new session should be executed under conditions for tracing. */ PCSZ PgmTitle; /* Address of an ASCIIZ string that contains the program title. */ PCSZ PgmName; /* The address of an ASCIIZ string that contains the file specification of the program to be loaded. */ PCSZ PgmInputs; /* Either 0 or the address of an ASCIIZ string that contains the input arguments to be passed to the program. */ PCSZ TermQ; /* Either 0 or the address of an ASCIIZ string that contains the file specification of a system queue. */ PCSZ Environment; /* The address of an environment string to be passed to the program started in the new session. */ USHORT InheritOpt; /* Specifies whether the program started in the new session should inherit the calling program's environment and open file handles. */ USHORT SessionType; /* The type of session that should be created for this program. */ PCSZ IconFile; /* Either 0 or the address of an ASCIIZ string that contains the file specification of an icon definition. */ ULONG PgmHandle; /* Either 0 or the program handle. */ USHORT PgmControl; /* An indicator which specifies the initial state for a windowed application. */ USHORT InitXPos; /* The initial x-coordinate, in pels, for the initial session window. */ USHORT InitYPos; /* The initial y-coordinate, in pels, for the initial session window. */ USHORT InitXSize; /* The initial x extent, in pels, for the initial session window. */ USHORT InitYSize; /* The initial y extent, in pels, for the initial session window. */ USHORT Reserved; /* Reserved; must be zero. */ PVOID ObjectBuffer; /* Buffer in which the name of the object that contributed to the failure of DosExecPgm is returned. */ ULONG ObjectBuffLen; /* The length, in bytes, of the buffer pointed to by ObjectBuffer. */ } STARTDATA; typedef STARTDATA FAR *PSTARTDATA; ═══ 7. Linkage Convention ═══ The linkage convention is handled in C/C++ by a macro called VDM_LINKAGE. In any other language you will need to deal with this, unless the default linkage convention is that of Pascal. This means that both Pascal and FORTRAN programmers should be OK. ═══ 7.1. Using Watcom C/C++ ═══ The Watcom C/C++ compiler permits #pragma aux to generate machine instructions from in-line assembler source. This is the approach I have taken for these API calls using this compiler. As a result, no linkage convention is used: the object code is in-line, and the VDM_LINKAGE macro is null. ═══ 7.2. Using Other Compilers ═══ Note: This section applies to compilers of languages other than C/C++, as well as to C/C++ compilers from other vendors. For compilers other than Watcom C/C++, I have used the Pascal linkage convention, since that is the "lowest common denominator" of subroutine linkage, and it is the one used by the OS/2 native API. Thus, the VDM_LINKAGE macro is resolved as _Pascal.