summaryrefslogtreecommitdiffstats
path: root/private/os2/client/dllmsl16.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--private/os2/client/dllmsl16.c712
1 files changed, 712 insertions, 0 deletions
diff --git a/private/os2/client/dllmsl16.c b/private/os2/client/dllmsl16.c
new file mode 100644
index 000000000..f109ffd10
--- /dev/null
+++ b/private/os2/client/dllmsl16.c
@@ -0,0 +1,712 @@
+/*++
+
+Copyright (c) 1989 Microsoft Corporation
+
+Module Name:
+
+ dllmsl16.c
+
+Abstract:
+
+ This module implements the OS/2 V1.x Lanman Mailslot APIs.
+
+Author:
+
+ Beni Lavi (benil) 3-Mar-1992
+
+Revision History:
+
+--*/
+
+
+#define INCL_OS2V20_ERRORS
+#define INCL_OS2V20_FILESYS
+#include "os2dll.h"
+
+#define NERR_NetNotStarted 2102
+
+APIRET
+Dos16MakeMailslot(
+ IN PSZ pName,
+ IN ULONG MessageSize,
+ IN ULONG MailslotSize,
+ OUT PUSHORT pMailslot
+ )
+{
+ APIRET RetCode;
+ NTSTATUS Status;
+ HFILE hLocalHandle;
+ PFILE_HANDLE hFileRecord;
+ STRING CanonicalNameString;
+ UNICODE_STRING CanonicalNameString_U;
+ ULONG FileType;
+ ULONG FileFlags;
+ ULONG CalculatedMailslotSize;
+ HANDLE NtFileHandle;
+ OBJECT_ATTRIBUTES Obja;
+ IO_STATUS_BLOCK IoStatus;
+ PSECURITY_DESCRIPTOR securityDescriptor;
+ CHAR localSecurityDescriptor[SECURITY_DESCRIPTOR_MIN_LENGTH];
+
+ #if DBG
+ PSZ RoutineName = "DosMakeMailslot";
+ #endif
+
+ try {
+ Od2ProbeForWrite(pMailslot, sizeof(USHORT), 1);
+ } except( EXCEPTION_EXECUTE_HANDLER ) {
+ Od2ExitGP();
+ }
+
+ AcquireFileLockExclusive(
+ #if DBG
+ RoutineName
+ #endif
+ );
+ RetCode = AllocateHandle(&hLocalHandle);
+ ReleaseFileLockExclusive(
+ #if DBG
+ RoutineName
+ #endif
+ );
+ if (RetCode) {
+ return RetCode;
+ }
+
+ RetCode = Od2Canonicalize(pName,
+ CANONICALIZE_MAILSLOT,
+ &CanonicalNameString,
+ &NtFileHandle,
+ &FileFlags, // BUGBUG shouldn't we check for root dir
+ &FileType
+ );
+ if ((RetCode != NO_ERROR)|| (FileFlags & CANONICALIZE_META_CHARS_FOUND)) {
+ AcquireFileLockExclusive(
+ #if DBG
+ RoutineName
+ #endif
+ );
+ FreeHandle(hLocalHandle);
+ ReleaseFileLockExclusive(
+ #if DBG
+ RoutineName
+ #endif
+ );
+ if (RetCode == NO_ERROR && (FileFlags & CANONICALIZE_META_CHARS_FOUND)) {
+ RtlFreeHeap(Od2Heap,0,CanonicalNameString.Buffer);
+ RetCode = ERROR_FILE_NOT_FOUND;
+ }
+ return RetCode;
+ }
+
+#if DBG
+ IF_OD2_DEBUG( FILESYS ) {
+ DbgPrint("canonical name is %s\n",CanonicalNameString.Buffer);
+ }
+#endif
+
+ //
+ // UNICODE conversion -
+ //
+
+ RetCode = Od2MBStringToUnicodeString(
+ &CanonicalNameString_U,
+ &CanonicalNameString,
+ TRUE);
+
+ if (RetCode)
+ {
+#if DBG
+ IF_OD2_DEBUG( FILESYS )
+ {
+ DbgPrint("Dos16MakeMailslot: no memory for Unicode Conversion\n");
+ }
+#endif
+ RtlFreeHeap(Od2Heap,0,CanonicalNameString.Buffer);
+ AcquireFileLockExclusive(
+ #if DBG
+ RoutineName
+ #endif
+ );
+ FreeHandle(hLocalHandle);
+ ReleaseFileLockExclusive(
+ #if DBG
+ RoutineName
+ #endif
+ );
+ return RetCode;
+ }
+
+ Status = RtlCreateSecurityDescriptor( (PSECURITY_DESCRIPTOR)
+ &localSecurityDescriptor,
+ SECURITY_DESCRIPTOR_REVISION );
+ if (!NT_SUCCESS( Status )) {
+#if DBG
+ DbgPrint("DosMakeMailslot: failed at RtlCreateSecurityDescriptor %x\n", Status);
+ ASSERT(FALSE);
+#endif
+ return ERROR_ACCESS_DENIED;
+ }
+
+ Status = RtlSetDaclSecurityDescriptor( (PSECURITY_DESCRIPTOR)
+ &localSecurityDescriptor,
+ (BOOLEAN)TRUE,
+ (PACL) NULL,
+ (BOOLEAN)FALSE );
+
+ if (!NT_SUCCESS( Status )) {
+#if DBG
+ DbgPrint("DosMakeMailslot: failed at RtlSetDaclSecurityDescriptor %x\n", Status);
+ ASSERT(FALSE);
+#endif
+ return ERROR_ACCESS_DENIED;
+ }
+ securityDescriptor = (PSECURITY_DESCRIPTOR) &localSecurityDescriptor;
+ InitializeObjectAttributes( &Obja,
+ &CanonicalNameString_U,
+ OBJ_CASE_INSENSITIVE,
+ NtFileHandle,
+ securityDescriptor
+ );
+
+ CalculatedMailslotSize = MailslotSize * 2;
+ if (CalculatedMailslotSize < 4096) {
+ CalculatedMailslotSize = 4096;
+ }
+
+ Status = NtCreateMailslotFile(
+ &NtFileHandle,
+ SYNCHRONIZE |
+ FILE_READ_DATA | FILE_WRITE_DATA |
+ FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES,
+ &Obja,
+ &IoStatus,
+ FILE_SYNCHRONOUS_IO_ALERT,
+ CalculatedMailslotSize,
+ MessageSize,
+ NULL // WAIT FOREVER
+ );
+
+ RtlFreeHeap(Od2Heap,0,CanonicalNameString.Buffer);
+ RtlFreeUnicodeString (&CanonicalNameString_U);
+
+ if (!(NT_SUCCESS(Status))) {
+#if DBG
+ IF_OD2_DEBUG( FILESYS ) {
+ DbgPrint("St == %X\n",Status);
+ }
+#endif
+
+ AcquireFileLockExclusive(
+ #if DBG
+ RoutineName
+ #endif
+ );
+ FreeHandle(hLocalHandle);
+ ReleaseFileLockExclusive(
+ #if DBG
+ RoutineName
+ #endif
+ );
+
+ //
+ // Map some of the NT error codes where there is a clear mapping
+ //
+ switch (Status) {
+ case STATUS_OBJECT_NAME_COLLISION:
+ return ERROR_ALREADY_EXISTS;
+
+ default:
+ return (Or2MapNtStatusToOs2Error(Status, ERROR_PATH_NOT_FOUND));
+ }
+ }
+
+ AcquireFileLockExclusive(
+ #if DBG
+ RoutineName
+ #endif
+ );
+ hFileRecord = DereferenceFileHandleNoCheck(hLocalHandle);
+ hFileRecord->NtHandle = NtFileHandle;
+ hFileRecord->FileType = (USHORT) FILE_TYPE_MAILSLOT;
+ hFileRecord->Flags |= OPEN_SHARE_DENYREAD & QFHSTATE_FLAGS;
+ hFileRecord->DeviceAttribute = 0;
+ hFileRecord->IoVectorType = FileVectorType;
+
+ //
+ // validate file handle
+ //
+
+ ValidateHandle(hFileRecord);
+ ReleaseFileLockExclusive(
+ #if DBG
+ RoutineName
+ #endif
+ );
+
+ *pMailslot = (USHORT)hLocalHandle;
+ return NO_ERROR;
+}
+
+APIRET
+Dos16DeleteMailslot(
+ IN HFILE Mailslot
+ )
+{
+ APIRET RetCode;
+
+ RetCode = DosClose(Mailslot);
+
+ return NO_ERROR;
+}
+
+APIRET
+Dos16MailslotInfo(
+ IN HFILE Mailslot,
+ OUT PUSHORT pMessageSize,
+ OUT PUSHORT pMailslotSize,
+ OUT PUSHORT pNextSize,
+ OUT PUSHORT pNextPriority,
+ OUT PUSHORT pMessages
+ )
+{
+ APIRET RetCode;
+ NTSTATUS Status;
+ PFILE_HANDLE hFileRecord;
+ HANDLE NtFileHandle;
+ IO_STATUS_BLOCK IoStatus;
+ FILE_MAILSLOT_QUERY_INFORMATION MailslotInfo;
+ #if DBG
+ PSZ RoutineName = "DosMakeMailslot";
+ #endif
+
+
+ try {
+ Od2ProbeForWrite(pMessageSize, sizeof(USHORT), 1);
+ Od2ProbeForWrite(pMailslotSize, sizeof(USHORT), 1);
+ Od2ProbeForWrite(pNextSize, sizeof(USHORT), 1);
+ Od2ProbeForWrite(pNextPriority, sizeof(USHORT), 1);
+ Od2ProbeForWrite(pMessages, sizeof(USHORT), 1);
+ } except( EXCEPTION_EXECUTE_HANDLER ) {
+ Od2ExitGP();
+ }
+
+ AcquireFileLockShared(
+ #if DBG
+ RoutineName
+ #endif
+ );
+ RetCode = DereferenceFileHandle(Mailslot, &hFileRecord);
+ if (RetCode) {
+ ReleaseFileLockShared(
+ #if DBG
+ RoutineName
+ #endif
+ );
+ return RetCode;
+ }
+ if (hFileRecord->FileType != FILE_TYPE_MAILSLOT) {
+ ReleaseFileLockShared(
+ #if DBG
+ RoutineName
+ #endif
+ );
+ return ERROR_INVALID_HANDLE;
+ }
+ NtFileHandle = hFileRecord->NtHandle;
+
+ Status = NtQueryInformationFile(
+ NtFileHandle,
+ &IoStatus,
+ &MailslotInfo,
+ sizeof(FILE_MAILSLOT_QUERY_INFORMATION),
+ FileMailslotQueryInformation
+ );
+
+ ReleaseFileLockShared(
+ #if DBG
+ RoutineName
+ #endif
+ );
+
+ if (!(NT_SUCCESS(Status))) {
+ return ERROR_INVALID_HANDLE;
+ }
+
+ *pMessageSize = (USHORT)MailslotInfo.MaximumMessageSize;
+ *pMailslotSize = (USHORT)MailslotInfo.MailslotQuota;
+ *pNextSize = (USHORT)((MailslotInfo.NextMessageSize == MAILSLOT_NO_MESSAGE)
+ ? 0 : MailslotInfo.NextMessageSize);
+ *pNextPriority = 0;
+ *pMessages = (USHORT)MailslotInfo.MessagesAvailable;
+
+ return NO_ERROR;
+}
+
+APIRET
+Dos16ReadMailslot(
+ IN HANDLE Mailslot,
+ OUT PCHAR pBuffer,
+ OUT PUSHORT pReturned,
+ OUT PUSHORT pNextSize,
+ OUT PUSHORT pNextPriority,
+ IN LONG Timeout
+ )
+{
+ APIRET RetCode;
+ NTSTATUS Status;
+ PFILE_HANDLE hFileRecord;
+ HANDLE NtFileHandle;
+ IO_STATUS_BLOCK IoStatus;
+ ULONG FileType;
+ LARGE_INTEGER NtTimeout;
+ ULONG BytesRead;
+ FILE_MAILSLOT_QUERY_INFORMATION MailslotQueryInfo;
+ FILE_MAILSLOT_SET_INFORMATION MailslotSetInfo;
+ #if DBG
+ PSZ RoutineName = "DosReadMailslot";
+ #endif
+
+ try {
+ Od2ProbeForWrite(pReturned, sizeof(USHORT), 1);
+ Od2ProbeForWrite(pNextSize, sizeof(USHORT), 1);
+ Od2ProbeForWrite(pNextPriority, sizeof(USHORT), 1);
+ } except( EXCEPTION_EXECUTE_HANDLER ) {
+ Od2ExitGP();
+ }
+
+ AcquireFileLockShared(
+ #if DBG
+ RoutineName
+ #endif
+ );
+
+ //
+ // Check for invalid handle.
+ //
+
+ RetCode = DereferenceFileHandle(Mailslot, &hFileRecord);
+ if (RetCode) {
+ ReleaseFileLockShared(
+ #if DBG
+ RoutineName
+ #endif
+ );
+ return RetCode;
+ }
+ NtFileHandle = hFileRecord->NtHandle;
+ FileType = hFileRecord->FileType;
+ ReleaseFileLockShared(
+ #if DBG
+ RoutineName
+ #endif
+ );
+
+ if (FileType != FILE_TYPE_MAILSLOT) {
+ return ERROR_INVALID_HANDLE;
+ }
+
+ //
+ // Set the timeout to the value requested by the read operation
+ //
+ if (Timeout == -1 /*MAILSLOT_NO_TIMEOUT*/) {
+ NtTimeout = RtlConvertLongToLargeInteger(MAILSLOT_WAIT_FOREVER);
+ }
+ else {
+ NtTimeout = RtlEnlargedIntegerMultiply(-10000, Timeout);
+ }
+ MailslotSetInfo.ReadTimeout = &NtTimeout;
+
+ Status = NtSetInformationFile(
+ NtFileHandle,
+ &IoStatus,
+ &MailslotSetInfo,
+ sizeof(FILE_MAILSLOT_SET_INFORMATION),
+ FileMailslotSetInformation
+ );
+
+ if (!(NT_SUCCESS(Status))) {
+ return (Or2MapNtStatusToOs2Error(Status, ERROR_BROKEN_PIPE));
+ }
+
+ //
+ // Get the maximum possible size of the buffer
+ //
+ Status = NtQueryInformationFile(
+ NtFileHandle,
+ &IoStatus,
+ &MailslotQueryInfo,
+ sizeof(FILE_MAILSLOT_QUERY_INFORMATION),
+ FileMailslotQueryInformation
+ );
+
+ if (!(NT_SUCCESS(Status))) {
+ return (Or2MapNtStatusToOs2Error(Status, ERROR_BROKEN_PIPE));
+ }
+
+ Status = NtReadFile(
+ NtFileHandle,
+ 0,
+ NULL,
+ NULL,
+ &IoStatus,
+ pBuffer,
+ MailslotQueryInfo.MaximumMessageSize,
+ NULL,
+ NULL
+ );
+
+ if (!(NT_SUCCESS(Status))) {
+ return (Or2MapNtStatusToOs2Error(Status, ERROR_BROKEN_PIPE));
+ }
+
+ BytesRead = IoStatus.Information;
+
+ //
+ // Get Info about next message in buffer
+ //
+ Status = NtQueryInformationFile(
+ NtFileHandle,
+ &IoStatus,
+ &MailslotQueryInfo,
+ sizeof(FILE_MAILSLOT_QUERY_INFORMATION),
+ FileMailslotQueryInformation
+ );
+
+ if (!(NT_SUCCESS(Status))) {
+ return (Or2MapNtStatusToOs2Error(Status, ERROR_BROKEN_PIPE));
+ }
+
+ *pReturned = (USHORT)BytesRead;
+ if (MailslotQueryInfo.NextMessageSize == MAILSLOT_NO_MESSAGE) {
+ *pNextSize = 0;
+ }
+ else {
+ *pNextSize = (USHORT)MailslotQueryInfo.NextMessageSize;
+ }
+ *pNextPriority = 0;
+
+ return NO_ERROR;
+}
+
+APIRET
+Dos16PeekMailslot(
+ IN HANDLE Mailslot,
+ OUT PCHAR pBuffer,
+ OUT PUSHORT pReturned,
+ OUT PUSHORT pNextSize,
+ OUT PUSHORT pNextPriority
+ )
+{
+ APIRET RetCode;
+ NTSTATUS Status;
+ PFILE_HANDLE hFileRecord;
+ HANDLE NtFileHandle;
+ IO_STATUS_BLOCK IoStatus;
+ ULONG FileType;
+ FILE_MAILSLOT_QUERY_INFORMATION MailslotInfo;
+ FILE_MAILSLOT_PEEK_BUFFER MailslotPeekBuffer;
+ #if DBG
+ PSZ RoutineName = "DosPeekMailslot";
+ #endif
+
+ try {
+ Od2ProbeForWrite(pReturned, sizeof(USHORT), 1);
+ Od2ProbeForWrite(pNextSize, sizeof(USHORT), 1);
+ Od2ProbeForWrite(pNextPriority, sizeof(USHORT), 1);
+ } except( EXCEPTION_EXECUTE_HANDLER ) {
+ Od2ExitGP();
+ }
+
+ AcquireFileLockShared(
+ #if DBG
+ RoutineName
+ #endif
+ );
+
+ //
+ // Check for invalid handle.
+ //
+
+ RetCode = DereferenceFileHandle(Mailslot, &hFileRecord);
+ if (RetCode) {
+ ReleaseFileLockShared(
+ #if DBG
+ RoutineName
+ #endif
+ );
+ return RetCode;
+ }
+ NtFileHandle = hFileRecord->NtHandle;
+ FileType = hFileRecord->FileType;
+ ReleaseFileLockShared(
+ #if DBG
+ RoutineName
+ #endif
+ );
+
+ if (FileType != FILE_TYPE_MAILSLOT) {
+ return ERROR_INVALID_HANDLE;
+ }
+
+ Status = NtQueryInformationFile(
+ NtFileHandle,
+ &IoStatus,
+ &MailslotInfo,
+ sizeof(FILE_MAILSLOT_QUERY_INFORMATION),
+ FileMailslotQueryInformation
+ );
+
+ if (!(NT_SUCCESS(Status))) {
+ return ERROR_BROKEN_PIPE;
+ }
+
+ if (MailslotInfo.NextMessageSize == (ULONG)(MAILSLOT_NO_MESSAGE)) {
+ *pReturned = 0;
+ *pNextSize = 0;
+ *pNextPriority = 0;
+ return (NO_ERROR);
+ }
+
+ Status = NtFsControlFile( NtFileHandle,
+ 0,
+ NULL,
+ NULL,
+ &IoStatus,
+ FSCTL_MAILSLOT_PEEK,
+ &MailslotPeekBuffer,
+ sizeof(FILE_MAILSLOT_PEEK_BUFFER),
+ pBuffer,
+ MailslotInfo.NextMessageSize
+ );
+
+ if (!NT_SUCCESS(Status)) {
+ return (Or2MapNtStatusToOs2Error(Status, ERROR_BROKEN_PIPE));
+ }
+
+ *pReturned = (USHORT)MailslotPeekBuffer.MessageLength;
+ if (MailslotPeekBuffer.NumberOfMessages <= 1) {
+ *pNextSize = 0;
+ }
+ else {
+ //
+ // We don't have enough information to determine the NextSize
+ // value so we play it safe
+ //
+ *pNextSize = (USHORT)MailslotInfo.MaximumMessageSize;
+ }
+ *pNextPriority = 0;
+
+ return NO_ERROR;
+}
+
+APIRET
+Dos16WriteMailslot(
+ IN PSZ pName,
+ OUT PCHAR pBuffer,
+ IN ULONG BufferSize,
+ IN ULONG Priority,
+ IN ULONG Class,
+ IN LONG Timeout
+ )
+{
+ APIRET RetCode;
+ NTSTATUS Status;
+ ULONG FileType;
+ ULONG FileFlags;
+ STRING CanonicalNameString;
+ UNICODE_STRING CanonicalNameString_U;
+ HANDLE NtFileHandle;
+ OBJECT_ATTRIBUTES Obja;
+ IO_STATUS_BLOCK IoStatus;
+
+ UNREFERENCED_PARAMETER(Priority);
+ UNREFERENCED_PARAMETER(Class);
+ UNREFERENCED_PARAMETER(Timeout);
+
+ try {
+ Od2ProbeForRead(pBuffer, BufferSize, 1);
+ } except( EXCEPTION_EXECUTE_HANDLER ) {
+ Od2ExitGP();
+ }
+
+ RetCode = Od2Canonicalize(pName,
+ CANONICALIZE_MAILSLOT,
+ &CanonicalNameString,
+ &NtFileHandle,
+ &FileFlags,
+ &FileType
+ );
+ if (RetCode != NO_ERROR) {
+ return (ERROR_FILE_NOT_FOUND);
+ }
+
+#if DBG
+ IF_OD2_DEBUG( FILESYS ) {
+ DbgPrint("canonical name is %s\n",CanonicalNameString.Buffer);
+ }
+#endif
+
+ //
+ // UNICODE conversion -
+ //
+
+ RetCode = Od2MBStringToUnicodeString(
+ &CanonicalNameString_U,
+ &CanonicalNameString,
+ TRUE);
+
+ if (RetCode)
+ {
+#if DBG
+ IF_OD2_DEBUG( FILESYS )
+ {
+ DbgPrint("Dos16WriteMailslot: no memory for Unicode Conversion\n");
+ }
+#endif
+ RtlFreeHeap(Od2Heap,0,CanonicalNameString.Buffer);
+ return RetCode;
+ }
+
+ InitializeObjectAttributes(&Obja,
+ &CanonicalNameString_U,
+ OBJ_CASE_INSENSITIVE,
+ NtFileHandle,
+ NULL);
+
+ Status = NtOpenFile(
+ &NtFileHandle,
+ SYNCHRONIZE | FILE_WRITE_DATA | FILE_READ_DATA,
+ &Obja,
+ &IoStatus,
+ FILE_SHARE_WRITE | FILE_SHARE_READ,
+ FILE_SYNCHRONOUS_IO_ALERT
+ );
+
+ RtlFreeHeap(Od2Heap,0,CanonicalNameString.Buffer);
+ RtlFreeUnicodeString (&CanonicalNameString_U);
+
+ if (!(NT_SUCCESS(Status))) {
+ return (Or2MapNtStatusToOs2Error(Status, ERROR_PATH_NOT_FOUND));
+ }
+
+ Status = NtWriteFile(
+ NtFileHandle,
+ 0,
+ NULL,
+ NULL,
+ &IoStatus,
+ pBuffer,
+ BufferSize,
+ NULL,
+ 0
+ );
+
+ if (!(NT_SUCCESS(Status))) {
+ return (Or2MapNtStatusToOs2Error(Status, ERROR_BROKEN_PIPE));
+ }
+
+ Status = NtClose(NtFileHandle);
+
+ return NO_ERROR;
+}