Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
37b3881f06
@ -40,10 +40,6 @@ WINPR_API BOOL SetCurrentDirectoryW(LPCWSTR lpPathName);
|
||||
WINPR_API DWORD SearchPathA(LPCSTR lpPath, LPCSTR lpFileName, LPCSTR lpExtension, DWORD nBufferLength, LPSTR lpBuffer, LPSTR* lpFilePart);
|
||||
WINPR_API DWORD SearchPathW(LPCWSTR lpPath, LPCWSTR lpFileName, LPCWSTR lpExtension, DWORD nBufferLength, LPWSTR lpBuffer, LPWSTR* lpFilePart);
|
||||
|
||||
WINPR_API HANDLE GetStdHandle(DWORD nStdHandle);
|
||||
WINPR_API BOOL SetStdHandle(DWORD nStdHandle, HANDLE hHandle);
|
||||
WINPR_API BOOL SetStdHandleEx(DWORD dwStdHandle, HANDLE hNewHandle, HANDLE* phOldHandle);
|
||||
|
||||
WINPR_API LPSTR GetCommandLineA(VOID);
|
||||
WINPR_API LPWSTR GetCommandLineW(VOID);
|
||||
|
||||
|
@ -161,6 +161,10 @@
|
||||
#define FIND_FIRST_EX_CASE_SENSITIVE 0x1
|
||||
#define FIND_FIRST_EX_LARGE_FETCH 0x2
|
||||
|
||||
#define STD_INPUT_HANDLE (DWORD)-10
|
||||
#define STD_OUTPUT_HANDLE (DWORD)-11
|
||||
#define STD_ERROR_HANDLE (DWORD)-12
|
||||
|
||||
typedef union _FILE_SEGMENT_ELEMENT
|
||||
{
|
||||
PVOID64 Buffer;
|
||||
@ -294,6 +298,10 @@ WINPR_API BOOL CreateDirectoryW(LPCWSTR lpPathName, LPSECURITY_ATTRIBUTES lpSecu
|
||||
WINPR_API BOOL RemoveDirectoryA(LPCSTR lpPathName);
|
||||
WINPR_API BOOL RemoveDirectoryW(LPCWSTR lpPathName);
|
||||
|
||||
WINPR_API HANDLE GetStdHandle(DWORD nStdHandle);
|
||||
WINPR_API BOOL SetStdHandle(DWORD nStdHandle, HANDLE hHandle);
|
||||
WINPR_API BOOL SetStdHandleEx(DWORD dwStdHandle, HANDLE hNewHandle, HANDLE* phOldHandle);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@ -316,7 +324,6 @@ WINPR_API BOOL RemoveDirectoryW(LPCWSTR lpPathName);
|
||||
#define RemoveDirectory RemoveDirectoryA
|
||||
#endif
|
||||
|
||||
|
||||
/* Extra Functions */
|
||||
|
||||
typedef BOOL (*pcIsFileHandled)(LPCSTR lpFileName);
|
||||
@ -329,8 +336,6 @@ typedef struct _HANDLE_CREATOR
|
||||
pcCreateFileA CreateFileA;
|
||||
} HANDLE_CREATOR, *PHANDLE_CREATOR, *LPHANDLE_CREATOR;
|
||||
|
||||
BOOL RegisterHandleCreator(PHANDLE_CREATOR pHandleCreator);
|
||||
|
||||
#endif /* _WIN32 */
|
||||
|
||||
#define WILDCARD_STAR 0x00000001
|
||||
|
@ -262,6 +262,16 @@ typedef struct tagBITMAPFILEHEADER
|
||||
DWORD bfOffBits;
|
||||
} BITMAPFILEHEADER, FAR *LPBITMAPFILEHEADER, *PBITMAPFILEHEADER;
|
||||
|
||||
typedef enum _ORIENTATION_PREFERENCE
|
||||
{
|
||||
ORIENTATION_PREFERENCE_NONE = 0x0,
|
||||
ORIENTATION_PREFERENCE_LANDSCAPE = 0x1,
|
||||
|
||||
ORIENTATION_PREFERENCE_PORTRAIT = 0x2,
|
||||
ORIENTATION_PREFERENCE_LANDSCAPE_FLIPPED = 0x4,
|
||||
ORIENTATION_PREFERENCE_PORTRAIT_FLIPPED = 0x8
|
||||
} ORIENTATION_PREFERENCE;
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
#endif
|
||||
|
@ -71,7 +71,7 @@ typedef struct comm_device COMM_DEVICE;
|
||||
static COMM_DEVICE **_CommDevices = NULL;
|
||||
static CRITICAL_SECTION _CommDevicesLock;
|
||||
|
||||
static HANDLE_CREATOR *_CommHandleCreator = NULL;
|
||||
static HANDLE_CREATOR _CommHandleCreator;
|
||||
|
||||
static pthread_once_t _CommInitialized = PTHREAD_ONCE_INIT;
|
||||
|
||||
@ -85,14 +85,19 @@ static int CommGetFd(HANDLE handle)
|
||||
return comm->fd;
|
||||
}
|
||||
|
||||
static void _CommInit()
|
||||
HANDLE_CREATOR *GetCommHandleCreator(void)
|
||||
{
|
||||
_CommHandleCreator.IsHandled = IsCommDevice;
|
||||
_CommHandleCreator.CreateFileA = CommCreateFileA;
|
||||
return &_CommHandleCreator;
|
||||
}
|
||||
|
||||
static void _CommInit(void)
|
||||
{
|
||||
/* NB: error management to be done outside of this function */
|
||||
|
||||
assert(_Log == NULL);
|
||||
assert(_CommDevices == NULL);
|
||||
assert(_CommHandleCreator == NULL);
|
||||
|
||||
|
||||
_CommDevices = (COMM_DEVICE**)calloc(COMM_DEVICE_MAX+1, sizeof(COMM_DEVICE*));
|
||||
if (!_CommDevices)
|
||||
@ -105,32 +110,10 @@ static void _CommInit()
|
||||
return;
|
||||
}
|
||||
|
||||
_CommHandleCreator = (HANDLE_CREATOR*)malloc(sizeof(HANDLE_CREATOR));
|
||||
if (!_CommHandleCreator)
|
||||
{
|
||||
DeleteCriticalSection(&_CommDevicesLock);
|
||||
free(_CommDevices);
|
||||
_CommDevices = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
_CommHandleCreator->IsHandled = IsCommDevice;
|
||||
_CommHandleCreator->CreateFileA = CommCreateFileA;
|
||||
|
||||
if (!RegisterHandleCreator(_CommHandleCreator))
|
||||
{
|
||||
DeleteCriticalSection(&_CommDevicesLock);
|
||||
free(_CommDevices);
|
||||
free(_CommHandleCreator);
|
||||
_CommDevices = NULL;
|
||||
_CommHandleCreator = NULL;
|
||||
return;
|
||||
}
|
||||
_Log = WLog_Get("com.winpr.comm");
|
||||
assert(_Log != NULL);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns TRUE when the comm module is correctly intialized, FALSE otherwise
|
||||
* with ERROR_DLL_INIT_FAILED set as the last error.
|
||||
@ -143,12 +126,6 @@ static BOOL CommInitialized()
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (_CommHandleCreator == NULL)
|
||||
{
|
||||
SetLastError(ERROR_DLL_INIT_FAILED);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -111,21 +111,6 @@ DWORD SearchPathW(LPCWSTR lpPath, LPCWSTR lpFileName, LPCWSTR lpExtension, DWORD
|
||||
return 0;
|
||||
}
|
||||
|
||||
HANDLE GetStdHandle(DWORD nStdHandle)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BOOL SetStdHandle(DWORD nStdHandle, HANDLE hHandle)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL SetStdHandleEx(DWORD dwStdHandle, HANDLE hNewHandle, HANDLE* phOldHandle)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
LPSTR GetCommandLineA(VOID)
|
||||
{
|
||||
return NULL;
|
||||
|
@ -15,7 +15,7 @@
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
winpr_module_add(file.c pattern.c)
|
||||
winpr_module_add(generic.c namedPipeClient.c pattern.c file.c)
|
||||
|
||||
if(BUILD_TESTING)
|
||||
add_subdirectory(test)
|
||||
|
File diff suppressed because it is too large
Load Diff
610
winpr/libwinpr/file/generic.c
Normal file
610
winpr/libwinpr/file/generic.c
Normal file
@ -0,0 +1,610 @@
|
||||
/**
|
||||
* WinPR: Windows Portable Runtime
|
||||
* File Functions
|
||||
*
|
||||
* Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||
* Copyright 2014 Hewlett-Packard Development Company, L.P.
|
||||
*
|
||||
* 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
|
||||
|
||||
#ifdef HAVE_FCNTL_H
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
#include "../log.h"
|
||||
#define TAG WINPR_TAG("file")
|
||||
|
||||
#ifndef _WIN32
|
||||
|
||||
#include <assert.h>
|
||||
#include <pthread.h>
|
||||
#include <dirent.h>
|
||||
|
||||
#include <sys/un.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#ifdef HAVE_AIO_H
|
||||
#undef HAVE_AIO_H /* disable for now, incomplete */
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_AIO_H
|
||||
#include <aio.h>
|
||||
#endif
|
||||
|
||||
#ifdef ANDROID
|
||||
#include <sys/vfs.h>
|
||||
#else
|
||||
#include <sys/statvfs.h>
|
||||
#endif
|
||||
|
||||
#include "../handle/handle.h"
|
||||
|
||||
#include "../pipe/pipe.h"
|
||||
|
||||
/**
|
||||
* api-ms-win-core-file-l1-2-0.dll:
|
||||
*
|
||||
* CreateFileA
|
||||
* CreateFileW
|
||||
* CreateFile2
|
||||
* DeleteFileA
|
||||
* DeleteFileW
|
||||
* CreateDirectoryA
|
||||
* CreateDirectoryW
|
||||
* RemoveDirectoryA
|
||||
* RemoveDirectoryW
|
||||
* CompareFileTime
|
||||
* DefineDosDeviceW
|
||||
* DeleteVolumeMountPointW
|
||||
* FileTimeToLocalFileTime
|
||||
* LocalFileTimeToFileTime
|
||||
* FindClose
|
||||
* FindCloseChangeNotification
|
||||
* FindFirstChangeNotificationA
|
||||
* FindFirstChangeNotificationW
|
||||
* FindFirstFileA
|
||||
* FindFirstFileExA
|
||||
* FindFirstFileExW
|
||||
* FindFirstFileW
|
||||
* FindFirstVolumeW
|
||||
* FindNextChangeNotification
|
||||
* FindNextFileA
|
||||
* FindNextFileW
|
||||
* FindNextVolumeW
|
||||
* FindVolumeClose
|
||||
* GetDiskFreeSpaceA
|
||||
* GetDiskFreeSpaceExA
|
||||
* GetDiskFreeSpaceExW
|
||||
* GetDiskFreeSpaceW
|
||||
* GetDriveTypeA
|
||||
* GetDriveTypeW
|
||||
* GetFileAttributesA
|
||||
* GetFileAttributesExA
|
||||
* GetFileAttributesExW
|
||||
* GetFileAttributesW
|
||||
* GetFileInformationByHandle
|
||||
* GetFileSize
|
||||
* GetFileSizeEx
|
||||
* GetFileTime
|
||||
* GetFileType
|
||||
* GetFinalPathNameByHandleA
|
||||
* GetFinalPathNameByHandleW
|
||||
* GetFullPathNameA
|
||||
* GetFullPathNameW
|
||||
* GetLogicalDrives
|
||||
* GetLogicalDriveStringsW
|
||||
* GetLongPathNameA
|
||||
* GetLongPathNameW
|
||||
* GetShortPathNameW
|
||||
* GetTempFileNameW
|
||||
* GetTempPathW
|
||||
* GetVolumeInformationByHandleW
|
||||
* GetVolumeInformationW
|
||||
* GetVolumeNameForVolumeMountPointW
|
||||
* GetVolumePathNamesForVolumeNameW
|
||||
* GetVolumePathNameW
|
||||
* QueryDosDeviceW
|
||||
* SetFileAttributesA
|
||||
* SetFileAttributesW
|
||||
* SetFileTime
|
||||
* SetFileValidData
|
||||
* SetFileInformationByHandle
|
||||
* ReadFile
|
||||
* ReadFileEx
|
||||
* ReadFileScatter
|
||||
* WriteFile
|
||||
* WriteFileEx
|
||||
* WriteFileGather
|
||||
* FlushFileBuffers
|
||||
* SetEndOfFile
|
||||
* SetFilePointer
|
||||
* SetFilePointerEx
|
||||
* LockFile
|
||||
* LockFileEx
|
||||
* UnlockFile
|
||||
* UnlockFileEx
|
||||
*/
|
||||
|
||||
/**
|
||||
* File System Behavior in the Microsoft Windows Environment:
|
||||
* http://download.microsoft.com/download/4/3/8/43889780-8d45-4b2e-9d3a-c696a890309f/File%20System%20Behavior%20Overview.pdf
|
||||
*/
|
||||
|
||||
/**
|
||||
* Asynchronous I/O - The GNU C Library:
|
||||
* http://www.gnu.org/software/libc/manual/html_node/Asynchronous-I_002fO.html
|
||||
*/
|
||||
|
||||
/**
|
||||
* aio.h - asynchronous input and output:
|
||||
* http://pubs.opengroup.org/onlinepubs/009695399/basedefs/aio.h.html
|
||||
*/
|
||||
|
||||
/**
|
||||
* Asynchronous I/O User Guide:
|
||||
* http://code.google.com/p/kernel/wiki/AIOUserGuide
|
||||
*/
|
||||
|
||||
static wArrayList *_HandleCreators;
|
||||
|
||||
static pthread_once_t _HandleCreatorsInitialized = PTHREAD_ONCE_INIT;
|
||||
|
||||
|
||||
HANDLE_CREATOR *GetNamedPipeClientHandleCreator(void);
|
||||
|
||||
#if defined __linux__ && !defined ANDROID
|
||||
HANDLE_CREATOR *GetCommHandleCreator(void);
|
||||
#endif /* __linux__ && !defined ANDROID */
|
||||
|
||||
static void _HandleCreatorsInit()
|
||||
{
|
||||
|
||||
assert(_HandleCreators == NULL);
|
||||
_HandleCreators = ArrayList_New(TRUE);
|
||||
if (!_HandleCreators)
|
||||
return;
|
||||
|
||||
/*
|
||||
* Register all file handle creators.
|
||||
*/
|
||||
ArrayList_Add(_HandleCreators, GetNamedPipeClientHandleCreator());
|
||||
#if defined __linux__ && !defined ANDROID
|
||||
ArrayList_Add(_HandleCreators, GetCommHandleCreator());
|
||||
#endif /* __linux__ && !defined ANDROID */
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE_AIO_H
|
||||
|
||||
static BOOL g_AioSignalHandlerInstalled = FALSE;
|
||||
|
||||
void AioSignalHandler(int signum, siginfo_t* siginfo, void* arg)
|
||||
{
|
||||
WLog_INFO("%d", signum);
|
||||
}
|
||||
|
||||
int InstallAioSignalHandler()
|
||||
{
|
||||
if (!g_AioSignalHandlerInstalled)
|
||||
{
|
||||
struct sigaction action;
|
||||
sigemptyset(&action.sa_mask);
|
||||
sigaddset(&action.sa_mask, SIGIO);
|
||||
action.sa_flags = SA_SIGINFO;
|
||||
action.sa_sigaction = (void*) &AioSignalHandler;
|
||||
sigaction(SIGIO, &action, NULL);
|
||||
g_AioSignalHandlerInstalled = TRUE;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* HAVE_AIO_H */
|
||||
|
||||
HANDLE CreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes,
|
||||
DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!lpFileName)
|
||||
return INVALID_HANDLE_VALUE;
|
||||
|
||||
if (pthread_once(&_HandleCreatorsInitialized, _HandleCreatorsInit) != 0)
|
||||
{
|
||||
SetLastError(ERROR_DLL_INIT_FAILED);
|
||||
return INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
if (_HandleCreators == NULL)
|
||||
{
|
||||
SetLastError(ERROR_DLL_INIT_FAILED);
|
||||
return INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
ArrayList_Lock(_HandleCreators);
|
||||
|
||||
for (i=0; i <= ArrayList_Count(_HandleCreators); i++)
|
||||
{
|
||||
HANDLE_CREATOR* creator = ArrayList_GetItem(_HandleCreators, i);
|
||||
|
||||
if (creator && creator->IsHandled(lpFileName))
|
||||
{
|
||||
HANDLE newHandle = creator->CreateFileA(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes,
|
||||
dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
|
||||
ArrayList_Unlock(_HandleCreators);
|
||||
return newHandle;
|
||||
}
|
||||
}
|
||||
|
||||
ArrayList_Unlock(_HandleCreators);
|
||||
return INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
HANDLE CreateFileW(LPCWSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes,
|
||||
DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BOOL DeleteFileA(LPCSTR lpFileName)
|
||||
{
|
||||
int status;
|
||||
status = unlink(lpFileName);
|
||||
return (status != -1) ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
BOOL DeleteFileW(LPCWSTR lpFileName)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL ReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead,
|
||||
LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped)
|
||||
{
|
||||
ULONG Type;
|
||||
WINPR_HANDLE *handle;
|
||||
|
||||
if (hFile == INVALID_HANDLE_VALUE)
|
||||
return FALSE;
|
||||
|
||||
/*
|
||||
* from http://msdn.microsoft.com/en-us/library/windows/desktop/aa365467%28v=vs.85%29.aspx
|
||||
* lpNumberOfBytesRead can be NULL only when the lpOverlapped parameter is not NULL.
|
||||
*/
|
||||
|
||||
if (!lpNumberOfBytesRead && !lpOverlapped)
|
||||
return FALSE;
|
||||
|
||||
if (!winpr_Handle_GetInfo(hFile, &Type, &handle))
|
||||
return FALSE;
|
||||
|
||||
handle = (WINPR_HANDLE *)hFile;
|
||||
if (handle->ops->ReadFile)
|
||||
return handle->ops->ReadFile(handle, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, lpOverlapped);
|
||||
|
||||
WLog_ERR(TAG, "ReadFile operation not implemented");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL ReadFileEx(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead,
|
||||
LPOVERLAPPED lpOverlapped, LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL ReadFileScatter(HANDLE hFile, FILE_SEGMENT_ELEMENT aSegmentArray[],
|
||||
DWORD nNumberOfBytesToRead, LPDWORD lpReserved, LPOVERLAPPED lpOverlapped)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL WriteFile(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite,
|
||||
LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped)
|
||||
{
|
||||
ULONG Type;
|
||||
WINPR_HANDLE *handle;
|
||||
|
||||
if (hFile == INVALID_HANDLE_VALUE)
|
||||
return FALSE;
|
||||
|
||||
if (!winpr_Handle_GetInfo(hFile, &Type, &handle))
|
||||
return FALSE;
|
||||
|
||||
handle = (WINPR_HANDLE *)hFile;
|
||||
if (handle->ops->WriteFile)
|
||||
return handle->ops->WriteFile(handle, lpBuffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten, lpOverlapped);
|
||||
|
||||
WLog_ERR(TAG, "ReadFile operation not implemented");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL WriteFileEx(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite,
|
||||
LPOVERLAPPED lpOverlapped, LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL WriteFileGather(HANDLE hFile, FILE_SEGMENT_ELEMENT aSegmentArray[],
|
||||
DWORD nNumberOfBytesToWrite, LPDWORD lpReserved, LPOVERLAPPED lpOverlapped)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL FlushFileBuffers(HANDLE hFile)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL SetEndOfFile(HANDLE hFile)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
DWORD SetFilePointer(HANDLE hFile, LONG lDistanceToMove,
|
||||
PLONG lpDistanceToMoveHigh, DWORD dwMoveMethod)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL SetFilePointerEx(HANDLE hFile, LARGE_INTEGER liDistanceToMove,
|
||||
PLARGE_INTEGER lpNewFilePointer, DWORD dwMoveMethod)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL LockFile(HANDLE hFile, DWORD dwFileOffsetLow, DWORD dwFileOffsetHigh,
|
||||
DWORD nNumberOfBytesToLockLow, DWORD nNumberOfBytesToLockHigh)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL LockFileEx(HANDLE hFile, DWORD dwFlags, DWORD dwReserved,
|
||||
DWORD nNumberOfBytesToLockLow, DWORD nNumberOfBytesToLockHigh, LPOVERLAPPED lpOverlapped)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL UnlockFile(HANDLE hFile, DWORD dwFileOffsetLow, DWORD dwFileOffsetHigh,
|
||||
DWORD nNumberOfBytesToUnlockLow, DWORD nNumberOfBytesToUnlockHigh)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL UnlockFileEx(HANDLE hFile, DWORD dwReserved, DWORD nNumberOfBytesToUnlockLow,
|
||||
DWORD nNumberOfBytesToUnlockHigh, LPOVERLAPPED lpOverlapped)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
struct _WIN32_FILE_SEARCH
|
||||
{
|
||||
DIR* pDir;
|
||||
LPSTR lpPath;
|
||||
LPSTR lpPattern;
|
||||
struct dirent* pDirent;
|
||||
};
|
||||
typedef struct _WIN32_FILE_SEARCH WIN32_FILE_SEARCH;
|
||||
|
||||
HANDLE FindFirstFileA(LPCSTR lpFileName, LPWIN32_FIND_DATAA lpFindFileData)
|
||||
{
|
||||
char* p;
|
||||
int index;
|
||||
int length;
|
||||
struct stat fileStat;
|
||||
WIN32_FILE_SEARCH* pFileSearch;
|
||||
ZeroMemory(lpFindFileData, sizeof(WIN32_FIND_DATAA));
|
||||
pFileSearch = (WIN32_FILE_SEARCH*) calloc(1, sizeof(WIN32_FILE_SEARCH));
|
||||
if (!pFileSearch)
|
||||
{
|
||||
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||
return INVALID_HANDLE_VALUE;
|
||||
}
|
||||
/* Separate lpFileName into path and pattern components */
|
||||
p = strrchr(lpFileName, '/');
|
||||
|
||||
if (!p)
|
||||
p = strrchr(lpFileName, '\\');
|
||||
|
||||
index = (p - lpFileName);
|
||||
length = (p - lpFileName);
|
||||
pFileSearch->lpPath = (LPSTR) malloc(length + 1);
|
||||
if (!pFileSearch->lpPath)
|
||||
{
|
||||
free(pFileSearch);
|
||||
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||
return INVALID_HANDLE_VALUE;
|
||||
}
|
||||
CopyMemory(pFileSearch->lpPath, lpFileName, length);
|
||||
pFileSearch->lpPath[length] = '\0';
|
||||
length = strlen(lpFileName) - index;
|
||||
pFileSearch->lpPattern = (LPSTR) malloc(length + 1);
|
||||
if (!pFileSearch->lpPattern)
|
||||
{
|
||||
free(pFileSearch->lpPath);
|
||||
free(pFileSearch);
|
||||
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||
return INVALID_HANDLE_VALUE;
|
||||
}
|
||||
CopyMemory(pFileSearch->lpPattern, &lpFileName[index + 1], length);
|
||||
pFileSearch->lpPattern[length] = '\0';
|
||||
|
||||
/* Check if the path is a directory */
|
||||
|
||||
if (lstat(pFileSearch->lpPath, &fileStat) < 0)
|
||||
{
|
||||
FindClose(pFileSearch);
|
||||
return INVALID_HANDLE_VALUE; /* stat error */
|
||||
}
|
||||
|
||||
if (S_ISDIR(fileStat.st_mode) == 0)
|
||||
{
|
||||
FindClose(pFileSearch);
|
||||
return INVALID_HANDLE_VALUE; /* not a directory */
|
||||
}
|
||||
|
||||
/* Open directory for reading */
|
||||
pFileSearch->pDir = opendir(pFileSearch->lpPath);
|
||||
|
||||
if (!pFileSearch->pDir)
|
||||
{
|
||||
FindClose(pFileSearch);
|
||||
return INVALID_HANDLE_VALUE; /* failed to open directory */
|
||||
}
|
||||
|
||||
while ((pFileSearch->pDirent = readdir(pFileSearch->pDir)) != NULL)
|
||||
{
|
||||
if ((strcmp(pFileSearch->pDirent->d_name, ".") == 0) || (strcmp(pFileSearch->pDirent->d_name, "..") == 0))
|
||||
{
|
||||
/* skip "." and ".." */
|
||||
continue;
|
||||
}
|
||||
|
||||
if (FilePatternMatchA(pFileSearch->pDirent->d_name, pFileSearch->lpPattern))
|
||||
{
|
||||
strcpy(lpFindFileData->cFileName, pFileSearch->pDirent->d_name);
|
||||
return (HANDLE) pFileSearch;
|
||||
}
|
||||
}
|
||||
|
||||
FindClose(pFileSearch);
|
||||
return INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
HANDLE FindFirstFileW(LPCWSTR lpFileName, LPWIN32_FIND_DATAW lpFindFileData)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
HANDLE FindFirstFileExA(LPCSTR lpFileName, FINDEX_INFO_LEVELS fInfoLevelId, LPVOID lpFindFileData,
|
||||
FINDEX_SEARCH_OPS fSearchOp, LPVOID lpSearchFilter, DWORD dwAdditionalFlags)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
HANDLE FindFirstFileExW(LPCWSTR lpFileName, FINDEX_INFO_LEVELS fInfoLevelId, LPVOID lpFindFileData,
|
||||
FINDEX_SEARCH_OPS fSearchOp, LPVOID lpSearchFilter, DWORD dwAdditionalFlags)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BOOL FindNextFileA(HANDLE hFindFile, LPWIN32_FIND_DATAA lpFindFileData)
|
||||
{
|
||||
WIN32_FILE_SEARCH* pFileSearch;
|
||||
|
||||
if (!hFindFile)
|
||||
return FALSE;
|
||||
|
||||
if (hFindFile == INVALID_HANDLE_VALUE)
|
||||
return FALSE;
|
||||
|
||||
pFileSearch = (WIN32_FILE_SEARCH*) hFindFile;
|
||||
|
||||
while ((pFileSearch->pDirent = readdir(pFileSearch->pDir)) != NULL)
|
||||
{
|
||||
if (FilePatternMatchA(pFileSearch->pDirent->d_name, pFileSearch->lpPattern))
|
||||
{
|
||||
strcpy(lpFindFileData->cFileName, pFileSearch->pDirent->d_name);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL FindNextFileW(HANDLE hFindFile, LPWIN32_FIND_DATAW lpFindFileData)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL FindClose(HANDLE hFindFile)
|
||||
{
|
||||
WIN32_FILE_SEARCH* pFileSearch;
|
||||
pFileSearch = (WIN32_FILE_SEARCH*) hFindFile;
|
||||
|
||||
if (pFileSearch)
|
||||
{
|
||||
free(pFileSearch->lpPath);
|
||||
free(pFileSearch->lpPattern);
|
||||
|
||||
if (pFileSearch->pDir)
|
||||
closedir(pFileSearch->pDir);
|
||||
|
||||
free(pFileSearch);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL CreateDirectoryA(LPCSTR lpPathName, LPSECURITY_ATTRIBUTES lpSecurityAttributes)
|
||||
{
|
||||
if (!mkdir(lpPathName, S_IRUSR | S_IWUSR | S_IXUSR))
|
||||
return TRUE;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL CreateDirectoryW(LPCWSTR lpPathName, LPSECURITY_ATTRIBUTES lpSecurityAttributes)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL RemoveDirectoryA(LPCSTR lpPathName)
|
||||
{
|
||||
return (rmdir(lpPathName) == 0);
|
||||
}
|
||||
|
||||
BOOL RemoveDirectoryW(LPCWSTR lpPathName)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* Extended API */
|
||||
|
||||
int UnixChangeFileMode(const char* filename, int flags)
|
||||
{
|
||||
#ifndef _WIN32
|
||||
mode_t fl = 0;
|
||||
fl |= (flags & 0x4000) ? S_ISUID : 0;
|
||||
fl |= (flags & 0x2000) ? S_ISGID : 0;
|
||||
fl |= (flags & 0x1000) ? S_ISVTX : 0;
|
||||
fl |= (flags & 0x0400) ? S_IRUSR : 0;
|
||||
fl |= (flags & 0x0200) ? S_IWUSR : 0;
|
||||
fl |= (flags & 0x0100) ? S_IXUSR : 0;
|
||||
fl |= (flags & 0x0040) ? S_IRGRP : 0;
|
||||
fl |= (flags & 0x0020) ? S_IWGRP : 0;
|
||||
fl |= (flags & 0x0010) ? S_IXGRP : 0;
|
||||
fl |= (flags & 0x0004) ? S_IROTH : 0;
|
||||
fl |= (flags & 0x0002) ? S_IWOTH : 0;
|
||||
fl |= (flags & 0x0001) ? S_IXOTH : 0;
|
||||
return chmod(filename, fl);
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
288
winpr/libwinpr/file/namedPipeClient.c
Normal file
288
winpr/libwinpr/file/namedPipeClient.c
Normal file
@ -0,0 +1,288 @@
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
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,
|
||||
NamedPipeWrite
|
||||
};
|
||||
|
||||
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 (!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;
|
||||
strcpy(s.sun_path, 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[strlen(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
|
||||
}
|
||||
|
@ -12,7 +12,9 @@ set(${MODULE_PREFIX}_TESTS
|
||||
TestFilePatternMatch.c
|
||||
TestFileFindFirstFile.c
|
||||
TestFileFindFirstFileEx.c
|
||||
TestFileFindNextFile.c)
|
||||
TestFileFindNextFile.c
|
||||
TestFileGetStdHandle.c
|
||||
)
|
||||
|
||||
create_test_sourcelist(${MODULE_PREFIX}_SRCS
|
||||
${${MODULE_PREFIX}_DRIVER}
|
||||
|
47
winpr/libwinpr/file/test/TestFileGetStdHandle.c
Normal file
47
winpr/libwinpr/file/test/TestFileGetStdHandle.c
Normal file
@ -0,0 +1,47 @@
|
||||
|
||||
/**
|
||||
* WinPR: Windows Portable Runtime
|
||||
* File Functions
|
||||
*
|
||||
* Copyright 2015 Thincast Technologies GmbH
|
||||
* Copyright 2015 Bernhard Miklautz <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.
|
||||
*/
|
||||
|
||||
#include <winpr/file.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int TestFileGetStdHandle(int argc, char* argv[])
|
||||
{
|
||||
HANDLE stdout;
|
||||
char *buf = "happy happy";
|
||||
DWORD bytesWritten;
|
||||
|
||||
stdout = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
if (stdout == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
fprintf(stderr, "GetStdHandle failed ;(\n");
|
||||
return -1;
|
||||
}
|
||||
WriteFile(stdout, buf, strlen(buf), &bytesWritten, FALSE);
|
||||
if (bytesWritten != strlen(buf))
|
||||
{
|
||||
fprintf(stderr, "write failed\n");
|
||||
return -1;
|
||||
}
|
||||
CloseHandle(stdout);
|
||||
|
||||
return 0;
|
||||
}
|
@ -102,7 +102,7 @@ static INLINE int winpr_Handle_getFd(HANDLE handle)
|
||||
if (!winpr_Handle_GetInfo(handle, &type, &hdl))
|
||||
return -1;
|
||||
|
||||
if (!hdl || !hdl->ops->GetFd)
|
||||
if (!hdl || !hdl->ops || !hdl->ops->GetFd)
|
||||
return -1;
|
||||
|
||||
return hdl->ops->GetFd(handle);
|
||||
@ -116,7 +116,7 @@ static INLINE DWORD winpr_Handle_cleanup(HANDLE handle)
|
||||
if (!winpr_Handle_GetInfo(handle, &type, &hdl))
|
||||
return WAIT_FAILED;
|
||||
|
||||
if (!hdl)
|
||||
if (!hdl || !hdl->ops)
|
||||
return WAIT_FAILED;
|
||||
|
||||
/* If there is no cleanup function, assume all ok. */
|
||||
|
@ -36,12 +36,6 @@ static void* named_pipe_client_thread(void* arg)
|
||||
WaitForSingleObject(ReadyEvent, INFINITE);
|
||||
hNamedPipe = CreateFile(lpszPipeNameMt, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
|
||||
|
||||
if (!hNamedPipe)
|
||||
{
|
||||
printf("%s:Named Pipe CreateFile failure: NULL handle\n", __FUNCTION__);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (hNamedPipe == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
printf("%s: Named Pipe CreateFile failure: INVALID_HANDLE_VALUE\n", __FUNCTION__);
|
||||
@ -252,8 +246,8 @@ static void* named_pipe_single_thread(void* arg)
|
||||
|
||||
for (i = 0; i < numPipes; i++)
|
||||
{
|
||||
if (!(clients[i] = CreateFile(lpszPipeNameSt, GENERIC_READ | GENERIC_WRITE,
|
||||
0, NULL, OPEN_EXISTING, 0, NULL)))
|
||||
if ((clients[i] = CreateFile(lpszPipeNameSt, GENERIC_READ | GENERIC_WRITE,
|
||||
0, NULL, OPEN_EXISTING, 0, NULL)) == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
printf("%s: CreateFile #%d failed\n", __FUNCTION__, i);
|
||||
goto out;
|
||||
|
Loading…
Reference in New Issue
Block a user