123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315 |
- /**
- * WinPR: Windows Portable Runtime
- * File Functions
- *
- * Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
- * Copyright 2014 Hewlett-Packard Development Company, L.P.
- * Copyright 2015 Thincast Technologies GmbH
- * Copyright 2015 bernhard.miklautz@thincast.com
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- #ifdef HAVE_CONFIG_H
- #include "config.h"
- #endif
- #include <winpr/crt.h>
- #include <winpr/path.h>
- #include <winpr/file.h>
- #ifdef HAVE_UNISTD_H
- #include <unistd.h>
- #endif
- #include "../log.h"
- #define TAG WINPR_TAG("file")
- #ifndef _WIN32
- #ifdef ANDROID
- #include <sys/vfs.h>
- #else
- #include <sys/statvfs.h>
- #endif
- #include "../handle/handle.h"
- #include "../pipe/pipe.h"
- static HANDLE_CREATOR _NamedPipeClientHandleCreator;
- static BOOL NamedPipeClientIsHandled(HANDLE handle)
- {
- WINPR_NAMED_PIPE* pFile = (WINPR_NAMED_PIPE*)handle;
- if (!pFile || (pFile->Type != HANDLE_TYPE_NAMED_PIPE) || (pFile == INVALID_HANDLE_VALUE))
- {
- SetLastError(ERROR_INVALID_HANDLE);
- return FALSE;
- }
- return TRUE;
- }
- static BOOL NamedPipeClientCloseHandle(HANDLE handle)
- {
- WINPR_NAMED_PIPE* pNamedPipe = (WINPR_NAMED_PIPE*)handle;
- if (!NamedPipeClientIsHandled(handle))
- return FALSE;
- if (pNamedPipe->clientfd != -1)
- {
- // WLOG_DBG(TAG, "closing clientfd %d", pNamedPipe->clientfd);
- close(pNamedPipe->clientfd);
- }
- if (pNamedPipe->serverfd != -1)
- {
- // WLOG_DBG(TAG, "closing serverfd %d", pNamedPipe->serverfd);
- close(pNamedPipe->serverfd);
- }
- if (pNamedPipe->pfnUnrefNamedPipe)
- pNamedPipe->pfnUnrefNamedPipe(pNamedPipe);
- free(pNamedPipe->lpFileName);
- free(pNamedPipe->lpFilePath);
- free(pNamedPipe->name);
- free(pNamedPipe);
- return TRUE;
- }
- static int NamedPipeClientGetFd(HANDLE handle)
- {
- WINPR_NAMED_PIPE* file = (WINPR_NAMED_PIPE*)handle;
- if (!NamedPipeClientIsHandled(handle))
- return -1;
- if (file->ServerMode)
- return file->serverfd;
- else
- return file->clientfd;
- }
- static HANDLE_OPS ops = {
- NamedPipeClientIsHandled,
- NamedPipeClientCloseHandle,
- NamedPipeClientGetFd,
- NULL, /* CleanupHandle */
- NamedPipeRead,
- NULL, /* FileReadEx */
- NULL, /* FileReadScatter */
- NamedPipeWrite,
- NULL, /* FileWriteEx */
- NULL, /* FileWriteGather */
- NULL, /* FileGetFileSize */
- NULL, /* FlushFileBuffers */
- NULL, /* FileSetEndOfFile */
- NULL, /* FileSetFilePointer */
- NULL, /* SetFilePointerEx */
- NULL, /* FileLockFile */
- NULL, /* FileLockFileEx */
- NULL, /* FileUnlockFile */
- NULL, /* FileUnlockFileEx */
- NULL /* SetFileTime */
- };
- static HANDLE NamedPipeClientCreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess,
- DWORD dwShareMode,
- LPSECURITY_ATTRIBUTES lpSecurityAttributes,
- DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes,
- HANDLE hTemplateFile)
- {
- char* name;
- int status;
- HANDLE hNamedPipe;
- struct sockaddr_un s;
- WINPR_NAMED_PIPE* pNamedPipe;
- if (dwFlagsAndAttributes & FILE_FLAG_OVERLAPPED)
- {
- WLog_ERR(TAG, "WinPR %s does not support the FILE_FLAG_OVERLAPPED flag", __FUNCTION__);
- SetLastError(ERROR_NOT_SUPPORTED);
- return INVALID_HANDLE_VALUE;
- }
- if (!lpFileName)
- return INVALID_HANDLE_VALUE;
- if (!IsNamedPipeFileNameA(lpFileName))
- return INVALID_HANDLE_VALUE;
- name = GetNamedPipeNameWithoutPrefixA(lpFileName);
- if (!name)
- return INVALID_HANDLE_VALUE;
- free(name);
- pNamedPipe = (WINPR_NAMED_PIPE*)calloc(1, sizeof(WINPR_NAMED_PIPE));
- if (!pNamedPipe)
- {
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
- return INVALID_HANDLE_VALUE;
- }
- hNamedPipe = (HANDLE)pNamedPipe;
- WINPR_HANDLE_SET_TYPE_AND_MODE(pNamedPipe, HANDLE_TYPE_NAMED_PIPE, WINPR_FD_READ);
- pNamedPipe->name = _strdup(lpFileName);
- if (!pNamedPipe->name)
- {
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
- free(pNamedPipe);
- return INVALID_HANDLE_VALUE;
- }
- pNamedPipe->dwOpenMode = 0;
- pNamedPipe->dwPipeMode = 0;
- pNamedPipe->nMaxInstances = 0;
- pNamedPipe->nOutBufferSize = 0;
- pNamedPipe->nInBufferSize = 0;
- pNamedPipe->nDefaultTimeOut = 0;
- pNamedPipe->dwFlagsAndAttributes = dwFlagsAndAttributes;
- pNamedPipe->lpFileName = GetNamedPipeNameWithoutPrefixA(lpFileName);
- if (!pNamedPipe->lpFileName)
- {
- free((void*)pNamedPipe->name);
- free(pNamedPipe);
- return INVALID_HANDLE_VALUE;
- }
- pNamedPipe->lpFilePath = GetNamedPipeUnixDomainSocketFilePathA(lpFileName);
- if (!pNamedPipe->lpFilePath)
- {
- free((void*)pNamedPipe->lpFileName);
- free((void*)pNamedPipe->name);
- free(pNamedPipe);
- return INVALID_HANDLE_VALUE;
- }
- pNamedPipe->clientfd = socket(PF_LOCAL, SOCK_STREAM, 0);
- pNamedPipe->serverfd = -1;
- pNamedPipe->ServerMode = FALSE;
- ZeroMemory(&s, sizeof(struct sockaddr_un));
- s.sun_family = AF_UNIX;
- sprintf_s(s.sun_path, ARRAYSIZE(s.sun_path), "%s", pNamedPipe->lpFilePath);
- status = connect(pNamedPipe->clientfd, (struct sockaddr*)&s, sizeof(struct sockaddr_un));
- pNamedPipe->ops = &ops;
- if (status != 0)
- {
- close(pNamedPipe->clientfd);
- free((char*)pNamedPipe->name);
- free((char*)pNamedPipe->lpFileName);
- free((char*)pNamedPipe->lpFilePath);
- free(pNamedPipe);
- return INVALID_HANDLE_VALUE;
- }
- if (dwFlagsAndAttributes & FILE_FLAG_OVERLAPPED)
- {
- #if 0
- int flags = fcntl(pNamedPipe->clientfd, F_GETFL);
- if (flags != -1)
- fcntl(pNamedPipe->clientfd, F_SETFL, flags | O_NONBLOCK);
- #endif
- }
- return hNamedPipe;
- }
- HANDLE_CREATOR* GetNamedPipeClientHandleCreator(void)
- {
- _NamedPipeClientHandleCreator.IsHandled = IsNamedPipeFileNameA;
- _NamedPipeClientHandleCreator.CreateFileA = NamedPipeClientCreateFileA;
- return &_NamedPipeClientHandleCreator;
- }
- #endif
- /* Extended API */
- #define NAMED_PIPE_PREFIX_PATH "\\\\.\\pipe\\"
- BOOL IsNamedPipeFileNameA(LPCSTR lpName)
- {
- if (strncmp(lpName, NAMED_PIPE_PREFIX_PATH, sizeof(NAMED_PIPE_PREFIX_PATH) - 1) != 0)
- return FALSE;
- return TRUE;
- }
- char* GetNamedPipeNameWithoutPrefixA(LPCSTR lpName)
- {
- char* lpFileName;
- if (!lpName)
- return NULL;
- if (!IsNamedPipeFileNameA(lpName))
- return NULL;
- lpFileName = _strdup(&lpName[strnlen(NAMED_PIPE_PREFIX_PATH, sizeof(NAMED_PIPE_PREFIX_PATH))]);
- return lpFileName;
- }
- char* GetNamedPipeUnixDomainSocketBaseFilePathA()
- {
- char* lpTempPath;
- char* lpPipePath;
- lpTempPath = GetKnownPath(KNOWN_PATH_TEMP);
- if (!lpTempPath)
- return NULL;
- lpPipePath = GetCombinedPath(lpTempPath, ".pipe");
- free(lpTempPath);
- return lpPipePath;
- }
- 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;
- }
- int GetNamePipeFileDescriptor(HANDLE hNamedPipe)
- {
- #ifndef _WIN32
- int fd;
- WINPR_NAMED_PIPE* pNamedPipe;
- pNamedPipe = (WINPR_NAMED_PIPE*)hNamedPipe;
- if (!pNamedPipe || pNamedPipe->Type != HANDLE_TYPE_NAMED_PIPE)
- return -1;
- fd = (pNamedPipe->ServerMode) ? pNamedPipe->serverfd : pNamedPipe->clientfd;
- return fd;
- #else
- return -1;
- #endif
- }
|