// Common, groups Files and WinWrap
// Copyright Alexander Liss
#ifndef __FILEWIN_H__
#define __FILEWIN_H__
#include "kernel.h"
#include "event.h"
// blocking operations
class File: public Kernel
{
File(const File&);
File& operator=(const File&);
public:
File(
LPCTSTR lpFileName,
DWORD dwDesiredAccess = GENERIC_READ | GENERIC_WRITE,
DWORD dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE, // A DEVICE NEEDS EXCLUSIVE = 0
DWORD dwCreationDisposition = OPEN_EXISTING,
DWORD dwFlagsAndAttributes= FILE_FLAG_OVERLAPPED | FILE_FLAG_RANDOM_ACCESS, // OVERLAPPED - CANOT USE BLOCKING READ AND WRITE
LPSECURITY_ATTRIBUTES lpSA = 0,
HANDLE hTemplateFile = 0
);
~File(){}
BOOL get_type(DWORD& type);
BOOL get_size(DWORD& FileSize );
BOOL get_size(ULARGE_INTEGER& FileSize );
BOOL set_pointer(
LONG DistanceToMove, // bytes to move pointer
DWORD dwMoveMethod = FILE_BEGIN // starting point
);
BOOL set_pointer(
LARGE_INTEGER DistanceToMove, // bytes to move pointer
DWORD dwMoveMethod = FILE_BEGIN // starting point
);
BOOL set_file_end();
BOOL current_pointer(DWORD& place);
BOOL current_pointer(ULARGE_INTEGER& place);
// only if overlapped flag is not set
BOOL read(
DWORD& bytesActual,
LPVOID lpBuffer,
DWORD dwBytesLimit
);
// only if overlapped flag is not set
BOOL write(
DWORD& bytesActual,
LPVOID lpBuffer,
DWORD dwBytesSize
);
BOOL flush();
BOOL lock(
DWORD dwFileOffsetLow,
DWORD dwFileOffsetHigh,
DWORD nNumberOfBytesToLockLow,
DWORD nNumberOfBytesToLockHigh
);
BOOL unlock(
DWORD dwFileOffsetLow,
DWORD dwFileOffsetHigh,
DWORD nNumberOfBytesToLockLow,
DWORD nNumberOfBytesToLockHigh
);
// calling thread only
BOOL cancel();
};
// can be used with file, pipe, device:
// AsyncFileOperation
class AsyncFileOperation
{
AsyncFileOperation(const AsyncFileOperation&);
AsyncFileOperation& operator=(const AsyncFileOperation&);
public:
AsyncFileOperation(){clear();}
AsyncFileOperation(Kernel& z){clear();set(z);}
virtual ~AsyncFileOperation(){}
int set(Kernel& z){handle=z.get_handle();return 0;}
int put_pointer(DWORD offset,DWORD offset_high=0)
{overlapped.Offset=offset;overlapped.OffsetHigh=offset_high;return 0;}
int get_pointer(DWORD& offset,DWORD& offset_high)
{offset=overlapped.Offset;offset_high=overlapped.OffsetHigh;return 0;}
BOOL lock(
DWORD nNumberOfBytesToLockLow,
DWORD nNumberOfBytesToLockHigh,
DWORD dwFlags // lock options
);
BOOL unlock(
DWORD nNumberOfBytesToLockLow,
DWORD nNumberOfBytesToLockHigh
);
BOOL get_result(DWORD& dwTransfer,BOOL bWait=TRUE);
protected:
HANDLE handle;
OVERLAPPED overlapped;
void clear();
};
// AsyncReadWrite
class AsyncReadWrite: public AsyncFileOperation
{
AsyncReadWrite(const AsyncReadWrite&);
AsyncReadWrite& operator=(const AsyncReadWrite&);
public:
AsyncReadWrite(){}
AsyncReadWrite(Kernel& z):AsyncFileOperation(z){}
AsyncReadWrite(Kernel& f, Event& e):AsyncFileOperation(f){set(e);}
// manual reset event !
int set(Event& z){overlapped.hEvent=z.get_handle();return 0;}
// sets event to non-signaled state at operation's start
BOOL read(DWORD& BytesActual,LPVOID lpBuffer, DWORD dwBytesLimit);
// sets event to non-signaled state at operation's start
BOOL write(DWORD& BytesActual,LPVOID lpBuffer,DWORD dwBytes);
// blocking
BOOL read_loop(DWORD& BytesActual,LPVOID lpBuffer, DWORD dwBytesLimit,
DWORD timeout_milliseconds, DWORD wait_slice_milliseconds);
// blocking
BOOL write_loop(DWORD& BytesActual,LPVOID lpBuffer,DWORD dwBytes,
DWORD timeout_milliseconds, DWORD wait_slice_milliseconds);
};
// AsyncReadWriteEx
class AsyncReadWriteEx: public AsyncFileOperation
{
AsyncReadWriteEx(const AsyncReadWriteEx&);
AsyncReadWriteEx& operator=(const AsyncReadWriteEx&);
public:
AsyncReadWriteEx():completion_routine(0){}
AsyncReadWriteEx(Kernel& z):AsyncFileOperation(z),completion_routine(0){}
AsyncReadWriteEx(Kernel& f, LPOVERLAPPED_COMPLETION_ROUTINE z):
AsyncFileOperation(f){set(z);}
int set(LPOVERLAPPED_COMPLETION_ROUTINE z){completion_routine=z;return 0;}
// one or the other, manual reset event
int set_data(LPVOID z){overlapped.hEvent=(HANDLE)z;return 0;}
int set(Event& z){overlapped.hEvent=z.get_handle();return 0;}
BOOL read(LPVOID lpBuffer, DWORD dwBytesLimit);
BOOL write(LPVOID lpBuffer,DWORD dwBytes);
private:
VOID (CALLBACK* completion_routine) (DWORD dwErrorCode,DWORD dwNumberOfBytesTransfered,LPOVERLAPPED lpOverlapped);
};
#endif