diff options
Diffstat (limited to '')
-rw-r--r-- | private/nw/nw16/dll/locks.c | 677 |
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; +} |