summaryrefslogtreecommitdiffstats
path: root/private/nw/nw16/dll/locks.c
diff options
context:
space:
mode:
Diffstat (limited to 'private/nw/nw16/dll/locks.c')
-rw-r--r--private/nw/nw16/dll/locks.c677
1 files changed, 677 insertions, 0 deletions
diff --git a/private/nw/nw16/dll/locks.c b/private/nw/nw16/dll/locks.c
new file mode 100644
index 000000000..f3d9ff362
--- /dev/null
+++ b/private/nw/nw16/dll/locks.c
@@ -0,0 +1,677 @@
+
+/*++
+
+Copyright (c) 1993/4 Microsoft Corporation
+
+Module Name:
+
+ Locks.c
+
+Abstract:
+
+ This module implements the routines for the NetWare
+ 16 bit support to perform the synchonization api's
+
+Author:
+
+ Colin Watson [ColinW] 07-Dec-1993
+
+Revision History:
+
+--*/
+
+#include "Procs.h"
+UCHAR LockMode = 0;
+
+BOOLEAN Tickle[MC];
+
+NTSTATUS
+Sem(
+ UCHAR Function,
+ UCHAR Connection
+ );
+
+VOID
+Locks(
+ USHORT Command
+ )
+/*++
+
+Routine Description:
+
+ Implements all the locking operations
+
+Arguments:
+
+ Command - supplies Applications AX.
+
+Return Value:
+
+ Return status.
+
+--*/
+{
+ UCHAR Function = Command & 0x00ff;
+ USHORT Operation = Command & 0xff00;
+ CONN_INDEX Connection;
+ NTSTATUS status = STATUS_SUCCESS;
+ PUCHAR Request;
+ ULONG RequestLength;
+ WORD Timeout;
+
+ if ( Operation != 0xCF00) {
+
+ //
+ // Connection does not need to be initialised for CF00 because
+ // we have to loop through all connections. Its harmful because
+ // a CF00 is created during ProcessExit(). If we call selectconnection
+ // and there is no server available this will make process exit
+ // really slow.
+ //
+
+ Connection = SelectConnection();
+ if (Connection == 0xff) {
+ setAL(0xff);
+ return;
+ }
+
+ if ( ServerHandles[Connection] == NULL ) {
+
+ status = OpenConnection( Connection );
+
+ if (!NT_SUCCESS(status)) {
+ setAL((UCHAR)RtlNtStatusToDosError(status));
+ return;
+ }
+ }
+ }
+
+ switch ( Operation ) {
+
+ case 0xBC00: // Log physical record
+
+ status = NwlibMakeNcp(
+ GET_NT_HANDLE(),
+ NWR_ANY_HANDLE_NCP(0x1A),
+ 17, // RequestSize
+ 0, // ResponseSize
+ "b_wwwww",
+ Function,
+ 6, // Leave space for NetWare handle
+ getCX(),getDX(),
+ getSI(),getDI(),
+ getBP());
+ break;
+
+ case 0xBD00: // Physical Unlock
+ status = NwlibMakeNcp(
+ GET_NT_HANDLE(),
+ NWR_ANY_HANDLE_NCP(0x1C),
+ 15, // RequestSize
+ 0, // ResponseSize
+ "b_wwww",
+ Function,
+ 6, // Leave space for NetWare handle
+ getCX(),getDX(),
+ getSI(),getDI());
+
+ break;
+
+ case 0xBE00: // Clear physical record
+
+ status = NwlibMakeNcp(
+ GET_NT_HANDLE(),
+ NWR_ANY_HANDLE_NCP(0x1E),
+ 15, // RequestSize
+ 0, // ResponseSize
+ "b_wwww",
+ Function,
+ 6, // Leave space for NetWare handle
+ getCX(),getDX(),
+ getSI(),getDI());
+
+ break;
+
+ case 0xC200: // Physical Lock set
+ status = NwlibMakeNcp(
+ ServerHandles[Connection],
+ NWR_ANY_F2_NCP(0x1B),
+ 3, // RequestSize
+ 0, // ResponseSize
+ "bw",
+ Function,
+ getBP());
+ break;
+
+ case 0xC300: // Release Physical Record Set
+ status = NwlibMakeNcp(
+ ServerHandles[Connection],
+ NWR_ANY_F2_NCP(0x1D),
+ 0, // RequestSize
+ 0, // ResponseSize
+ "");
+ break;
+
+ case 0xC400: // Clear Physical Record Set
+ status = NwlibMakeNcp(
+ ServerHandles[Connection],
+ NWR_ANY_F2_NCP(0x1F), // Clear Physical Record Set
+ 0, // RequestSize
+ 0, // ResponseSize
+ "");
+ break;
+
+ case 0xC500: // All Semaphore operations
+ status = Sem(Function, Connection);
+ break;
+
+ case 0xC600: // Set/Get Lock mode
+
+ if (Function != 2) {
+ LockMode = Function;
+ }
+
+ setAL(LockMode);
+ return; // avoid setting AL to status at the end of this routine
+ break;
+
+ case 0xCB00: // Lock File Set
+
+ if (LockMode == 0) {
+ if (getDL()) {
+ Timeout = 0xffff;
+ } else {
+ Timeout = 0;
+ }
+ } else {
+ Timeout = getBP();
+ }
+
+ for (Connection = 0; Connection < MC; Connection++) {
+ if (Tickle[Connection]) {
+ status = NwlibMakeNcp(
+ ServerHandles[Connection],
+ NWR_ANY_F2_NCP(0x04),
+ 2, // RequestSize
+ 0, // ResponseSize
+ "w",
+ Timeout);
+ if (!NT_SUCCESS(status)) {
+ break;
+ }
+ }
+ }
+ break;
+
+ case 0xCD00: // Release File Set
+ case 0xCF00: // Clear File Set
+ for (Connection = 0; Connection < MC; Connection++) {
+ if (Tickle[Connection]) {
+ status = NwlibMakeNcp(
+ ServerHandles[Connection],
+ (Operation == 0xCD00) ? NWR_ANY_F2_NCP(0x06): NWR_ANY_F2_NCP(0x08),
+ 0, // RequestSize
+ 0, // ResponseSize
+ "");
+ if (!NT_SUCCESS(status)) {
+ break;
+ }
+
+ if (Operation == 0xCF00) {
+ Tickle[Connection] = FALSE;
+ }
+ }
+ }
+
+ break;
+
+ case 0xD000: // Log Logical Record
+
+ Request = GetVDMPointer (
+ (ULONG)((getDS() << 16)|getDX()),
+ sizeof(UCHAR),
+ IS_PROTECT_MODE());
+
+ RequestLength = Request[0] + 1;
+
+ Request = GetVDMPointer (
+ (ULONG)((getDS() << 16)|getDX()),
+ RequestLength,
+ IS_PROTECT_MODE());
+
+ status = NwlibMakeNcp(
+ ServerHandles[Connection],
+ NWR_ANY_F2_NCP(0x09),
+ RequestLength + 5, // RequestSize
+ 0, // ResponseSize
+ "bwbr",
+ (LockMode) ? Function : 0,
+ (LockMode) ? getBP() : 0,
+ RequestLength,
+ Request, RequestLength );
+ break;
+
+ case 0xD100: // Lock Logical Record Set
+
+ if (LockMode == 0) {
+ if (getDL()) {
+ Timeout = 0xffff;
+ } else {
+ Timeout = 0;
+ }
+ } else {
+ Timeout = getBP();
+ }
+
+ status = NwlibMakeNcp(
+ ServerHandles[Connection],
+ NWR_ANY_F2_NCP(0x0A),
+ 3, // RequestSize
+ 0, // ResponseSize
+ "bw",
+ (LockMode) ? Function : 0,
+ Timeout);
+ break;
+
+ case 0xD200: // Release File
+ case 0xD400: // Clear Logical Record
+ Request = GetVDMPointer (
+ (ULONG)((getDS() << 16)|getDX()),
+ sizeof(UCHAR),
+ IS_PROTECT_MODE());
+
+ RequestLength = Request[0]+1;
+
+ Request = GetVDMPointer (
+ (ULONG)((getDS() << 16)|getDX()),
+ RequestLength,
+ IS_PROTECT_MODE());
+
+ status = NwlibMakeNcp(
+ ServerHandles[Connection],
+ (Operation == 0xD200) ? NWR_ANY_F2_NCP(0x0C) :
+ NWR_ANY_F2_NCP(0x0B),
+ RequestLength+1,
+ 0, // ResponseSize
+ "br",
+ RequestLength,
+ Request, RequestLength );
+ break;
+
+ case 0xD300:
+ status = NwlibMakeNcp(
+ ServerHandles[Connection],
+ NWR_ANY_F2_NCP(0x13),
+ 0, // RequestSize
+ 0, // ResponseSize
+ "");
+ break;
+
+
+ case 0xD500: // Clear Logical Record Set
+ status = NwlibMakeNcp(
+ ServerHandles[Connection],
+ NWR_ANY_F2_NCP(0x0E),
+ 0, // RequestSize
+ 0, // ResponseSize
+ "");
+ break;
+
+ case 0xEB00: // Log File
+ case 0xEC00: // Release File
+ case 0xED00: // Clear File
+ {
+ UCHAR DirHandle;
+ HANDLE Win32DirectoryHandle = 0;
+ PUCHAR ptr;
+
+ Request = GetVDMPointer (
+ (ULONG)((getDS() << 16)|getDX()),
+ 256 * sizeof(UCHAR),
+ IS_PROTECT_MODE());
+
+ RequestLength = strlen(Request);
+
+ // Find DirHandle
+ ptr = Request;
+ while ( (*ptr != 0) &&
+ (!IS_ASCII_PATH_SEPARATOR(*ptr)) &&
+ (*ptr != ':' )) {
+ ptr++;
+ }
+
+ if (IS_ASCII_PATH_SEPARATOR(*ptr)) {
+ int ServerNameLength = ptr - Request;
+ PUCHAR scanptr = ptr;
+
+ //
+ // Make sure there is a ":" further up the name otherwise
+ // we could confuse foo\bar.txt with a server called foo
+ //
+
+ while ( (*scanptr != 0) &&
+ (*scanptr != ':' )) {
+ scanptr++;
+ }
+
+ if (*scanptr) {
+ //
+ // Name is of the form server\sys:foo\bar.txt
+ // set connection appropriately.
+ //
+
+ for (Connection = 0; Connection < MC ; Connection++ ) {
+
+ //
+ // Look for server foo avoiding foobar.
+ //
+
+ if ((pNwDosTable->ConnectionIdTable[Connection].ci_InUse ==
+ IN_USE) &&
+ (!memcmp( pNwDosTable->ServerNameTable[Connection],
+ Request,
+ ServerNameLength)) &&
+ (pNwDosTable->ServerNameTable[Connection][ServerNameLength] ==
+ '\0')) {
+ break; // Connection is the correct server
+ }
+ }
+
+ //
+ // Move Request to after the seperator and ptr to the ":"
+ //
+
+ RequestLength -= ptr + sizeof(UCHAR) - Request;
+ Request = ptr + sizeof(UCHAR);
+ ptr = scanptr;
+ }
+ }
+
+ if (*ptr) {
+
+ //
+ // Name of form "sys:foo\bar.txt" this gives the server
+ // all the information required.
+ //
+
+ DirHandle = 0;
+
+ if (Request[1] == ':') {
+
+ UCHAR Drive = tolower(Request[0])-'a';
+
+ //
+ // Its a normal (redirected) drive k:foo\bar.txt.
+ // Use the drive tables to give the connection and handle.
+ //
+
+ Connection = pNwDosTable->DriveIdTable[ Drive ] - 1;
+ DirHandle = pNwDosTable->DriveHandleTable[Drive];
+
+ if (DirHandle == 0) {
+ DirHandle = (UCHAR)GetDirectoryHandle2(Drive);
+ }
+ Request += 2; // skip "k:"
+ RequestLength -= 2;
+ }
+
+ } else {
+
+ WCHAR Curdir[256];
+
+ //
+ // Name of form "foo\bar.txt"
+ //
+
+ GetCurrentDirectory(sizeof(Curdir), Curdir);
+
+ Win32DirectoryHandle =
+ CreateFileW( Curdir,
+ 0,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL,
+ OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS,
+ 0);
+
+ if (Win32DirectoryHandle != INVALID_HANDLE_VALUE) {
+ DWORD BytesReturned;
+
+ if ( DeviceIoControl(
+ Win32DirectoryHandle,
+ IOCTL_NWR_RAW_HANDLE,
+ NULL,
+ 0,
+ (PUCHAR)&DirHandle,
+ sizeof(DirHandle),
+ &BytesReturned,
+ NULL ) == FALSE ) {
+
+ CloseHandle( Win32DirectoryHandle );
+ setAL(0xff);
+ return;
+
+ }
+
+ } else {
+
+ setAL(0xff);
+ return;
+ }
+ }
+
+ if (Operation == 0xEB00) {
+ status = NwlibMakeNcp(
+ ServerHandles[Connection],
+ NWR_ANY_F2_NCP(0x03),
+ RequestLength + 5,
+ 0, // ResponseSize
+ "bbwbr",
+ DirHandle,
+ (LockMode) ? Function : 0,
+ (LockMode) ? getBP() : 0,
+ RequestLength,
+ Request, RequestLength );
+
+ Tickle[Connection] = TRUE;
+
+ } else {
+ status = NwlibMakeNcp(
+ ServerHandles[Connection],
+ (Operation == 0xEC00 ) ?
+ NWR_ANY_F2_NCP(0x07) :
+ NWR_ANY_F2_NCP(0x05),
+ RequestLength + 2,
+ 0, // ResponseSize
+ "bbr",
+ DirHandle,
+ RequestLength,
+ Request, RequestLength );
+ }
+
+ if (Win32DirectoryHandle) {
+ CloseHandle( Win32DirectoryHandle );
+ }
+ }
+ break;
+
+ }
+
+ if (!NT_SUCCESS(status)) {
+ setAL((UCHAR)RtlNtStatusToDosError(status));
+ return;
+ } else {
+ setAL(0);
+ }
+}
+
+VOID
+InitLocks(
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Reset the Tickle internal variables
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ None.
+
+--*/
+{
+
+ ZeroMemory( Tickle, sizeof(Tickle));
+}
+
+VOID
+ResetLocks(
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Reset the Locks for the current VDM. Called during process exit.
+
+Arguments:
+
+ None.
+
+Return Value:
+
+ None.
+
+--*/
+{
+
+ Locks(0xCF00); // Clear all File sets.
+
+}
+
+NTSTATUS
+Sem(
+ UCHAR Function,
+ UCHAR Connection
+ )
+/*++
+
+Routine Description:
+
+ Build all NCPs for Semaphore support
+
+Arguments:
+
+ Function - Supplies the subfunction from AL
+
+ Connection - Supplies the server for the request
+
+Return Value:
+
+ None.
+
+--*/
+{
+ PUCHAR Request;
+ NTSTATUS status;
+
+ switch (Function) {
+
+ UCHAR Value;
+ UCHAR OpenCount;
+ WORD HandleHigh, HandleLow;
+
+ case 0: //OpenSemaphore
+
+ Request = GetVDMPointer (
+ (ULONG)((getDS() << 16)|getDX()),
+ 256 * sizeof(UCHAR),
+ IS_PROTECT_MODE());
+
+ NwPrint(("Nw16: OpenSemaphore\n"));
+
+ status = NwlibMakeNcp(
+ ServerHandles[Connection],
+ NWR_ANY_F2_NCP(0x20),
+ Request[0] + 3, // RequestSize
+ 5, // ResponseSize
+ "bbr|wwb",
+ 0,
+ getCL(), // Semaphore Value
+ Request, Request[0] + 1,
+
+ &HandleHigh, &HandleLow,
+ &OpenCount);
+
+
+ if (NT_SUCCESS(status)) {
+ setBL(OpenCount);
+ setCX(HandleHigh);
+ setDX(HandleLow);
+ }
+
+ break;
+
+ case 1: // ExamineSemaphore
+
+ NwPrint(("Nw16: ExamineSemaphore\n"));
+ status = NwlibMakeNcp(
+ ServerHandles[Connection],
+ NWR_ANY_F2_NCP(0x20),
+ 5, // RequestSize
+ 2, // ResponseSize
+ "bww|bb",
+ 1,
+ getCX(),getDX(),
+
+ &Value,
+ &OpenCount);
+
+ if (NT_SUCCESS(status)) {
+ setCX(Value);
+ setDL(OpenCount);
+ }
+ break;
+
+ case 2: // WaitOnSemaphore
+ NwPrint(("Nw16: WaitOnSemaphore\n"));
+ status = NwlibMakeNcp(
+ ServerHandles[Connection],
+ NWR_ANY_F2_NCP(0x20),
+ 7, // RequestSize
+ 0, // ResponseSize
+ "bwww",
+ 2,
+ getCX(),getDX(),
+ getBP());
+ break;
+
+ case 3: // SignalSemaphore
+ NwPrint(("Nw16: SignalSemaphore\n"));
+ case 4: // CloseSemaphore
+
+ if (Function == 4) {
+ NwPrint(("Nw16: CloseSemaphore\n"));
+ }
+
+ status = NwlibMakeNcp( // Close and Signal
+ ServerHandles[Connection],
+ NWR_ANY_F2_NCP(0x20),
+ 5, // RequestSize
+ 0, // ResponseSize
+ "bww",
+ Function,
+ getCX(),getDX());
+ break;
+
+ default:
+ NwPrint(("Nw16: Unknown Semaphore operation %d\n", Function));
+ break;
+ }
+ return status;
+}