22#include <winpr/config.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"
48static BOOL NamedPipeClientIsHandled(HANDLE handle)
50 return WINPR_HANDLE_IS_HANDLED(handle, HANDLE_TYPE_NAMED_PIPE, TRUE);
53static 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);
82static 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,
120NamedPipeClientCreateFileA(LPCSTR lpFileName, WINPR_ATTR_UNUSED DWORD dwDesiredAccess,
121 WINPR_ATTR_UNUSED DWORD dwShareMode,
122 WINPR_ATTR_UNUSED LPSECURITY_ATTRIBUTES lpSecurityAttributes,
123 WINPR_ATTR_UNUSED DWORD dwCreationDisposition,
124 DWORD dwFlagsAndAttributes, WINPR_ATTR_UNUSED HANDLE hTemplateFile)
127 struct sockaddr_un s = { 0 };
129 if (dwFlagsAndAttributes & FILE_FLAG_OVERLAPPED)
131 WLog_ERR(TAG,
"WinPR does not support the FILE_FLAG_OVERLAPPED flag");
132 SetLastError(ERROR_NOT_SUPPORTED);
133 return INVALID_HANDLE_VALUE;
137 return INVALID_HANDLE_VALUE;
139 if (!IsNamedPipeFileNameA(lpFileName))
140 return INVALID_HANDLE_VALUE;
142 WINPR_NAMED_PIPE* pNamedPipe = (WINPR_NAMED_PIPE*)calloc(1,
sizeof(WINPR_NAMED_PIPE));
146 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
147 return INVALID_HANDLE_VALUE;
150 HANDLE hNamedPipe = (HANDLE)pNamedPipe;
151 WINPR_HANDLE_SET_TYPE_AND_MODE(pNamedPipe, HANDLE_TYPE_NAMED_PIPE, WINPR_FD_READ);
152 pNamedPipe->name = _strdup(lpFileName);
154 if (!pNamedPipe->name)
156 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
160 pNamedPipe->dwOpenMode = 0;
161 pNamedPipe->dwPipeMode = 0;
162 pNamedPipe->nMaxInstances = 0;
163 pNamedPipe->nOutBufferSize = 0;
164 pNamedPipe->nInBufferSize = 0;
165 pNamedPipe->nDefaultTimeOut = 0;
166 pNamedPipe->dwFlagsAndAttributes = dwFlagsAndAttributes;
167 pNamedPipe->lpFileName = GetNamedPipeNameWithoutPrefixA(lpFileName);
169 if (!pNamedPipe->lpFileName)
172 pNamedPipe->lpFilePath = GetNamedPipeUnixDomainSocketFilePathA(lpFileName);
174 if (!pNamedPipe->lpFilePath)
177 pNamedPipe->clientfd = socket(PF_LOCAL, SOCK_STREAM, 0);
178 if (pNamedPipe->clientfd < 0)
181 pNamedPipe->serverfd = -1;
182 pNamedPipe->ServerMode = FALSE;
183 s.sun_family = AF_UNIX;
184 (void)sprintf_s(s.sun_path, ARRAYSIZE(s.sun_path),
"%s", pNamedPipe->lpFilePath);
185 status = connect(pNamedPipe->clientfd, (
struct sockaddr*)&s,
sizeof(
struct sockaddr_un));
186 pNamedPipe->common.ops = &ops;
191 if (dwFlagsAndAttributes & FILE_FLAG_OVERLAPPED)
194 WLog_ERR(TAG,
"TODO: implement this");
202 if (pNamedPipe->clientfd >= 0)
203 close(pNamedPipe->clientfd);
204 free(pNamedPipe->name);
205 free(pNamedPipe->lpFileName);
206 free(pNamedPipe->lpFilePath);
209 return INVALID_HANDLE_VALUE;
214 static const HANDLE_CREATOR NamedPipeClientHandleCreator = { .IsHandled = IsNamedPipeFileNameA,
216 NamedPipeClientCreateFileA };
217 return &NamedPipeClientHandleCreator;
224#define NAMED_PIPE_PREFIX_PATH "\\\\.\\pipe\\"
226BOOL IsNamedPipeFileNameA(LPCSTR lpName)
228 if (strncmp(lpName, NAMED_PIPE_PREFIX_PATH,
sizeof(NAMED_PIPE_PREFIX_PATH) - 1) != 0)
234char* GetNamedPipeNameWithoutPrefixA(LPCSTR lpName)
236 char* lpFileName = NULL;
241 if (!IsNamedPipeFileNameA(lpName))
244 lpFileName = _strdup(&lpName[strnlen(NAMED_PIPE_PREFIX_PATH,
sizeof(NAMED_PIPE_PREFIX_PATH))]);
248char* GetNamedPipeUnixDomainSocketBaseFilePathA(
void)
250 char* lpTempPath = NULL;
251 char* lpPipePath = NULL;
252 lpTempPath = GetKnownPath(KNOWN_PATH_TEMP);
257 lpPipePath = GetCombinedPath(lpTempPath,
".pipe");
262char* GetNamedPipeUnixDomainSocketFilePathA(LPCSTR lpName)
264 char* lpPipePath = NULL;
265 char* lpFileName = NULL;
266 char* lpFilePath = NULL;
267 lpPipePath = GetNamedPipeUnixDomainSocketBaseFilePathA();
268 lpFileName = GetNamedPipeNameWithoutPrefixA(lpName);
269 lpFilePath = GetCombinedPath(lpPipePath, lpFileName);
275int GetNamePipeFileDescriptor(HANDLE hNamedPipe)
279 WINPR_NAMED_PIPE* pNamedPipe = (WINPR_NAMED_PIPE*)hNamedPipe;
281 if (!NamedPipeClientIsHandled(hNamedPipe))
284 fd = (pNamedPipe->ServerMode) ? pNamedPipe->serverfd : pNamedPipe->clientfd;