char* GetNamedPipeUnixDomainSocketFilePathA(LPCSTR lpName) { char* lpPipePath; char* lpFileName; char* lpFilePath; lpPipePath = GetNamedPipeUnixDomainSocketBaseFilePathA(); lpFileName = GetNamedPipeNameWithoutPrefixA(lpName); lpFilePath = GetCombinedPath(lpPipePath, (char*) lpFileName); free(lpPipePath); free(lpFileName); return lpFilePath; }
HANDLE CreateNamedPipeA(LPCSTR lpName, DWORD dwOpenMode, DWORD dwPipeMode, DWORD nMaxInstances, DWORD nOutBufferSize, DWORD nInBufferSize, DWORD nDefaultTimeOut, LPSECURITY_ATTRIBUTES lpSecurityAttributes) { int index; HANDLE hNamedPipe = INVALID_HANDLE_VALUE; char* lpPipePath; struct sockaddr_un s; WINPR_NAMED_PIPE* pNamedPipe = NULL; int serverfd = -1; NamedPipeServerSocketEntry* baseSocket = NULL; if (!lpName) return INVALID_HANDLE_VALUE; InitWinPRPipeModule(); pNamedPipe = (WINPR_NAMED_PIPE*) calloc(1, sizeof(WINPR_NAMED_PIPE)); if (!pNamedPipe) return INVALID_HANDLE_VALUE; WINPR_HANDLE_SET_TYPE(pNamedPipe, HANDLE_TYPE_NAMED_PIPE); if (!(pNamedPipe->name = _strdup(lpName))) goto out; if (!(pNamedPipe->lpFileName = GetNamedPipeNameWithoutPrefixA(lpName))) goto out; if (!(pNamedPipe->lpFilePath = GetNamedPipeUnixDomainSocketFilePathA(lpName))) goto out; pNamedPipe->dwOpenMode = dwOpenMode; pNamedPipe->dwPipeMode = dwPipeMode; pNamedPipe->nMaxInstances = nMaxInstances; pNamedPipe->nOutBufferSize = nOutBufferSize; pNamedPipe->nInBufferSize = nInBufferSize; pNamedPipe->nDefaultTimeOut = nDefaultTimeOut; pNamedPipe->dwFlagsAndAttributes = dwOpenMode; pNamedPipe->clientfd = -1; pNamedPipe->ServerMode = TRUE; ArrayList_Lock(g_NamedPipeServerSockets); for (index = 0; index < ArrayList_Count(g_NamedPipeServerSockets); index++) { baseSocket = (NamedPipeServerSocketEntry*) ArrayList_GetItem( g_NamedPipeServerSockets, index); if (!strcmp(baseSocket->name, lpName)) { serverfd = baseSocket->serverfd; //WLog_DBG(TAG, "using shared socked resource for pipe %p (%s)", pNamedPipe, lpName); break; } } /* If this is the first instance of the named pipe... */ if (serverfd == -1) { /* Create the UNIX domain socket and start listening. */ if (!(lpPipePath = GetNamedPipeUnixDomainSocketBaseFilePathA())) goto out; if (!PathFileExistsA(lpPipePath)) { CreateDirectoryA(lpPipePath, 0); UnixChangeFileMode(lpPipePath, 0xFFFF); } free(lpPipePath); if (PathFileExistsA(pNamedPipe->lpFilePath)) { DeleteFileA(pNamedPipe->lpFilePath); } if ((serverfd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { WLog_ERR(TAG, "CreateNamedPipeA: socket error, %s", strerror(errno)); goto out; } ZeroMemory(&s, sizeof(struct sockaddr_un)); s.sun_family = AF_UNIX; strcpy(s.sun_path, pNamedPipe->lpFilePath); if (bind(serverfd, (struct sockaddr*) &s, sizeof(struct sockaddr_un)) == -1) { WLog_ERR(TAG, "CreateNamedPipeA: bind error, %s", strerror(errno)); goto out; } if (listen(serverfd, 2) == -1) { WLog_ERR(TAG, "CreateNamedPipeA: listen error, %s", strerror(errno)); goto out; } UnixChangeFileMode(pNamedPipe->lpFilePath, 0xFFFF); if (!(baseSocket = (NamedPipeServerSocketEntry*) malloc(sizeof(NamedPipeServerSocketEntry)))) goto out; if (!(baseSocket->name = _strdup(lpName))) { free(baseSocket); goto out; } baseSocket->serverfd = serverfd; baseSocket->references = 0; ArrayList_Add(g_NamedPipeServerSockets, baseSocket); //WLog_DBG(TAG, "created shared socked resource for pipe %p (%s). base serverfd = %d", pNamedPipe, lpName, serverfd); } pNamedPipe->serverfd = dup(baseSocket->serverfd); //WLog_DBG(TAG, "using serverfd %d (duplicated from %d)", pNamedPipe->serverfd, baseSocket->serverfd); pNamedPipe->pfnUnrefNamedPipe = winpr_unref_named_pipe; baseSocket->references++; if (dwOpenMode & FILE_FLAG_OVERLAPPED) { #if 0 int flags = fcntl(pNamedPipe->serverfd, F_GETFL); if (flags != -1) fcntl(pNamedPipe->serverfd, F_SETFL, flags | O_NONBLOCK); #endif } hNamedPipe = (HANDLE) pNamedPipe; out: if (hNamedPipe == INVALID_HANDLE_VALUE) { if (pNamedPipe) { free((void*)pNamedPipe->name); free((void*)pNamedPipe->lpFileName); free((void*)pNamedPipe->lpFilePath); free(pNamedPipe); } if (serverfd != -1) close(serverfd); } ArrayList_Unlock(g_NamedPipeServerSockets); return hNamedPipe; }
HANDLE CreateNamedPipeA(LPCSTR lpName, DWORD dwOpenMode, DWORD dwPipeMode, DWORD nMaxInstances, DWORD nOutBufferSize, DWORD nInBufferSize, DWORD nDefaultTimeOut, LPSECURITY_ATTRIBUTES lpSecurityAttributes) { int status; HANDLE hNamedPipe; char* lpPipePath; unsigned long flags; struct sockaddr_un s; WINPR_NAMED_PIPE* pNamedPipe; if (!lpName) return INVALID_HANDLE_VALUE; pNamedPipe = (WINPR_NAMED_PIPE*) malloc(sizeof(WINPR_NAMED_PIPE)); hNamedPipe = (HANDLE) pNamedPipe; WINPR_HANDLE_SET_TYPE(pNamedPipe, HANDLE_TYPE_NAMED_PIPE); pNamedPipe->name = _strdup(lpName); pNamedPipe->dwOpenMode = dwOpenMode; pNamedPipe->dwPipeMode = dwPipeMode; pNamedPipe->nMaxInstances = nMaxInstances; pNamedPipe->nOutBufferSize = nOutBufferSize; pNamedPipe->nInBufferSize = nInBufferSize; pNamedPipe->nDefaultTimeOut = nDefaultTimeOut; pNamedPipe->dwFlagsAndAttributes = dwOpenMode; pNamedPipe->lpFileName = GetNamedPipeNameWithoutPrefixA(lpName); pNamedPipe->lpFilePath = GetNamedPipeUnixDomainSocketFilePathA(lpName); lpPipePath = GetNamedPipeUnixDomainSocketBaseFilePathA(); if (!PathFileExistsA(lpPipePath)) CreateDirectoryA(lpPipePath, 0); free(lpPipePath); pNamedPipe->clientfd = -1; pNamedPipe->serverfd = socket(PF_LOCAL, SOCK_STREAM, 0); if (0) { flags = fcntl(pNamedPipe->serverfd, F_GETFL); flags = flags | O_NONBLOCK; fcntl(pNamedPipe->serverfd, F_SETFL, flags); } ZeroMemory(&s, sizeof(struct sockaddr_un)); s.sun_family = AF_UNIX; strcpy(s.sun_path, pNamedPipe->lpFilePath); unlink(s.sun_path); status = bind(pNamedPipe->serverfd, (struct sockaddr*) &s, sizeof(struct sockaddr_un)); if (status == 0) { status = listen(pNamedPipe->serverfd, 2); if (status == 0) { UnixChangeFileMode(pNamedPipe->lpFilePath, 0xFFFF); } } return hNamedPipe; }