[KERNEL32]: Fix mailslot code to use the static unicode string in the TEB for conversion, and correctly handle failure cases to bound names to MAX_PATH as Win32 demands. Also fix timeout conversions to use the correct timeout value for infinite timeout.

[KERNEL32]: Reformat since 3-space identation is just murder.

svn path=/trunk/; revision=54365
This commit is contained in:
Alex Ionescu 2011-11-12 18:28:16 +00:00
parent 1898591063
commit 174739a13c
2 changed files with 178 additions and 158 deletions

View file

@ -8,216 +8,226 @@
* UPDATE HISTORY:
*/
/* INCLUDES *****************************************************************/
/* INCLUDES *******************************************************************/
#include <k32.h>
#define NDEBUG
#include <debug.h>
DEBUG_CHANNEL(kernel32file);
/* FUNCTIONS ****************************************************************/
/* FUNCTIONS ******************************************************************/
/*
* @implemented
*/
HANDLE WINAPI
CreateMailslotA(LPCSTR lpName,
DWORD nMaxMessageSize,
DWORD lReadTimeout,
LPSECURITY_ATTRIBUTES lpSecurityAttributes)
HANDLE
WINAPI
CreateMailslotA(IN LPCSTR lpName,
IN DWORD nMaxMessageSize,
IN DWORD lReadTimeout,
IN LPSECURITY_ATTRIBUTES lpSecurityAttributes)
{
HANDLE MailslotHandle;
UNICODE_STRING NameU;
ANSI_STRING NameA;
PUNICODE_STRING NameU;
ANSI_STRING NameA;
NTSTATUS Status;
RtlInitAnsiString(&NameA, (LPSTR)lpName);
RtlAnsiStringToUnicodeString(&NameU, &NameA, TRUE);
NameU = &NtCurrentTeb()->StaticUnicodeString;
MailslotHandle = CreateMailslotW(NameU.Buffer,
nMaxMessageSize,
lReadTimeout,
lpSecurityAttributes);
RtlInitAnsiString(&NameA, (LPSTR)lpName);
Status = RtlAnsiStringToUnicodeString(NameU, &NameA, FALSE);
if (!NT_SUCCESS(Status))
{
if (Status == STATUS_BUFFER_OVERFLOW)
{
SetLastError(ERROR_FILENAME_EXCED_RANGE);
}
else
{
BaseSetLastNTError(Status);
}
RtlFreeUnicodeString(&NameU);
return INVALID_HANDLE_VALUE;
}
return(MailslotHandle);
return CreateMailslotW(NameU->Buffer,
nMaxMessageSize,
lReadTimeout,
lpSecurityAttributes);
}
/*
* @implemented
*/
HANDLE WINAPI
CreateMailslotW(LPCWSTR lpName,
DWORD nMaxMessageSize,
DWORD lReadTimeout,
LPSECURITY_ATTRIBUTES lpSecurityAttributes)
HANDLE
WINAPI
CreateMailslotW(IN LPCWSTR lpName,
IN DWORD nMaxMessageSize,
IN DWORD lReadTimeout,
IN LPSECURITY_ATTRIBUTES lpSecurityAttributes)
{
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING MailslotName;
HANDLE MailslotHandle;
NTSTATUS Status;
BOOLEAN Result;
LARGE_INTEGER DefaultTimeOut;
IO_STATUS_BLOCK Iosb;
ULONG Attributes = OBJ_CASE_INSENSITIVE;
PSECURITY_DESCRIPTOR SecurityDescriptor = NULL;
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING MailslotName;
HANDLE MailslotHandle;
NTSTATUS Status;
BOOLEAN Result;
LARGE_INTEGER DefaultTimeOut;
IO_STATUS_BLOCK Iosb;
ULONG Attributes = OBJ_CASE_INSENSITIVE;
PSECURITY_DESCRIPTOR SecurityDescriptor = NULL;
Result = RtlDosPathNameToNtPathName_U(lpName,
&MailslotName,
NULL,
NULL);
if (!Result)
{
SetLastError(ERROR_PATH_NOT_FOUND);
return(INVALID_HANDLE_VALUE);
}
Result = RtlDosPathNameToNtPathName_U(lpName, &MailslotName, NULL, NULL);
if (!Result)
{
SetLastError(ERROR_PATH_NOT_FOUND);
return INVALID_HANDLE_VALUE;
}
TRACE("Mailslot name: %wZ\n", &MailslotName);
DPRINT("Mailslot name: %wZ\n", &MailslotName);
if(lpSecurityAttributes)
{
SecurityDescriptor = lpSecurityAttributes->lpSecurityDescriptor;
if(lpSecurityAttributes->bInheritHandle)
Attributes |= OBJ_INHERIT;
}
if (lpSecurityAttributes)
{
SecurityDescriptor = lpSecurityAttributes->lpSecurityDescriptor;
if(lpSecurityAttributes->bInheritHandle) Attributes |= OBJ_INHERIT;
}
InitializeObjectAttributes(&ObjectAttributes,
&MailslotName,
Attributes,
NULL,
SecurityDescriptor);
InitializeObjectAttributes(&ObjectAttributes,
&MailslotName,
Attributes,
NULL,
SecurityDescriptor);
if (lReadTimeout == MAILSLOT_WAIT_FOREVER)
{
/* Set the max */
DefaultTimeOut.LowPart = 0;
DefaultTimeOut.HighPart = 0x80000000;
}
else
{
/* Convert to NT format */
DefaultTimeOut.QuadPart = UInt32x32To64(-10000, lReadTimeout);
}
if (lReadTimeout == MAILSLOT_WAIT_FOREVER)
{
/* Set the max */
DefaultTimeOut.QuadPart = 0xFFFFFFFFFFFFFFFFLL;
}
else
{
/* Convert to NT format */
DefaultTimeOut.QuadPart = UInt32x32To64(-10000, lReadTimeout);
}
Status = NtCreateMailslotFile(&MailslotHandle,
GENERIC_READ | SYNCHRONIZE | WRITE_DAC,
&ObjectAttributes,
&Iosb,
FILE_WRITE_THROUGH,
0,
nMaxMessageSize,
&DefaultTimeOut);
Status = NtCreateMailslotFile(&MailslotHandle,
GENERIC_READ | SYNCHRONIZE | WRITE_DAC,
&ObjectAttributes,
&Iosb,
FILE_WRITE_THROUGH,
0,
nMaxMessageSize,
&DefaultTimeOut);
if (Status == STATUS_INVALID_DEVICE_REQUEST || Status == STATUS_NOT_SUPPORTED)
{
Status = STATUS_OBJECT_NAME_INVALID;
}
if ((Status == STATUS_INVALID_DEVICE_REQUEST) ||
(Status == STATUS_NOT_SUPPORTED))
{
Status = STATUS_OBJECT_NAME_INVALID;
}
RtlFreeHeap(RtlGetProcessHeap(),
0,
MailslotName.Buffer);
RtlFreeHeap(RtlGetProcessHeap(), 0, MailslotName.Buffer);
if (!NT_SUCCESS(Status))
{
WARN("NtCreateMailslot failed (Status %x)!\n", Status);
BaseSetLastNTError (Status);
return(INVALID_HANDLE_VALUE);
}
if (!NT_SUCCESS(Status))
{
DPRINT1("NtCreateMailslot failed (Status %x)!\n", Status);
BaseSetLastNTError(Status);
return INVALID_HANDLE_VALUE;
}
return(MailslotHandle);
return MailslotHandle;
}
/*
* @implemented
*/
BOOL WINAPI
GetMailslotInfo(HANDLE hMailslot,
LPDWORD lpMaxMessageSize,
LPDWORD lpNextSize,
LPDWORD lpMessageCount,
LPDWORD lpReadTimeout)
BOOL
WINAPI
GetMailslotInfo(IN HANDLE hMailslot,
IN LPDWORD lpMaxMessageSize,
IN LPDWORD lpNextSize,
IN LPDWORD lpMessageCount,
IN LPDWORD lpReadTimeout)
{
FILE_MAILSLOT_QUERY_INFORMATION Buffer;
IO_STATUS_BLOCK Iosb;
NTSTATUS Status;
FILE_MAILSLOT_QUERY_INFORMATION Buffer;
IO_STATUS_BLOCK Iosb;
NTSTATUS Status;
LARGE_INTEGER Timeout;
Status = NtQueryInformationFile(hMailslot,
&Iosb,
&Buffer,
sizeof(FILE_MAILSLOT_QUERY_INFORMATION),
FileMailslotQueryInformation);
if (!NT_SUCCESS(Status))
{
WARN("NtQueryInformationFile failed (Status %x)!\n", Status);
BaseSetLastNTError (Status);
return(FALSE);
Status = NtQueryInformationFile(hMailslot,
&Iosb,
&Buffer,
sizeof(FILE_MAILSLOT_QUERY_INFORMATION),
FileMailslotQueryInformation);
if (!NT_SUCCESS(Status))
{
DPRINT1("NtQueryInformationFile failed (Status %x)!\n", Status);
BaseSetLastNTError(Status);
return FALSE;
}
if (lpMaxMessageSize != NULL)
if (lpMaxMessageSize) *lpMaxMessageSize = Buffer.MaximumMessageSize;
if (lpNextSize) *lpNextSize = Buffer.NextMessageSize;
if (lpMessageCount) *lpMessageCount = Buffer.MessagesAvailable;
if (lpReadTimeout)
{
*lpMaxMessageSize = Buffer.MaximumMessageSize;
}
if (lpNextSize != NULL)
{
*lpNextSize = Buffer.NextMessageSize;
}
if (lpMessageCount != NULL)
{
*lpMessageCount = Buffer.MessagesAvailable;
}
if (lpReadTimeout != NULL)
{
if (Buffer.ReadTimeout.LowPart == 0 &&
Buffer.ReadTimeout.HighPart == (LONG)0x80000000)
*lpReadTimeout = MAILSLOT_WAIT_FOREVER;
else
*lpReadTimeout = (DWORD)(Buffer.ReadTimeout.QuadPart / -10000);
if (Buffer.ReadTimeout.QuadPart == 0xFFFFFFFFFFFFFFFFLL)
{
*lpReadTimeout = MAILSLOT_WAIT_FOREVER;
}
else
{
Timeout.QuadPart = -Buffer.ReadTimeout.QuadPart;
Timeout = RtlExtendedLargeIntegerDivide(Timeout, 10000, NULL);
if (Timeout.HighPart == 0)
{
*lpReadTimeout = Timeout.LowPart;
}
else
{
*lpReadTimeout = 0xFFFFFFFE;
}
}
}
return(TRUE);
return TRUE;
}
/*
* @implemented
*/
BOOL WINAPI
SetMailslotInfo(HANDLE hMailslot,
DWORD lReadTimeout)
BOOL
WINAPI
SetMailslotInfo(IN HANDLE hMailslot,
IN DWORD lReadTimeout)
{
FILE_MAILSLOT_SET_INFORMATION Buffer;
LARGE_INTEGER Timeout;
IO_STATUS_BLOCK Iosb;
NTSTATUS Status;
FILE_MAILSLOT_SET_INFORMATION Buffer;
LARGE_INTEGER Timeout;
IO_STATUS_BLOCK Iosb;
NTSTATUS Status;
if (lReadTimeout == MAILSLOT_WAIT_FOREVER)
{
/* Set the max */
Timeout.LowPart = 0;
Timeout.HighPart = 0x80000000;
}
else
{
/* Convert to NT format */
Timeout.QuadPart = UInt32x32To64(-10000, lReadTimeout);
}
Buffer.ReadTimeout = &Timeout;
if (lReadTimeout == MAILSLOT_WAIT_FOREVER)
{
/* Set the max */
Timeout.QuadPart = 0xFFFFFFFFFFFFFFFFLL;
}
else
{
/* Convert to NT format */
Timeout.QuadPart = UInt32x32To64(-10000, lReadTimeout);
}
Status = NtSetInformationFile(hMailslot,
&Iosb,
&Buffer,
sizeof(FILE_MAILSLOT_SET_INFORMATION),
FileMailslotSetInformation);
if (!NT_SUCCESS(Status))
{
WARN("NtSetInformationFile failed (Status %x)!\n", Status);
BaseSetLastNTError (Status);
return(FALSE);
Buffer.ReadTimeout = &Timeout;
Status = NtSetInformationFile(hMailslot,
&Iosb,
&Buffer,
sizeof(FILE_MAILSLOT_SET_INFORMATION),
FileMailslotSetInformation);
if (!NT_SUCCESS(Status))
{
DPRINT1("NtSetInformationFile failed (Status %x)!\n", Status);
BaseSetLastNTError(Status);
return FALSE;
}
return(TRUE);
return TRUE;
}
/* EOF */

View file

@ -3554,8 +3554,18 @@ RtlEnlargedUnsignedMultiply(
Product.QuadPart = (ULONGLONG)Multiplicand * (ULONGLONG)Multiplier;
return Product;
}
#endif
NTSYSAPI
LARGE_INTEGER
NTAPI
RtlExtendedLargeIntegerDivide(
IN LARGE_INTEGER Dividend,
IN ULONG Divisor,
OUT PULONG Remainder OPTIONAL
);
NTSYSAPI
ULONG
NTAPI