winpr/file: initial regular file support
Add initial support for "regular" files. First implemented call is GetStdHandle to get stdin/stdout/stderr.
This commit is contained in:
parent
204ae5462a
commit
6b52a2e5cc
@ -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;
|
||||
@ -316,7 +320,6 @@ WINPR_API BOOL RemoveDirectoryW(LPCWSTR lpPathName);
|
||||
#define RemoveDirectory RemoveDirectoryA
|
||||
#endif
|
||||
|
||||
|
||||
/* Extra Functions */
|
||||
|
||||
typedef BOOL (*pcIsFileHandled)(LPCSTR lpFileName);
|
||||
@ -329,7 +332,9 @@ typedef struct _HANDLE_CREATOR
|
||||
pcCreateFileA CreateFileA;
|
||||
} HANDLE_CREATOR, *PHANDLE_CREATOR, *LPHANDLE_CREATOR;
|
||||
|
||||
BOOL RegisterHandleCreator(PHANDLE_CREATOR pHandleCreator);
|
||||
WINPR_API HANDLE GetStdHandle(DWORD nStdHandle);
|
||||
WINPR_API BOOL SetStdHandle(DWORD nStdHandle, HANDLE hHandle);
|
||||
WINPR_API BOOL SetStdHandleEx(DWORD dwStdHandle, HANDLE hNewHandle, HANDLE* phOldHandle);
|
||||
|
||||
#endif /* _WIN32 */
|
||||
|
||||
|
@ -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(generic.c namedPipeClient.c pattern.c)
|
||||
winpr_module_add(generic.c namedPipeClient.c pattern.c file.c)
|
||||
|
||||
if(BUILD_TESTING)
|
||||
add_subdirectory(test)
|
||||
|
222
winpr/libwinpr/file/file.c
Normal file
222
winpr/libwinpr/file/file.c
Normal file
@ -0,0 +1,222 @@
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef _WIN32
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
|
||||
#include "../log.h"
|
||||
#define TAG WINPR_TAG("file")
|
||||
|
||||
#include <winpr/file.h>
|
||||
#include <winpr/wlog.h>
|
||||
|
||||
#include "../handle/handle.h"
|
||||
#include <errno.h>
|
||||
|
||||
struct winpr_file
|
||||
{
|
||||
WINPR_HANDLE_DEF();
|
||||
|
||||
int fd;
|
||||
};
|
||||
|
||||
typedef struct winpr_file WINPR_FILE;
|
||||
|
||||
static BOOL FileIsHandled(HANDLE handle)
|
||||
{
|
||||
WINPR_FILE* pFile = (WINPR_FILE*) handle;
|
||||
|
||||
if (!pFile || (pFile->Type != HANDLE_TYPE_FILE))
|
||||
{
|
||||
SetLastError(ERROR_INVALID_HANDLE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static int FileGetFd(HANDLE handle)
|
||||
{
|
||||
WINPR_FILE *file= (WINPR_FILE*)handle;
|
||||
|
||||
if (!FileIsHandled(handle))
|
||||
return -1;
|
||||
|
||||
return file->fd;
|
||||
}
|
||||
|
||||
static BOOL FileCloseHandle(HANDLE handle) {
|
||||
WINPR_FILE* file = (WINPR_FILE *)handle;
|
||||
|
||||
if (!FileIsHandled(handle))
|
||||
return FALSE;
|
||||
|
||||
if (file->fd != -1)
|
||||
{
|
||||
close(file->fd);
|
||||
file->fd = -1;
|
||||
}
|
||||
|
||||
free(handle);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL FileRead(PVOID Object, LPVOID lpBuffer, DWORD nNumberOfBytesToRead,
|
||||
LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped)
|
||||
{
|
||||
int io_status;
|
||||
WINPR_FILE* file;
|
||||
BOOL status = TRUE;
|
||||
|
||||
if (!Object)
|
||||
return FALSE;
|
||||
|
||||
if (lpOverlapped)
|
||||
{
|
||||
WLog_ERR(TAG, "Overlapping write not supported.");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
file = (WINPR_FILE *)Object;
|
||||
do
|
||||
{
|
||||
io_status = read(file->fd, lpBuffer, nNumberOfBytesToRead);
|
||||
}
|
||||
while ((io_status < 0) && (errno == EINTR));
|
||||
|
||||
if (io_status < 0)
|
||||
{
|
||||
status = FALSE;
|
||||
|
||||
switch (errno)
|
||||
{
|
||||
case EWOULDBLOCK:
|
||||
SetLastError(ERROR_NO_DATA);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (lpNumberOfBytesRead)
|
||||
*lpNumberOfBytesRead = io_status;
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static BOOL FileWrite(PVOID Object, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite,
|
||||
LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped)
|
||||
{
|
||||
int io_status;
|
||||
WINPR_FILE* file;
|
||||
|
||||
if (!Object)
|
||||
return FALSE;
|
||||
|
||||
if (lpOverlapped)
|
||||
{
|
||||
WLog_ERR(TAG, "Overlapping write not supported.");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
file = (WINPR_FILE *)Object;
|
||||
|
||||
do
|
||||
{
|
||||
io_status = write(file->fd, lpBuffer, nNumberOfBytesToWrite);
|
||||
}
|
||||
while ((io_status < 0) && (errno == EINTR));
|
||||
|
||||
if ((io_status < 0) && (errno == EWOULDBLOCK))
|
||||
io_status = 0;
|
||||
|
||||
*lpNumberOfBytesWritten = io_status;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
static HANDLE_OPS ops = {
|
||||
FileIsHandled,
|
||||
FileCloseHandle,
|
||||
FileGetFd,
|
||||
NULL, /* CleanupHandle */
|
||||
FileRead,
|
||||
FileWrite
|
||||
};
|
||||
|
||||
static WINPR_FILE *FileHandle_New()
|
||||
{
|
||||
WINPR_FILE *pFile;
|
||||
HANDLE hFile;
|
||||
|
||||
pFile = (WINPR_FILE*) calloc(1, sizeof(WINPR_FILE));
|
||||
if (!pFile)
|
||||
{
|
||||
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||
return NULL;
|
||||
}
|
||||
pFile->fd = -1;
|
||||
pFile->ops = &ops;
|
||||
|
||||
hFile = (HANDLE) pFile;
|
||||
WINPR_HANDLE_SET_TYPE_AND_MODE(pFile, HANDLE_TYPE_FILE, WINPR_FD_READ);
|
||||
return pFile;
|
||||
}
|
||||
|
||||
HANDLE GetStdHandle(DWORD nStdHandle)
|
||||
{
|
||||
int fd;
|
||||
WINPR_FILE *pFile;
|
||||
switch (nStdHandle)
|
||||
{
|
||||
case STD_INPUT_HANDLE:
|
||||
fd = STDIN_FILENO;
|
||||
break;
|
||||
case STD_OUTPUT_HANDLE:
|
||||
fd = STDOUT_FILENO;
|
||||
break;
|
||||
case STD_ERROR_HANDLE:
|
||||
fd = STDERR_FILENO;
|
||||
break;
|
||||
default:
|
||||
return INVALID_HANDLE_VALUE;
|
||||
}
|
||||
pFile = FileHandle_New();
|
||||
if (!pFile)
|
||||
return INVALID_HANDLE_VALUE;
|
||||
|
||||
pFile->fd = fd;
|
||||
return (HANDLE)pFile;
|
||||
}
|
||||
|
||||
BOOL SetStdHandle(DWORD nStdHandle, HANDLE hHandle)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL SetStdHandleEx(DWORD dwStdHandle, HANDLE hNewHandle, HANDLE* phOldHandle)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#endif /* _WIN32 */
|
||||
|
@ -24,7 +24,6 @@
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/path.h>
|
||||
#include <winpr/synch.h>
|
||||
#include <winpr/file.h>
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
|
@ -61,7 +61,8 @@ static BOOL NamedPipeClientIsHandled(HANDLE handle)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL NamedPipeClientCloseHandle(HANDLE handle) {
|
||||
BOOL NamedPipeClientCloseHandle(HANDLE handle)
|
||||
{
|
||||
WINPR_NAMED_PIPE* pNamedPipe = (WINPR_NAMED_PIPE*) handle;
|
||||
|
||||
|
||||
|
@ -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}
|
||||
|
46
winpr/libwinpr/file/test/TestFileGetStdHandle.c
Normal file
46
winpr/libwinpr/file/test/TestFileGetStdHandle.c
Normal file
@ -0,0 +1,46 @@
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user