Added additional file functions and tests.

This commit is contained in:
Armin Novak 2015-12-09 18:29:16 +01:00
parent d0e3528c8e
commit 19744f3bb8
8 changed files with 853 additions and 53 deletions

View File

@ -165,6 +165,13 @@
#define STD_OUTPUT_HANDLE (DWORD)-11
#define STD_ERROR_HANDLE (DWORD)-12
#define FILE_BEGIN 0
#define FILE_CURRENT 1
#define FILE_END 2
#define LOCKFILE_FAIL_IMMEDIATELY 1
#define LOCKFILE_EXCLUSIVE_LOCK 2
typedef union _FILE_SEGMENT_ELEMENT
{
PVOID64 Buffer;
@ -261,6 +268,8 @@ WINPR_API BOOL FlushFileBuffers(HANDLE hFile);
WINPR_API BOOL SetEndOfFile(HANDLE hFile);
WINPR_API DWORD WINAPI GetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh);
WINPR_API DWORD SetFilePointer(HANDLE hFile, LONG lDistanceToMove,
PLONG lpDistanceToMoveHigh, DWORD dwMoveMethod);

View File

@ -30,19 +30,12 @@
#define TAG WINPR_TAG("file")
#include <winpr/wlog.h>
#include <winpr/string.h>
#include "../handle/handle.h"
#include "file.h"
#include <errno.h>
#include <fcntl.h>
struct winpr_file
{
WINPR_HANDLE_DEF();
int fd;
};
typedef struct winpr_file WINPR_FILE;
#include <sys/file.h>
static BOOL FileIsHandled(HANDLE handle)
{
@ -84,10 +77,81 @@ static BOOL FileCloseHandle(HANDLE handle) {
}
}
free(handle);
free(file->lpFileName);
free(file);
return TRUE;
}
static BOOL FileSetEndOfFile(HANDLE hFile)
{
WINPR_FILE* pFile = (WINPR_FILE*) hFile;
DWORD lowSize, highSize;
off_t size;
if (!hFile)
return FALSE;
lowSize = GetFileSize(hFile, &highSize);
if (lowSize == INVALID_FILE_SIZE)
return FALSE;
size = lowSize | ((off_t)highSize << 32);
if (ftruncate(pFile->fd, size) < 0)
{
WLog_ERR(TAG, "ftruncate %d failed with %s [%08X]",
pFile->fd, strerror(errno), errno);
return FALSE;
}
return TRUE;
}
static DWORD FileSetFilePointer(HANDLE hFile, LONG lDistanceToMove,
PLONG lpDistanceToMoveHigh, DWORD dwMoveMethod)
{
WINPR_FILE* pFile = (WINPR_FILE*) hFile;
long offset = lDistanceToMove;
int whence;
FILE* fp;
if (!hFile)
return INVALID_SET_FILE_POINTER;
fp = fdopen(pFile->fd, "w");
if (!fp)
{
WLog_ERR(TAG, "fdopen(%d) failed with %s [%08X]", pFile->fd,
strerror(errno), errno);
return INVALID_SET_FILE_POINTER;
}
switch(dwMoveMethod)
{
case FILE_BEGIN:
whence = SEEK_SET;
break;
case FILE_END:
whence = SEEK_END;
break;
case FILE_CURRENT:
whence = SEEK_CUR;
break;
default:
return INVALID_SET_FILE_POINTER;
}
if (fseek(fp, offset, whence))
{
WLog_ERR(TAG, "fseek(%d) failed with %s [%08X]", pFile->fd,
strerror(errno), errno);
return INVALID_SET_FILE_POINTER;
}
return ftell(fp);
}
static BOOL FileRead(PVOID Object, LPVOID lpBuffer, DWORD nNumberOfBytesToRead,
LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped)
{
@ -159,29 +223,347 @@ static BOOL FileWrite(PVOID Object, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrit
return TRUE;
}
static DWORD FileGetFileSize(HANDLE Object, LPDWORD lpFileSizeHigh)
{
WINPR_FILE* file;
FILE* fp;
long cur, size;
static HANDLE_OPS ops = {
FileIsHandled,
FileCloseHandle,
FileGetFd,
NULL, /* CleanupHandle */
FileRead,
FileWrite
if (!Object)
return 0;
file = (WINPR_FILE *)Object;
fp = fdopen(file->fd, "r");
if (!fp)
{
WLog_ERR(TAG, "fdopen(%d) failed with %s [%08X]", file->fd,
strerror(errno), errno);
return INVALID_FILE_SIZE;
}
cur = ftell(fp);
if (cur < 0)
{
WLog_ERR(TAG, "ftell(%d) failed with %s [%08X]", file->fd,
strerror(errno), errno);
return INVALID_FILE_SIZE;
}
if (fseek(fp, 0, SEEK_END) != 0)
{
WLog_ERR(TAG, "fseek(%d) failed with %s [%08X]", file->fd,
strerror(errno), errno);
return INVALID_FILE_SIZE;
}
size = ftell(fp);
if (size < 0)
{
WLog_ERR(TAG, "ftell(%d) failed with %s [%08X]", file->fd,
strerror(errno), errno);
return INVALID_FILE_SIZE;
}
if (fseek(fp, cur, SEEK_SET) != 0)
{
WLog_ERR(TAG, "ftell(%d) failed with %s [%08X]", file->fd,
strerror(errno), errno);
return INVALID_FILE_SIZE;
}
if (lpFileSizeHigh)
*lpFileSizeHigh = 0;
return size;
}
static BOOL FileLockFileEx(HANDLE hFile, DWORD dwFlags, DWORD dwReserved,
DWORD nNumberOfBytesToLockLow, DWORD nNumberOfBytesToLockHigh,
LPOVERLAPPED lpOverlapped)
{
int lock;
WINPR_FILE* pFile = (WINPR_FILE*)hFile;
if (!hFile)
return FALSE;
if (pFile->bLocked)
{
WLog_ERR(TAG, "File %d already locked!", pFile->fd);
return FALSE;
}
if (lpOverlapped)
{
WLog_ERR(TAG, "lpOverlapped not implemented!");
return FALSE;
}
if (dwFlags & LOCKFILE_EXCLUSIVE_LOCK)
lock = LOCK_EX;
else
lock = LOCK_SH;
if (dwFlags & LOCKFILE_FAIL_IMMEDIATELY)
lock |= LOCK_NB;
if (flock(pFile->fd, lock) < 0)
{
WLog_ERR(TAG, "flock failed with %s [%08X]",
strerror(errno), errno);
return FALSE;
}
pFile->bLocked = TRUE;
return TRUE;
}
static BOOL FileUnlockFile(HANDLE hFile, DWORD dwFileOffsetLow, DWORD dwFileOffsetHigh,
DWORD nNumberOfBytesToUnlockLow, DWORD nNumberOfBytesToUnlockHigh)
{
WINPR_FILE* pFile = (WINPR_FILE*)hFile;
if (!hFile)
return FALSE;
if (!pFile->bLocked)
{
WLog_ERR(TAG, "File %d is not locked!", pFile->fd);
return FALSE;
}
if (flock(pFile->fd, LOCK_UN) < 0)
{
WLog_ERR(TAG, "flock(LOCK_UN) %d failed with %s [%08X]",
pFile->fd, strerror(errno), errno);
return FALSE;
}
return TRUE;
}
static BOOL FileUnlockFileEx(HANDLE hFile, DWORD dwReserved, DWORD nNumberOfBytesToUnlockLow,
DWORD nNumberOfBytesToUnlockHigh, LPOVERLAPPED lpOverlapped)
{
WINPR_FILE* pFile = (WINPR_FILE*)hFile;
if (!hFile)
return FALSE;
if (!pFile->bLocked)
{
WLog_ERR(TAG, "File %d is not locked!", pFile->fd);
return FALSE;
}
if (lpOverlapped)
{
WLog_ERR(TAG, "lpOverlapped not implemented!");
return FALSE;
}
if (flock(pFile->fd, LOCK_UN) < 0)
{
WLog_ERR(TAG, "flock(LOCK_UN) %d failed with %s [%08X]",
pFile->fd, strerror(errno), errno);
return FALSE;
}
return TRUE;
}
static HANDLE_OPS fileOps = {
FileIsHandled,
FileCloseHandle,
FileGetFd,
NULL, /* CleanupHandle */
FileRead,
NULL, /* FileReadEx */
NULL, /* FileReadScatter */
FileWrite,
NULL, /* FileWriteEx */
NULL, /* FileWriteGather */
FileGetFileSize,
NULL, /* FlushFileBuffers */
FileSetEndOfFile,
FileSetFilePointer,
NULL, /* SetFilePointerEx */
NULL, /* FileLockFile */
FileLockFileEx,
FileUnlockFile,
FileUnlockFileEx
};
static WINPR_FILE *FileHandle_New()
static HANDLE_OPS pipeOps = {
FileIsHandled,
FileCloseHandle,
FileGetFd,
NULL, /* CleanupHandle */
FileRead,
NULL, /* FileReadEx */
NULL, /* FileReadScatter */
FileWrite,
NULL, /* FileWriteEx */
NULL, /* FileWriteGather */
NULL, /* FileGetFileSize */
NULL, /* FlushFileBuffers */
NULL, /* FileSetEndOfFile */
NULL, /* FileSetFilePointer */
NULL, /* SetFilePointerEx */
NULL, /* FileLockFile */
NULL, /* FileLockFileEx */
NULL, /* FileUnlockFile */
NULL /* FileUnlockFileEx */
};
static const char* FileGetMode(DWORD dwDesiredAccess, DWORD dwCreationDisposition, BOOL* create)
{
BOOL writeable = dwDesiredAccess & GENERIC_WRITE;
switch(dwCreationDisposition)
{
case CREATE_ALWAYS:
*create = TRUE;
return (writeable) ? "wb+" : "rwb";
case CREATE_NEW:
*create = TRUE;
return "wb+";
case OPEN_ALWAYS:
*create = TRUE;
return "rb+";
case OPEN_EXISTING:
*create = FALSE;
return "rb+";
case TRUNCATE_EXISTING:
*create = FALSE;
return "wb+";
default:
*create = FALSE;
return "";
}
}
static HANDLE FileCreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes,
DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile)
{
WINPR_FILE* pFile;
BOOL create;
const char* mode = FileGetMode(dwDesiredAccess, dwCreationDisposition, &create);
int lock;
pFile = (WINPR_FILE*) calloc(1, sizeof(WINPR_FILE));
if (!pFile)
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return INVALID_HANDLE_VALUE;
}
WINPR_HANDLE_SET_TYPE_AND_MODE(pFile, HANDLE_TYPE_FILE, WINPR_FD_READ);
pFile->ops = &fileOps;
pFile->lpFileName = _strdup(lpFileName);
if (!pFile->lpFileName)
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
free(pFile);
return INVALID_HANDLE_VALUE;
}
pFile->dwOpenMode = dwDesiredAccess;
pFile->dwShareMode = dwShareMode;
pFile->dwFlagsAndAttributes = dwFlagsAndAttributes;
pFile->lpSecurityAttributes = lpSecurityAttributes;
pFile->dwCreationDisposition = dwCreationDisposition;
pFile->hTemplateFile = hTemplateFile;
if (create)
{
FILE* fp = fopen(pFile->lpFileName, "ab");
if (!fp)
{
free(pFile->lpFileName);
free(pFile);
return INVALID_HANDLE_VALUE;
}
fclose(fp);
}
{
FILE* fp = fopen(pFile->lpFileName, mode);
pFile->fd = fileno(fp);
}
if (pFile->fd < 0)
{
WLog_ERR(TAG, "Failed to open file %s with mode %s",
pFile->lpFileName, mode);
free(pFile->lpFileName);
free(pFile);
return INVALID_HANDLE_VALUE;
}
if (dwShareMode & FILE_SHARE_READ)
lock = LOCK_SH;
if (dwShareMode & FILE_SHARE_WRITE)
lock = LOCK_EX;
if (dwShareMode & (FILE_SHARE_READ | FILE_SHARE_WRITE))
{
if (flock(pFile->fd, lock) < 0)
{
WLog_ERR(TAG, "flock failed with %s [%08X]",
strerror(errno), errno);
close(pFile->fd);
free(pFile->lpFileName);
free(pFile);
return INVALID_HANDLE_VALUE;
}
pFile->bLocked = TRUE;
}
return pFile;
}
BOOL IsFileDevice(LPCTSTR lpDeviceName)
{
return TRUE;
}
HANDLE_CREATOR _FileHandleCreator =
{
IsFileDevice,
FileCreateFileA
};
HANDLE_CREATOR *GetFileHandleCreator(void)
{
return &_FileHandleCreator;
}
static WINPR_FILE *FileHandle_New(int fd)
{
WINPR_FILE *pFile;
HANDLE hFile;
char name[MAX_PATH];
_snprintf(name, sizeof(name), "pipe_device_%d", fd);
pFile = (WINPR_FILE*) calloc(1, sizeof(WINPR_FILE));
if (!pFile)
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return NULL;
}
pFile->fd = -1;
pFile->ops = &ops;
pFile->fd = fd;
pFile->ops = &pipeOps;
pFile->lpFileName = _strdup(name);
hFile = (HANDLE) pFile;
WINPR_HANDLE_SET_TYPE_AND_MODE(pFile, HANDLE_TYPE_FILE, WINPR_FD_READ);
@ -206,11 +588,10 @@ HANDLE GetStdHandle(DWORD nStdHandle)
default:
return INVALID_HANDLE_VALUE;
}
pFile = FileHandle_New();
pFile = FileHandle_New(fd);
if (!pFile)
return INVALID_HANDLE_VALUE;
pFile->fd = fd;
return (HANDLE)pFile;
}
@ -239,7 +620,7 @@ HANDLE GetFileHandleForFileDescriptor(int fd)
if (fcntl(fd, F_GETFD) == -1 && errno == EBADF)
return INVALID_HANDLE_VALUE;
pFile = FileHandle_New();
pFile = FileHandle_New(fd);
if (!pFile)
return INVALID_HANDLE_VALUE;
pFile->fd = fd;

