1 /*
2  * COPYRIGHT:       See COPYING in the top level directory
3  * PROJECT:         ReactOS system libraries
4  * FILE:            dll/win32/kernel32/client/file/mailslot.c
5  * PURPOSE:         Mailslot functions
6  * PROGRAMMER:      Ariadne ( ariadne@xs4all.nl)
7  * UPDATE HISTORY:
8  */
9 
10 /* INCLUDES *******************************************************************/
11 
12 #include <k32.h>
13 #define NDEBUG
14 #include <debug.h>
15 
16 /* FUNCTIONS ******************************************************************/
17 
18 /*
19  * @implemented
20  */
21 HANDLE
22 WINAPI
CreateMailslotA(IN LPCSTR lpName,IN DWORD nMaxMessageSize,IN DWORD lReadTimeout,IN LPSECURITY_ATTRIBUTES lpSecurityAttributes)23 CreateMailslotA(IN LPCSTR lpName,
24                 IN DWORD nMaxMessageSize,
25                 IN DWORD lReadTimeout,
26                 IN LPSECURITY_ATTRIBUTES lpSecurityAttributes)
27 {
28     /* Call the W(ide) function */
29     ConvertWin32AnsiObjectApiToUnicodeApi2(Mailslot, lpName, nMaxMessageSize, lReadTimeout, lpSecurityAttributes);
30 }
31 
32 /*
33  * @implemented
34  */
35 HANDLE
36 WINAPI
CreateMailslotW(IN LPCWSTR lpName,IN DWORD nMaxMessageSize,IN DWORD lReadTimeout,IN LPSECURITY_ATTRIBUTES lpSecurityAttributes)37 CreateMailslotW(IN LPCWSTR lpName,
38                 IN DWORD nMaxMessageSize,
39                 IN DWORD lReadTimeout,
40                 IN LPSECURITY_ATTRIBUTES lpSecurityAttributes)
41 {
42     OBJECT_ATTRIBUTES ObjectAttributes;
43     UNICODE_STRING MailslotName;
44     HANDLE MailslotHandle;
45     NTSTATUS Status;
46     BOOLEAN Result;
47     LARGE_INTEGER DefaultTimeOut;
48     IO_STATUS_BLOCK Iosb;
49     ULONG Attributes = OBJ_CASE_INSENSITIVE;
50     PSECURITY_DESCRIPTOR SecurityDescriptor = NULL;
51 
52     Result = RtlDosPathNameToNtPathName_U(lpName, &MailslotName, NULL, NULL);
53     if (!Result)
54     {
55         SetLastError(ERROR_PATH_NOT_FOUND);
56         return INVALID_HANDLE_VALUE;
57     }
58 
59     DPRINT("Mailslot name: %wZ\n", &MailslotName);
60 
61     if (lpSecurityAttributes)
62     {
63         SecurityDescriptor = lpSecurityAttributes->lpSecurityDescriptor;
64         if(lpSecurityAttributes->bInheritHandle) Attributes |= OBJ_INHERIT;
65     }
66 
67     InitializeObjectAttributes(&ObjectAttributes,
68                                &MailslotName,
69                                Attributes,
70                                NULL,
71                                SecurityDescriptor);
72 
73     if (lReadTimeout == MAILSLOT_WAIT_FOREVER)
74     {
75         /* Set the max */
76         DefaultTimeOut.QuadPart = 0xFFFFFFFFFFFFFFFFLL;
77     }
78     else
79     {
80         /* Convert to NT format */
81         DefaultTimeOut.QuadPart = lReadTimeout * -10000LL;
82     }
83 
84     Status = NtCreateMailslotFile(&MailslotHandle,
85                                   GENERIC_READ | SYNCHRONIZE | WRITE_DAC,
86                                   &ObjectAttributes,
87                                   &Iosb,
88                                   FILE_WRITE_THROUGH,
89                                   0,
90                                   nMaxMessageSize,
91                                   &DefaultTimeOut);
92 
93     if ((Status == STATUS_INVALID_DEVICE_REQUEST) ||
94         (Status == STATUS_NOT_SUPPORTED))
95     {
96         Status = STATUS_OBJECT_NAME_INVALID;
97     }
98 
99     RtlFreeHeap(RtlGetProcessHeap(), 0, MailslotName.Buffer);
100 
101     if (!NT_SUCCESS(Status))
102     {
103         DPRINT1("NtCreateMailslot failed (Status %x)!\n", Status);
104         BaseSetLastNTError(Status);
105         return INVALID_HANDLE_VALUE;
106     }
107 
108     return MailslotHandle;
109 }
110 
111 /*
112  * @implemented
113  */
114 BOOL
115 WINAPI
GetMailslotInfo(IN HANDLE hMailslot,IN LPDWORD lpMaxMessageSize,IN LPDWORD lpNextSize,IN LPDWORD lpMessageCount,IN LPDWORD lpReadTimeout)116 GetMailslotInfo(IN HANDLE hMailslot,
117                 IN LPDWORD lpMaxMessageSize,
118                 IN LPDWORD lpNextSize,
119                 IN LPDWORD lpMessageCount,
120                 IN LPDWORD lpReadTimeout)
121 {
122     FILE_MAILSLOT_QUERY_INFORMATION Buffer;
123     IO_STATUS_BLOCK Iosb;
124     NTSTATUS Status;
125     LARGE_INTEGER Timeout;
126 
127     Status = NtQueryInformationFile(hMailslot,
128                                     &Iosb,
129                                     &Buffer,
130                                     sizeof(FILE_MAILSLOT_QUERY_INFORMATION),
131                                     FileMailslotQueryInformation);
132     if (!NT_SUCCESS(Status))
133     {
134         DPRINT1("NtQueryInformationFile failed (Status %x)!\n", Status);
135         BaseSetLastNTError(Status);
136         return FALSE;
137      }
138 
139      if (lpMaxMessageSize) *lpMaxMessageSize = Buffer.MaximumMessageSize;
140      if (lpNextSize) *lpNextSize = Buffer.NextMessageSize;
141      if (lpMessageCount) *lpMessageCount = Buffer.MessagesAvailable;
142 
143      if (lpReadTimeout)
144      {
145          if (Buffer.ReadTimeout.QuadPart == 0xFFFFFFFFFFFFFFFFLL)
146          {
147              *lpReadTimeout = MAILSLOT_WAIT_FOREVER;
148          }
149          else
150          {
151              Timeout.QuadPart = -Buffer.ReadTimeout.QuadPart;
152              Timeout = RtlExtendedLargeIntegerDivide(Timeout, 10000, NULL);
153              if (Timeout.HighPart == 0)
154              {
155                  *lpReadTimeout = Timeout.LowPart;
156              }
157              else
158              {
159                  *lpReadTimeout = 0xFFFFFFFE;
160              }
161          }
162      }
163 
164    return TRUE;
165 }
166 
167 /*
168  * @implemented
169  */
170 BOOL
171 WINAPI
SetMailslotInfo(IN HANDLE hMailslot,IN DWORD lReadTimeout)172 SetMailslotInfo(IN HANDLE hMailslot,
173                 IN DWORD lReadTimeout)
174 {
175     FILE_MAILSLOT_SET_INFORMATION Buffer;
176     LARGE_INTEGER Timeout;
177     IO_STATUS_BLOCK Iosb;
178     NTSTATUS Status;
179 
180     if (lReadTimeout == MAILSLOT_WAIT_FOREVER)
181     {
182         /* Set the max */
183         Timeout.QuadPart = 0xFFFFFFFFFFFFFFFFLL;
184     }
185     else
186     {
187         /* Convert to NT format */
188         Timeout.QuadPart = lReadTimeout * -10000LL;
189     }
190 
191     Buffer.ReadTimeout = &Timeout;
192 
193     Status = NtSetInformationFile(hMailslot,
194                                   &Iosb,
195                                   &Buffer,
196                                   sizeof(FILE_MAILSLOT_SET_INFORMATION),
197                                   FileMailslotSetInformation);
198     if (!NT_SUCCESS(Status))
199     {
200         DPRINT1("NtSetInformationFile failed (Status %x)!\n", Status);
201         BaseSetLastNTError(Status);
202         return FALSE;
203      }
204 
205      return TRUE;
206 }
207 
208 /* EOF */
209