/* * @implemented */ 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; Result = RtlDosPathNameToNtPathName_U(lpName, &MailslotName, NULL, NULL); if (!Result) { SetLastError(ERROR_PATH_NOT_FOUND); return INVALID_HANDLE_VALUE; } DPRINT("Mailslot name: %wZ\n", &MailslotName); if (lpSecurityAttributes) { SecurityDescriptor = lpSecurityAttributes->lpSecurityDescriptor; if(lpSecurityAttributes->bInheritHandle) Attributes |= OBJ_INHERIT; } InitializeObjectAttributes(&ObjectAttributes, &MailslotName, Attributes, NULL, SecurityDescriptor); if (lReadTimeout == MAILSLOT_WAIT_FOREVER) { /* Set the max */ DefaultTimeOut.QuadPart = 0xFFFFFFFFFFFFFFFFLL; } else { /* Convert to NT format */ DefaultTimeOut.QuadPart = lReadTimeout * -10000LL; } 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; } RtlFreeHeap(RtlGetProcessHeap(), 0, MailslotName.Buffer); if (!NT_SUCCESS(Status)) { DPRINT1("NtCreateMailslot failed (Status %x)!\n", Status); BaseSetLastNTError(Status); return INVALID_HANDLE_VALUE; } return MailslotHandle; }
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 = 0x7FFFFFFF; 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; }