View File

@ -0,0 +1,61 @@
/**
* WinPR: Windows Portable Runtime
* File Functions
*
* Copyright 2015 Armin Novak <armin.novak@thincast.com>
* Copyright 2015 Thincast Technologies GmbH
*
* 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 WINPR_FILE_PRIV_H
#define WINPR_FILE_PRIV_H
#include <winpr/winpr.h>
#include <winpr/wtypes.h>
#include <winpr/nt.h>
#include <winpr/io.h>
#include <winpr/error.h>
#ifndef _WIN32
#include <stdio.h>
#include "../handle/handle.h"
struct winpr_file
{
WINPR_HANDLE_DEF();
int fd;
char* lpFileName;
DWORD dwOpenMode;
DWORD dwShareMode;
DWORD dwFlagsAndAttributes;
LPSECURITY_ATTRIBUTES lpSecurityAttributes;
DWORD dwCreationDisposition;
HANDLE hTemplateFile;
BOOL bLocked;
};
typedef struct winpr_file WINPR_FILE;
HANDLE_CREATOR *GetFileHandleCreator(void);
#endif /* _WIN32 */
#endif /* WINPR_FILE_PRIV_H */

View File

@ -65,6 +65,8 @@
#include "../pipe/pipe.h"
#include "file.h"
/**
* api-ms-win-core-file-l1-2-0.dll:
*
@ -195,6 +197,7 @@ static void _HandleCreatorsInit()
#if defined __linux__ && !defined ANDROID
ArrayList_Add(_HandleCreators, GetCommHandleCreator());
#endif /* __linux__ && !defined ANDROID */
ArrayList_Add(_HandleCreators, GetFileHandleCreator());
}
@ -253,8 +256,9 @@ HANDLE CreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode,
if (creator && creator->IsHandled(lpFileName))
{
HANDLE newHandle = creator->CreateFileA(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes,
dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
HANDLE newHandle = creator->CreateFileA(lpFileName, dwDesiredAccess,
dwShareMode, lpSecurityAttributes, dwCreationDisposition,
dwFlagsAndAttributes, hTemplateFile);
ArrayList_Unlock(_HandleCreators);
return newHandle;
}
@ -267,7 +271,17 @@ HANDLE CreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode,
HANDLE CreateFileW(LPCWSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes,
DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile)
{
return NULL;
LPSTR lpFileNameA = NULL;
HANDLE hdl;
if (ConvertFromUnicode(CP_UTF8, 0, lpFileName, -1, &lpFileNameA, 0, NULL, NULL))
return NULL;
hdl= CreateFileA(lpFileNameA, dwDesiredAccess, dwShareMode, lpSecurityAttributes,
dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
free (lpFileNameA);
return hdl;
}
BOOL DeleteFileA(LPCSTR lpFileName)
@ -279,7 +293,15 @@ BOOL DeleteFileA(LPCSTR lpFileName)
BOOL DeleteFileW(LPCWSTR lpFileName)
{
return TRUE;
LPSTR lpFileNameA = NULL;
BOOL rc = FALSE;
if (ConvertFromUnicode(CP_UTF8, 0, lpFileName, -1, &lpFileNameA, 0, NULL, NULL))
return FALSE;
rc = DeleteFileA(lpFileNameA);
free (lpFileNameA);
return rc;
}
BOOL ReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead,
@ -304,22 +326,55 @@ BOOL ReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead,
handle = (WINPR_HANDLE *)hFile;
if (handle->ops->ReadFile)
return handle->ops->ReadFile(handle, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, lpOverlapped);
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)
LPOVERLAPPED lpOverlapped, LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
{
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->ReadFileEx)
return handle->ops->ReadFileEx(handle, lpBuffer, nNumberOfBytesToRead,
lpOverlapped, lpCompletionRoutine);
WLog_ERR(TAG, "ReadFileEx operation not implemented");
return FALSE;
return TRUE;
}
BOOL ReadFileScatter(HANDLE hFile, FILE_SEGMENT_ELEMENT aSegmentArray[],
DWORD nNumberOfBytesToRead, LPDWORD lpReserved, LPOVERLAPPED lpOverlapped)
DWORD nNumberOfBytesToRead, LPDWORD lpReserved, LPOVERLAPPED lpOverlapped)
{
return TRUE;
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->ReadFileScatter)
return handle->ops->ReadFileScatter(handle, aSegmentArray, nNumberOfBytesToRead,
lpReserved, lpOverlapped);
WLog_ERR(TAG, "ReadFileScatter operation not implemented");
return FALSE;
}
BOOL WriteFile(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite,
@ -336,68 +391,236 @@ BOOL WriteFile(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite,
handle = (WINPR_HANDLE *)hFile;
if (handle->ops->WriteFile)
return handle->ops->WriteFile(handle, lpBuffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten, lpOverlapped);
return handle->ops->WriteFile(handle, lpBuffer, nNumberOfBytesToWrite,
lpNumberOfBytesWritten, lpOverlapped);
WLog_ERR(TAG, "ReadFile operation not implemented");
WLog_ERR(TAG, "WriteFile operation not implemented");
return FALSE;
}
BOOL WriteFileEx(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite,
LPOVERLAPPED lpOverlapped, LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
LPOVERLAPPED lpOverlapped, LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
{
return TRUE;
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->WriteFileEx)
return handle->ops->WriteFileEx(handle, lpBuffer, nNumberOfBytesToWrite,
lpOverlapped, lpCompletionRoutine);
WLog_ERR(TAG, "WriteFileEx operation not implemented");
return FALSE;
}
BOOL WriteFileGather(HANDLE hFile, FILE_SEGMENT_ELEMENT aSegmentArray[],
DWORD nNumberOfBytesToWrite, LPDWORD lpReserved, LPOVERLAPPED lpOverlapped)
DWORD nNumberOfBytesToWrite, LPDWORD lpReserved, LPOVERLAPPED lpOverlapped)
{
return TRUE;
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->WriteFileGather)
return handle->ops->WriteFileGather(handle, aSegmentArray, nNumberOfBytesToWrite,
lpReserved, lpOverlapped);
WLog_ERR(TAG, "WriteFileGather operation not implemented");
return FALSE;
}
BOOL FlushFileBuffers(HANDLE hFile)
{
return TRUE;
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->FlushFileBuffers)
return handle->ops->FlushFileBuffers(handle);
WLog_ERR(TAG, "FlushFileBuffers operation not implemented");
return FALSE;
}
BOOL SetEndOfFile(HANDLE hFile)
{
return TRUE;
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->SetEndOfFile)
return handle->ops->SetEndOfFile(handle);
WLog_ERR(TAG, "SetEndOfFile operation not implemented");
return FALSE;
}
DWORD WINAPI GetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh)
{
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->GetFileSize)
return handle->ops->GetFileSize(handle, lpFileSizeHigh);
WLog_ERR(TAG, "GetFileSize operation not implemented");
return 0;
}
DWORD SetFilePointer(HANDLE hFile, LONG lDistanceToMove,
PLONG lpDistanceToMoveHigh, DWORD dwMoveMethod)
{
return TRUE;
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->SetFilePointer)
return handle->ops->SetFilePointer(handle, lDistanceToMove,
lpDistanceToMoveHigh, dwMoveMethod);
WLog_ERR(TAG, "SetFilePointer operation not implemented");
return 0;
}
BOOL SetFilePointerEx(HANDLE hFile, LARGE_INTEGER liDistanceToMove,
PLARGE_INTEGER lpNewFilePointer, DWORD dwMoveMethod)
PLARGE_INTEGER lpNewFilePointer, DWORD dwMoveMethod)
{
return TRUE;
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->SetFilePointerEx)
return handle->ops->SetFilePointerEx(handle, liDistanceToMove,
lpNewFilePointer, dwMoveMethod);
WLog_ERR(TAG, "SetFilePointerEx operation not implemented");
return 0;
}
BOOL LockFile(HANDLE hFile, DWORD dwFileOffsetLow, DWORD dwFileOffsetHigh,
DWORD nNumberOfBytesToLockLow, DWORD nNumberOfBytesToLockHigh)
{
return TRUE;
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->LockFile)
return handle->ops->LockFile(handle, dwFileOffsetLow, dwFileOffsetHigh,
nNumberOfBytesToLockLow, nNumberOfBytesToLockHigh);
WLog_ERR(TAG, "LockFile operation not implemented");
return FALSE;
}
BOOL LockFileEx(HANDLE hFile, DWORD dwFlags, DWORD dwReserved,
DWORD nNumberOfBytesToLockLow, DWORD nNumberOfBytesToLockHigh, LPOVERLAPPED lpOverlapped)
DWORD nNumberOfBytesToLockLow, DWORD nNumberOfBytesToLockHigh, LPOVERLAPPED lpOverlapped)
{
return TRUE;
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->LockFileEx)
return handle->ops->LockFileEx(handle, dwFlags, dwReserved,
nNumberOfBytesToLockLow, nNumberOfBytesToLockHigh, lpOverlapped);
WLog_ERR(TAG, "LockFileEx operation not implemented");
return FALSE;
}
BOOL UnlockFile(HANDLE hFile, DWORD dwFileOffsetLow, DWORD dwFileOffsetHigh,
DWORD nNumberOfBytesToUnlockLow, DWORD nNumberOfBytesToUnlockHigh)
{
return TRUE;
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->UnlockFile)
return handle->ops->UnlockFile(handle, dwFileOffsetLow, dwFileOffsetHigh,
nNumberOfBytesToUnlockLow, nNumberOfBytesToUnlockHigh);
WLog_ERR(TAG, "UnLockFile operation not implemented");
return FALSE;
}
BOOL UnlockFileEx(HANDLE hFile, DWORD dwReserved, DWORD nNumberOfBytesToUnlockLow,
DWORD nNumberOfBytesToUnlockHigh, LPOVERLAPPED lpOverlapped)
{
return TRUE;
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->UnlockFileEx)
return handle->ops->UnlockFileEx(handle, dwReserved,
nNumberOfBytesToUnlockLow, nNumberOfBytesToUnlockHigh, lpOverlapped);
WLog_ERR(TAG, "UnLockFileEx operation not implemented");
return FALSE;
}
struct _WIN32_FILE_SEARCH

