|
|
/*++
Copyright (c) 1990 Microsoft Corporation
Module Name:
mailslot.c
Abstract:
This module contains the Win32 Mailslot API
Author:
Manny Weiser (mannyw) 4-Mar-1991
Revision History:
--*/
#include "basedll.h"
HANDLE APIENTRY CreateMailslotW( IN LPCWSTR lpName, IN DWORD nMaxMessageSize, IN DWORD lReadTimeout, IN LPSECURITY_ATTRIBUTES lpSecurityAttributes OPTIONAL )
/*++
Routine Description:
The create mailslot API creates a local mailslot and return a server-side handle to the mailslot.
Arguments:
lpName - The name of the mailslot. This must be a local mailslot name.
nMaxMessageSize - The size (in bytes) of the largest message that can be written to the mailslot.
lReadTimeout - The initial read timeout, in milliseconds. This is the amount of time a read operation will block waiting for a message to be written to the mailslot. This value can be changed with the SetMailslotInfo API.
lpSecurityAttributes - An optional pointer to security information for this mailslot.
Return Value:
Returns one of the following:
0xFFFFFFFF --An error occurred. Call GetLastError for more information.
Anything else --Returns a handle for use in the server side of subsequent mailslot operations.
--*/
{ OBJECT_ATTRIBUTES objectAttributes; UNICODE_STRING fileName; LPWSTR filePart; RTL_RELATIVE_NAME relativeName; IO_STATUS_BLOCK ioStatusBlock; LARGE_INTEGER readTimeout; HANDLE handle; NTSTATUS status; PVOID freeBuffer; BOOLEAN TranslationStatus;
RtlInitUnicodeString( &fileName, lpName );
TranslationStatus = RtlDosPathNameToNtPathName_U( lpName, &fileName, &filePart, &relativeName );
if ( !TranslationStatus ) { SetLastError(ERROR_PATH_NOT_FOUND); return INVALID_HANDLE_VALUE; }
freeBuffer = fileName.Buffer;
if ( relativeName.RelativeName.Length ) { fileName = *(PUNICODE_STRING)&relativeName.RelativeName; } else { relativeName.ContainingDirectory = NULL; }
InitializeObjectAttributes( &objectAttributes, &fileName, OBJ_CASE_INSENSITIVE, relativeName.ContainingDirectory, NULL );
if ( ARGUMENT_PRESENT(lpSecurityAttributes) ) { objectAttributes.SecurityDescriptor = lpSecurityAttributes->lpSecurityDescriptor; if ( lpSecurityAttributes->bInheritHandle ) { objectAttributes.Attributes |= OBJ_INHERIT; } }
if (lReadTimeout == MAILSLOT_WAIT_FOREVER) { readTimeout.HighPart = 0xFFFFFFFF; readTimeout.LowPart = 0xFFFFFFFF; } else { readTimeout.QuadPart = - (LONGLONG)UInt32x32To64( lReadTimeout, 10 * 1000 ); }
status = NtCreateMailslotFile ( &handle, GENERIC_READ | SYNCHRONIZE | WRITE_DAC, &objectAttributes, &ioStatusBlock, FILE_CREATE, 0, nMaxMessageSize, (PLARGE_INTEGER)&readTimeout );
if ( status == STATUS_NOT_SUPPORTED || status == STATUS_INVALID_DEVICE_REQUEST ) {
//
// The request must have been processed by some other device driver
// (other than MSFS). Map the error to something reasonable.
//
status = STATUS_OBJECT_NAME_INVALID; }
RtlFreeHeap( RtlProcessHeap(), 0, freeBuffer );
if (!NT_SUCCESS(status)) { BaseSetLastNTError( status ); return INVALID_HANDLE_VALUE; }
return handle; }
HANDLE APIENTRY CreateMailslotA( IN LPCSTR lpName, IN DWORD nMaxMessageSize, IN DWORD lReadTimeout, IN LPSECURITY_ATTRIBUTES lpSecurityAttributes OPTIONAL ) { PUNICODE_STRING unicode; ANSI_STRING ansiString; NTSTATUS status;
unicode = &NtCurrentTeb()->StaticUnicodeString; RtlInitAnsiString( &ansiString, lpName ); status = RtlAnsiStringToUnicodeString( unicode, &ansiString, FALSE );
if ( !NT_SUCCESS( status ) ) { if ( status == STATUS_BUFFER_OVERFLOW ) { SetLastError(ERROR_FILENAME_EXCED_RANGE); } else { BaseSetLastNTError(status); } return INVALID_HANDLE_VALUE; }
return ( CreateMailslotW( unicode->Buffer, nMaxMessageSize, lReadTimeout, lpSecurityAttributes ) );
}
BOOL APIENTRY GetMailslotInfo( IN HANDLE hMailslot, OUT LPDWORD lpMaxMessageSize OPTIONAL, OUT LPDWORD lpNextSize OPTIONAL, OUT LPDWORD lpMessageCount OPTIONAL, OUT LPDWORD lpReadTimeout OPTIONAL )
/*++
Routine Description:
This function will return the requested information about the specified mailslot.
Arguments:
hMailslot - A handle to the mailslot.
lpMaxMessageSize - If specified returns the size of the largest message that can be written to the mailslot.
lpNextSize - If specified returns the size of the next message in the mailslot buffer. It will return MAILSLOT_NO_MESSAGE if there are no messages in the mailslot.
lpMessageCount - If specified returns the number of unread message currently in the mailslot.
lpReadTimeout - If specified returns the read timeout, in milliseconds.
Return Value:
TRUE - The operation was successful.
FALSE/NULL - The operation failed. Extended error status is available using GetLastError.
--*/
{ NTSTATUS status; IO_STATUS_BLOCK ioStatusBlock; FILE_MAILSLOT_QUERY_INFORMATION mailslotInfo; LARGE_INTEGER millisecondTimeout, tmp;
status = NtQueryInformationFile( hMailslot, &ioStatusBlock, &mailslotInfo, sizeof( mailslotInfo ), FileMailslotQueryInformation );
if ( !NT_SUCCESS( status ) ) { BaseSetLastNTError( status ); return ( FALSE ); }
if ( ARGUMENT_PRESENT( lpMaxMessageSize ) ) { *lpMaxMessageSize = mailslotInfo.MaximumMessageSize; }
if ( ARGUMENT_PRESENT( lpNextSize ) ) { *lpNextSize = mailslotInfo.NextMessageSize; }
if ( ARGUMENT_PRESENT( lpMessageCount ) ) { *lpMessageCount = mailslotInfo.MessagesAvailable; }
if ( ARGUMENT_PRESENT( lpReadTimeout ) ) {
//
// Convert read timeout from 100 ns intervals to milliseconds.
// The readtime is currently negative, since it is a relative time.
//
if ( mailslotInfo.ReadTimeout.HighPart != 0xFFFFFFFF || mailslotInfo.ReadTimeout.LowPart != 0xFFFFFFFF ) {
tmp.QuadPart = - mailslotInfo.ReadTimeout.QuadPart; millisecondTimeout = RtlExtendedLargeIntegerDivide( tmp, 10 * 1000, NULL );
if ( millisecondTimeout.HighPart == 0 ) { *lpReadTimeout = millisecondTimeout.LowPart; } else {
//
// The millisecond calculation would overflow the dword.
// Approximate a large number as best we can.
//
*lpReadTimeout = 0xFFFFFFFE;
}
} else {
//
// The mailslot timeout is infinite.
//
*lpReadTimeout = MAILSLOT_WAIT_FOREVER;
} }
return( TRUE ); }
BOOL APIENTRY SetMailslotInfo( IN HANDLE hMailslot, IN DWORD lReadTimeout )
/*++
Routine Description:
This function will set the read timeout for the specified mailslot.
Arguments:
hMailslot - A handle to the mailslot.
lReadTimeout - The new read timeout, in milliseconds.
Return Value:
TRUE - The operation was successful.
FALSE/NULL - The operation failed. Extended error status is available using GetLastError.
--*/
{ NTSTATUS status; IO_STATUS_BLOCK ioStatusBlock; FILE_MAILSLOT_SET_INFORMATION mailslotInfo; LARGE_INTEGER timeout;
if ( lReadTimeout == MAILSLOT_WAIT_FOREVER ) { timeout.HighPart = 0xFFFFFFFF; timeout.LowPart = 0xFFFFFFFF; } else { timeout.QuadPart = - (LONGLONG)UInt32x32To64( lReadTimeout, 10 * 1000 ); }
mailslotInfo.ReadTimeout = &timeout; status = NtSetInformationFile( hMailslot, &ioStatusBlock, &mailslotInfo, sizeof( mailslotInfo ), FileMailslotSetInformation );
if ( !NT_SUCCESS( status ) ) { BaseSetLastNTError( status ); return ( FALSE ); }
return TRUE; }
|