Added additional file functions and tests.
This commit is contained in:
parent
d0e3528c8e
commit
19744f3bb8
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
|
61
winpr/libwinpr/file/file.h
Normal file
61
winpr/libwinpr/file/file.h
Normal 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 */
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user