View File

@ -111,7 +111,20 @@ static HANDLE_OPS ops = {
NamedPipeClientGetFd,
NULL, /* CleanupHandle */
NamedPipeRead,
NamedPipeWrite
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 */
};
static HANDLE NamedPipeClientCreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes,

View File

@ -2,9 +2,70 @@
#include <stdio.h>
#include <winpr/crt.h>
#include <winpr/file.h>
#include <winpr/path.h>
#include <winpr/windows.h>
int TestFileCreateFile(int argc, char* argv[])
{
return 0;
HANDLE handle;
HRESULT hr;
DWORD written;
const char buffer[] = "Some random text\r\njust want it done.";
char cmp[sizeof(buffer)];
LPSTR name = GetKnownSubPath(KNOWN_PATH_TEMP, "CreateFile.testfile");
int rc = 0;
if (!name)
return -1;
/* On windows we would need '\\' or '/' as seperator.
* Single '\' do not work. */
hr = PathCchConvertStyleA(name, strlen(name), PATH_STYLE_UNIX);
if (FAILED(hr))
rc = -1;
handle = CreateFileA(name, GENERIC_READ | GENERIC_WRITE, 0, NULL,
CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
if (!handle)
{
free(name);
return -1;
}
if (!PathFileExistsA(name))
rc = -1;
if (!WriteFile(handle, buffer, sizeof(buffer), &written, NULL))
rc = -1;
if (written != sizeof(buffer))
rc = -1;
written = SetFilePointer(handle, 0, NULL, FILE_BEGIN);
if (written != 0)
rc = -1;
if (!ReadFile(handle, cmp, sizeof(cmp), &written, NULL))
rc = -1;
if (written != sizeof(cmp))
rc = -1;
if (memcmp(buffer, cmp, sizeof(buffer)))
rc = -1;
if (!CloseHandle(handle))
rc = -1;
if (!DeleteFileA(name))
rc = -1;
if (PathFileExistsA(name))
rc = -1;
free(name);
return rc;
}

View File

@ -50,9 +50,33 @@ typedef BOOL (*pcCloseHandle)(HANDLE handle);
typedef int (*pcGetFd)(HANDLE handle);
typedef DWORD (*pcCleanupHandle)(HANDLE handle);
typedef BOOL (*pcReadFile)(PVOID Object, LPVOID lpBuffer, DWORD nNumberOfBytesToRead,
LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped);
LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped);
typedef BOOL (*pcReadFileEx)(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead,
LPOVERLAPPED lpOverlapped, LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine);
typedef BOOL (*pcReadFileScatter)(HANDLE hFile, FILE_SEGMENT_ELEMENT aSegmentArray[],
DWORD nNumberOfBytesToRead, LPDWORD lpReserved, LPOVERLAPPED lpOverlapped);
typedef BOOL (*pcWriteFile)(PVOID Object, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite,
LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped);
LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped);
typedef BOOL (*pcWriteFileEx)(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite,
LPOVERLAPPED lpOverlapped, LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine);
typedef BOOL (*pcWriteFileGather)(HANDLE hFile, FILE_SEGMENT_ELEMENT aSegmentArray[],
DWORD nNumberOfBytesToWrite, LPDWORD lpReserved, LPOVERLAPPED lpOverlapped);
typedef DWORD (*pcGetFileSize)(HANDLE handle, LPDWORD lpFileSizeHigh);
typedef BOOL (*pcFlushFileBuffers)(HANDLE hFile);
typedef BOOL (*pcSetEndOfFile)(HANDLE handle);
typedef DWORD(*pcSetFilePointer)(HANDLE handle, LONG lDistanceToMove,
PLONG lpDistanceToMoveHigh, DWORD dwMoveMethod);
typedef BOOL (*pcSetFilePointerEx)(HANDLE hFile, LARGE_INTEGER liDistanceToMove,
PLARGE_INTEGER lpNewFilePointer, DWORD dwMoveMethod);
typedef BOOL (*pcLockFile)(HANDLE hFile, DWORD dwFileOffsetLow, DWORD dwFileOffsetHigh,
DWORD nNumberOfBytesToLockLow, DWORD nNumberOfBytesToLockHigh);
typedef BOOL (*pcLockFileEx)(HANDLE hFile, DWORD dwFlags, DWORD dwReserved,
DWORD nNumberOfBytesToLockLow, DWORD nNumberOfBytesToLockHigh,
LPOVERLAPPED lpOverlapped);
typedef BOOL (*pcUnlockFile)(HANDLE hFile, DWORD dwFileOffsetLow, DWORD dwFileOffsetHigh,
DWORD nNumberOfBytesToUnlockLow, DWORD nNumberOfBytesToUnlockHigh);
typedef BOOL (*pcUnlockFileEx)(HANDLE hFile, DWORD dwReserved, DWORD nNumberOfBytesToUnlockLow,
DWORD nNumberOfBytesToUnlockHigh, LPOVERLAPPED lpOverlapped);
typedef struct _HANDLE_OPS
{
@ -61,7 +85,20 @@ typedef struct _HANDLE_OPS
pcGetFd GetFd;
pcCleanupHandle CleanupHandle;
pcReadFile ReadFile;
pcReadFileEx ReadFileEx;
pcReadFileScatter ReadFileScatter;
pcWriteFile WriteFile;
pcWriteFileEx WriteFileEx;
pcWriteFileGather WriteFileGather;
pcGetFileSize GetFileSize;
pcFlushFileBuffers FlushFileBuffers;
pcSetEndOfFile SetEndOfFile;
pcSetFilePointer SetFilePointer;
pcSetFilePointerEx SetFilePointerEx;
pcLockFile LockFile;
pcLockFileEx LockFileEx;
pcUnlockFile UnlockFile;
pcUnlockFileEx UnlockFileEx;
} HANDLE_OPS;
struct winpr_handle

View File

@ -178,7 +178,20 @@ static HANDLE_OPS ops = {
PipeGetFd,
NULL, /* CleanupHandle */
PipeRead,
PipeWrite
NULL, /* FileReadEx */
NULL, /* FileReadScatter */
PipeWrite,
NULL, /* FileWriteEx */
NULL, /* FileWriteGather */
NULL, /* FileGetFileSize */
NULL, /* FlushFileBuffers */
NULL, /* FileSetEndOfFile */
NULL, /* FileSetFilePointer */
NULL, /* SetFilePointerEx */
NULL, /* FileLockFile */
NULL, /* FileLockFileEx */
NULL, /* FileUnlockFile */
NULL /* FileUnlockFileEx */
};
@ -409,6 +422,8 @@ static HANDLE_OPS namedOps = {
NamedPipeGetFd,
NULL, /* CleanupHandle */
NamedPipeRead,
NULL,
NULL,
NamedPipeWrite
};