22 #include <winpr/config.h>
24 #include <winpr/crt.h>
25 #include <winpr/path.h>
26 #include <winpr/file.h>
28 #ifdef WINPR_HAVE_UNISTD_H
33 #define TAG WINPR_TAG("file")
40 #include <sys/statvfs.h>
43 #include "../handle/handle.h"
45 #include "../pipe/pipe.h"
46 #include "namedPipeClient.h"
48 static BOOL NamedPipeClientIsHandled(HANDLE handle)
50 return WINPR_HANDLE_IS_HANDLED(handle, HANDLE_TYPE_NAMED_PIPE, TRUE);
53 static BOOL NamedPipeClientCloseHandle(HANDLE handle)
55 WINPR_NAMED_PIPE* pNamedPipe = (WINPR_NAMED_PIPE*)handle;
57 if (!NamedPipeClientIsHandled(handle))
60 if (pNamedPipe->clientfd != -1)
63 close(pNamedPipe->clientfd);
66 if (pNamedPipe->serverfd != -1)
69 close(pNamedPipe->serverfd);
72 if (pNamedPipe->pfnUnrefNamedPipe)
73 pNamedPipe->pfnUnrefNamedPipe(pNamedPipe);
75 free(pNamedPipe->lpFileName);
76 free(pNamedPipe->lpFilePath);
77 free(pNamedPipe->name);
82 static int NamedPipeClientGetFd(HANDLE handle)
84 WINPR_NAMED_PIPE* file = (WINPR_NAMED_PIPE*)handle;
86 if (!NamedPipeClientIsHandled(handle))
90 return file->serverfd;
92 return file->clientfd;
96 NamedPipeClientIsHandled,
97 NamedPipeClientCloseHandle,
119 static HANDLE NamedPipeClientCreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess,
121 LPSECURITY_ATTRIBUTES lpSecurityAttributes,
122 DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes,
123 HANDLE hTemplateFile)
126 struct sockaddr_un s = { 0 };
128 if (dwFlagsAndAttributes & FILE_FLAG_OVERLAPPED)
130 WLog_ERR(TAG,
"WinPR does not support the FILE_FLAG_OVERLAPPED flag");
131 SetLastError(ERROR_NOT_SUPPORTED);
132 return INVALID_HANDLE_VALUE;
136 return INVALID_HANDLE_VALUE;
138 if (!IsNamedPipeFileNameA(lpFileName))
139 return INVALID_HANDLE_VALUE;
141 WINPR_NAMED_PIPE* pNamedPipe = (WINPR_NAMED_PIPE*)calloc(1,
sizeof(WINPR_NAMED_PIPE));
145 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
146 return INVALID_HANDLE_VALUE;
149 HANDLE hNamedPipe = (HANDLE)pNamedPipe;
150 WINPR_HANDLE_SET_TYPE_AND_MODE(pNamedPipe, HANDLE_TYPE_NAMED_PIPE, WINPR_FD_READ);
151 pNamedPipe->name = _strdup(lpFileName);
153 if (!pNamedPipe->name)
155 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
159 pNamedPipe->dwOpenMode = 0;
160 pNamedPipe->dwPipeMode = 0;
161 pNamedPipe->nMaxInstances = 0;
162 pNamedPipe->nOutBufferSize = 0;
163 pNamedPipe->nInBufferSize = 0;
164 pNamedPipe->nDefaultTimeOut = 0;
165 pNamedPipe->dwFlagsAndAttributes = dwFlagsAndAttributes;
166 pNamedPipe->lpFileName = GetNamedPipeNameWithoutPrefixA(lpFileName);
168 if (!pNamedPipe->lpFileName)
171 pNamedPipe->lpFilePath = GetNamedPipeUnixDomainSocketFilePathA(lpFileName);
173 if (!pNamedPipe->lpFilePath)
176 pNamedPipe->clientfd = socket(PF_LOCAL, SOCK_STREAM, 0);
177 if (pNamedPipe->clientfd < 0)
180 pNamedPipe->serverfd = -1;
181 pNamedPipe->ServerMode = FALSE;
182 s.sun_family = AF_UNIX;
183 (void)sprintf_s(s.sun_path, ARRAYSIZE(s.sun_path),
"%s", pNamedPipe->lpFilePath);
184 status = connect(pNamedPipe->clientfd, (
struct sockaddr*)&s,
sizeof(
struct sockaddr_un));
185 pNamedPipe->common.ops = &ops;
190 if (dwFlagsAndAttributes & FILE_FLAG_OVERLAPPED)
193 int flags = fcntl(pNamedPipe->clientfd, F_GETFL);
196 (void)fcntl(pNamedPipe->clientfd, F_SETFL, flags | O_NONBLOCK);
206 if (pNamedPipe->clientfd >= 0)
207 close(pNamedPipe->clientfd);
208 free(pNamedPipe->name);
209 free(pNamedPipe->lpFileName);
210 free(pNamedPipe->lpFilePath);
213 return INVALID_HANDLE_VALUE;
218 static const HANDLE_CREATOR NamedPipeClientHandleCreator = { .IsHandled = IsNamedPipeFileNameA,
220 NamedPipeClientCreateFileA };
221 return &NamedPipeClientHandleCreator;
228 #define NAMED_PIPE_PREFIX_PATH "\\\\.\\pipe\\"
230 BOOL IsNamedPipeFileNameA(LPCSTR lpName)
232 if (strncmp(lpName, NAMED_PIPE_PREFIX_PATH,
sizeof(NAMED_PIPE_PREFIX_PATH) - 1) != 0)
238 char* GetNamedPipeNameWithoutPrefixA(LPCSTR lpName)
240 char* lpFileName = NULL;
245 if (!IsNamedPipeFileNameA(lpName))
248 lpFileName = _strdup(&lpName[strnlen(NAMED_PIPE_PREFIX_PATH,
sizeof(NAMED_PIPE_PREFIX_PATH))]);
252 char* GetNamedPipeUnixDomainSocketBaseFilePathA(
void)
254 char* lpTempPath = NULL;
255 char* lpPipePath = NULL;
256 lpTempPath = GetKnownPath(KNOWN_PATH_TEMP);
261 lpPipePath = GetCombinedPath(lpTempPath,
".pipe");
266 char* GetNamedPipeUnixDomainSocketFilePathA(LPCSTR lpName)
268 char* lpPipePath = NULL;
269 char* lpFileName = NULL;
270 char* lpFilePath = NULL;
271 lpPipePath = GetNamedPipeUnixDomainSocketBaseFilePathA();
272 lpFileName = GetNamedPipeNameWithoutPrefixA(lpName);
273 lpFilePath = GetCombinedPath(lpPipePath, lpFileName);
279 int GetNamePipeFileDescriptor(HANDLE hNamedPipe)
283 WINPR_NAMED_PIPE* pNamedPipe = (WINPR_NAMED_PIPE*)hNamedPipe;
285 if (!NamedPipeClientIsHandled(hNamedPipe))
288 fd = (pNamedPipe->ServerMode) ? pNamedPipe->serverfd : pNamedPipe->clientfd;