Browse Source

Use size_t for lengths in stream objects

Provides safety against them accidentally becoming negative because
of bugs in the calculations.

Also does the same to CharArray and friends as they were strongly
connection to the stream objects.

(cherry picked from commit 0943c006c7)
tags/v1.10.1
Pierre Ossman 4 years ago
parent
commit
f287032d36

+ 10
- 10
common/rdr/FdInStream.cxx View File

enum { DEFAULT_BUF_SIZE = 8192, enum { DEFAULT_BUF_SIZE = 8192,
MIN_BULK_SIZE = 1024 }; MIN_BULK_SIZE = 1024 };


FdInStream::FdInStream(int fd_, int timeoutms_, int bufSize_,
FdInStream::FdInStream(int fd_, int timeoutms_, size_t bufSize_,
bool closeWhenDone_) bool closeWhenDone_)
: fd(fd_), closeWhenDone(closeWhenDone_), : fd(fd_), closeWhenDone(closeWhenDone_),
timeoutms(timeoutms_), blockCallback(0), timeoutms(timeoutms_), blockCallback(0),
} }


FdInStream::FdInStream(int fd_, FdInStreamBlockCallback* blockCallback_, FdInStream::FdInStream(int fd_, FdInStreamBlockCallback* blockCallback_,
int bufSize_)
size_t bufSize_)
: fd(fd_), timeoutms(0), blockCallback(blockCallback_), : fd(fd_), timeoutms(0), blockCallback(blockCallback_),
timing(false), timeWaitedIn100us(5), timedKbits(0), timing(false), timeWaitedIn100us(5), timedKbits(0),
bufSize(bufSize_ ? bufSize_ : DEFAULT_BUF_SIZE), offset(0) bufSize(bufSize_ ? bufSize_ : DEFAULT_BUF_SIZE), offset(0)
timeoutms = 0; timeoutms = 0;
} }


int FdInStream::pos()
size_t FdInStream::pos()
{ {
return offset + ptr - start; return offset + ptr - start;
} }


void FdInStream::readBytes(void* data, int length)
void FdInStream::readBytes(void* data, size_t length)
{ {
if (length < MIN_BULK_SIZE) { if (length < MIN_BULK_SIZE) {
InStream::readBytes(data, length); InStream::readBytes(data, length);


U8* dataPtr = (U8*)data; U8* dataPtr = (U8*)data;


int n = end - ptr;
size_t n = end - ptr;
if (n > length) n = length; if (n > length) n = length;


memcpy(dataPtr, ptr, n); memcpy(dataPtr, ptr, n);
} }




int FdInStream::overrun(int itemSize, int nItems, bool wait)
size_t FdInStream::overrun(size_t itemSize, size_t nItems, bool wait)
{ {
if (itemSize > bufSize) if (itemSize > bufSize)
throw Exception("FdInStream overrun: max itemSize exceeded"); throw Exception("FdInStream overrun: max itemSize exceeded");
end -= ptr - start; end -= ptr - start;
ptr = start; ptr = start;


int bytes_to_read;
size_t bytes_to_read;
while (end < start + itemSize) { while (end < start + itemSize) {
bytes_to_read = start + bufSize - end; bytes_to_read = start + bufSize - end;
if (!timing) { if (!timing) {
// bytes is ineffecient. // bytes is ineffecient.
bytes_to_read = vncmin(bytes_to_read, vncmax(itemSize*nItems, 8)); bytes_to_read = vncmin(bytes_to_read, vncmax(itemSize*nItems, 8));
} }
int n = readWithTimeoutOrCallback((U8*)end, bytes_to_read, wait);
size_t n = readWithTimeoutOrCallback((U8*)end, bytes_to_read, wait);
if (n == 0) return 0; if (n == 0) return 0;
end += n; end += n;
} }


if (itemSize * nItems > end - ptr)
if (itemSize * nItems > (size_t)(end - ptr))
nItems = (end - ptr) / itemSize; nItems = (end - ptr) / itemSize;


return nItems; return nItems;
// returning EINTR. // returning EINTR.
// //


int FdInStream::readWithTimeoutOrCallback(void* buf, int len, bool wait)
size_t FdInStream::readWithTimeoutOrCallback(void* buf, size_t len, bool wait)
{ {
struct timeval before, after; struct timeval before, after;
if (timing) if (timing)

+ 9
- 8
common/rdr/FdInStream.h View File



public: public:


FdInStream(int fd, int timeoutms=-1, int bufSize=0,
FdInStream(int fd, int timeoutms=-1, size_t bufSize=0,
bool closeWhenDone_=false); bool closeWhenDone_=false);
FdInStream(int fd, FdInStreamBlockCallback* blockCallback, int bufSize=0);
FdInStream(int fd, FdInStreamBlockCallback* blockCallback,
size_t bufSize=0);
virtual ~FdInStream(); virtual ~FdInStream();


void setTimeout(int timeoutms); void setTimeout(int timeoutms);
void setBlockCallback(FdInStreamBlockCallback* blockCallback); void setBlockCallback(FdInStreamBlockCallback* blockCallback);
int getFd() { return fd; } int getFd() { return fd; }
int pos();
void readBytes(void* data, int length);
size_t pos();
void readBytes(void* data, size_t length);


void startTiming(); void startTiming();
void stopTiming(); void stopTiming();
unsigned int timeWaited() { return timeWaitedIn100us; } unsigned int timeWaited() { return timeWaitedIn100us; }


protected: protected:
int overrun(int itemSize, int nItems, bool wait);
size_t overrun(size_t itemSize, size_t nItems, bool wait);


private: private:
int readWithTimeoutOrCallback(void* buf, int len, bool wait=true);
size_t readWithTimeoutOrCallback(void* buf, size_t len, bool wait=true);


int fd; int fd;
bool closeWhenDone; bool closeWhenDone;
unsigned int timeWaitedIn100us; unsigned int timeWaitedIn100us;
unsigned int timedKbits; unsigned int timedKbits;


int bufSize;
int offset;
size_t bufSize;
size_t offset;
U8* start; U8* start;
}; };



+ 10
- 10
common/rdr/FdOutStream.cxx View File



enum { DEFAULT_BUF_SIZE = 16384 }; enum { DEFAULT_BUF_SIZE = 16384 };


FdOutStream::FdOutStream(int fd_, bool blocking_, int timeoutms_, int bufSize_)
FdOutStream::FdOutStream(int fd_, bool blocking_, int timeoutms_, size_t bufSize_)
: fd(fd_), blocking(blocking_), timeoutms(timeoutms_), : fd(fd_), blocking(blocking_), timeoutms(timeoutms_),
bufSize(bufSize_ ? bufSize_ : DEFAULT_BUF_SIZE), offset(0) bufSize(bufSize_ ? bufSize_ : DEFAULT_BUF_SIZE), offset(0)
{ {
blocking = blocking_; blocking = blocking_;
} }


int FdOutStream::length()
size_t FdOutStream::length()
{ {
return offset + ptr - sentUpTo; return offset + ptr - sentUpTo;
} }
void FdOutStream::flush() void FdOutStream::flush()
{ {
while (sentUpTo < ptr) { while (sentUpTo < ptr) {
int n = writeWithTimeout((const void*) sentUpTo,
ptr - sentUpTo,
blocking? timeoutms : 0);
size_t n = writeWithTimeout((const void*) sentUpTo,
ptr - sentUpTo,
blocking? timeoutms : 0);


// Timeout? // Timeout?
if (n == 0) { if (n == 0) {
} }




int FdOutStream::overrun(int itemSize, int nItems)
size_t FdOutStream::overrun(size_t itemSize, size_t nItems)
{ {
if (itemSize > bufSize) if (itemSize > bufSize)
throw Exception("FdOutStream overrun: max itemSize exceeded"); throw Exception("FdOutStream overrun: max itemSize exceeded");
flush(); flush();


// Still not enough space? // Still not enough space?
if (itemSize > end - ptr) {
if (itemSize > (size_t)(end - ptr)) {
// Can we shuffle things around? // Can we shuffle things around?
// (don't do this if it gains us less than 25%) // (don't do this if it gains us less than 25%)
if ((sentUpTo - start > bufSize / 4) &&
if (((size_t)(sentUpTo - start) > bufSize / 4) &&
(itemSize < bufSize - (ptr - sentUpTo))) { (itemSize < bufSize - (ptr - sentUpTo))) {
memmove(start, sentUpTo, ptr - sentUpTo); memmove(start, sentUpTo, ptr - sentUpTo);
ptr = start + (ptr - sentUpTo); ptr = start + (ptr - sentUpTo);
} }


// Can we fit all the items asked for? // Can we fit all the items asked for?
if (itemSize * nItems > end - ptr)
if (itemSize * nItems > (size_t)(end - ptr))
nItems = (end - ptr) / itemSize; nItems = (end - ptr) / itemSize;


return nItems; return nItems;
// select() and send() returning EINTR. // select() and send() returning EINTR.
// //


int FdOutStream::writeWithTimeout(const void* data, int length, int timeoutms)
size_t FdOutStream::writeWithTimeout(const void* data, size_t length, int timeoutms)
{ {
int n; int n;



+ 6
- 6
common/rdr/FdOutStream.h View File



public: public:


FdOutStream(int fd, bool blocking=true, int timeoutms=-1, int bufSize=0);
FdOutStream(int fd, bool blocking=true, int timeoutms=-1, size_t bufSize=0);
virtual ~FdOutStream(); virtual ~FdOutStream();


void setTimeout(int timeoutms); void setTimeout(int timeoutms);
int getFd() { return fd; } int getFd() { return fd; }


void flush(); void flush();
int length();
size_t length();


int bufferUsage(); int bufferUsage();


unsigned getIdleTime(); unsigned getIdleTime();


private: private:
int overrun(int itemSize, int nItems);
int writeWithTimeout(const void* data, int length, int timeoutms);
size_t overrun(size_t itemSize, size_t nItems);
size_t writeWithTimeout(const void* data, size_t length, int timeoutms);
int fd; int fd;
bool blocking; bool blocking;
int timeoutms; int timeoutms;
int bufSize;
int offset;
size_t bufSize;
size_t offset;
U8* start; U8* start;
U8* sentUpTo; U8* sentUpTo;
struct timeval lastWrite; struct timeval lastWrite;

+ 4
- 4
common/rdr/FileInStream.cxx View File

ptr = end = b; ptr = end = b;
} }


int FileInStream::pos()
size_t FileInStream::pos()
{ {
if (!file) if (!file)
throw Exception("File is not open"); throw Exception("File is not open");
return ftell(file) + ptr - b; return ftell(file) + ptr - b;
} }


int FileInStream::overrun(int itemSize, int nItems, bool wait)
size_t FileInStream::overrun(size_t itemSize, size_t nItems, bool wait)
{ {
if (itemSize > (int)sizeof(b))
if (itemSize > sizeof(b))
throw Exception("FileInStream overrun: max itemSize exceeded"); throw Exception("FileInStream overrun: max itemSize exceeded");


if (end - ptr != 0) if (end - ptr != 0)
end += b + sizeof(b) - end; end += b + sizeof(b) - end;
} }


if (itemSize * nItems > end - ptr)
if (itemSize * nItems > (size_t)(end - ptr))
nItems = (end - ptr) / itemSize; nItems = (end - ptr) / itemSize;


return nItems; return nItems;

+ 2
- 2
common/rdr/FileInStream.h View File



void reset(void); void reset(void);


int pos();
size_t pos();


protected: protected:
int overrun(int itemSize, int nItems, bool wait = true);
size_t overrun(size_t itemSize, size_t nItems, bool wait = true);


private: private:
U8 b[131072]; U8 b[131072];

+ 10
- 10
common/rdr/HexInStream.cxx View File



static inline int min(int a, int b) {return a<b ? a : b;} static inline int min(int a, int b) {return a<b ? a : b;}


HexInStream::HexInStream(InStream& is, int bufSize_)
HexInStream::HexInStream(InStream& is, size_t bufSize_)
: bufSize(bufSize_ ? bufSize_ : DEFAULT_BUF_LEN), offset(0), in_stream(is) : bufSize(bufSize_ ? bufSize_ : DEFAULT_BUF_LEN), offset(0), in_stream(is)
{ {
ptr = end = start = new U8[bufSize]; ptr = end = start = new U8[bufSize];
return true; return true;
} }


bool HexInStream::hexStrToBin(const char* s, char** data, int* length) {
int l=strlen(s);
bool HexInStream::hexStrToBin(const char* s, char** data, size_t* length) {
size_t l=strlen(s);
if ((l % 2) == 0) { if ((l % 2) == 0) {
delete [] *data; delete [] *data;
*data = 0; *length = 0; *data = 0; *length = 0;
return true; return true;
*data = new char[l/2]; *data = new char[l/2];
*length = l/2; *length = l/2;
for(int i=0;i<l;i+=2) {
for(size_t i=0;i<l;i+=2) {
int byte = 0; int byte = 0;
if (!readHexAndShift(s[i], &byte) || if (!readHexAndShift(s[i], &byte) ||
!readHexAndShift(s[i+1], &byte)) !readHexAndShift(s[i+1], &byte))
} }




int HexInStream::pos() {
size_t HexInStream::pos() {
return offset + ptr - start; return offset + ptr - start;
} }


int HexInStream::overrun(int itemSize, int nItems, bool wait) {
size_t HexInStream::overrun(size_t itemSize, size_t nItems, bool wait) {
if (itemSize > bufSize) if (itemSize > bufSize)
throw Exception("HexInStream overrun: max itemSize exceeded"); throw Exception("HexInStream overrun: max itemSize exceeded");


ptr = start; ptr = start;


while (end < ptr + itemSize) { while (end < ptr + itemSize) {
int n = in_stream.check(2, 1, wait);
size_t n = in_stream.check(2, 1, wait);
if (n == 0) return 0; if (n == 0) return 0;
const U8* iptr = in_stream.getptr(); const U8* iptr = in_stream.getptr();
const U8* eptr = in_stream.getend(); const U8* eptr = in_stream.getend();
int length = min((eptr - iptr)/2, start + bufSize - end);
size_t length = min((eptr - iptr)/2, start + bufSize - end);


U8* optr = (U8*) end; U8* optr = (U8*) end;
for (int i=0; i<length; i++) {
for (size_t i=0; i<length; i++) {
int v = 0; int v = 0;
readHexAndShift(iptr[i*2], &v); readHexAndShift(iptr[i*2], &v);
readHexAndShift(iptr[i*2+1], &v); readHexAndShift(iptr[i*2+1], &v);
end += length; end += length;
} }


if (itemSize * nItems > end - ptr)
if (itemSize * nItems > (size_t)(end - ptr))
nItems = (end - ptr) / itemSize; nItems = (end - ptr) / itemSize;


return nItems; return nItems;

+ 6
- 6
common/rdr/HexInStream.h View File

class HexInStream : public InStream { class HexInStream : public InStream {
public: public:


HexInStream(InStream& is, int bufSize=0);
HexInStream(InStream& is, size_t bufSize=0);
virtual ~HexInStream(); virtual ~HexInStream();


int pos();
size_t pos();


static bool readHexAndShift(char c, int* v); static bool readHexAndShift(char c, int* v);
static bool hexStrToBin(const char* s, char** data, int* length);
static bool hexStrToBin(const char* s, char** data, size_t* length);


protected: protected:
int overrun(int itemSize, int nItems, bool wait);
size_t overrun(size_t itemSize, size_t nItems, bool wait);


private: private:
int bufSize;
size_t bufSize;
U8* start; U8* start;
int offset;
size_t offset;


InStream& in_stream; InStream& in_stream;
}; };

+ 10
- 10
common/rdr/HexOutStream.cxx View File



const int DEFAULT_BUF_LEN = 16384; const int DEFAULT_BUF_LEN = 16384;


static inline int min(int a, int b) {return a<b ? a : b;}
static inline size_t min(size_t a, size_t b) {return a<b ? a : b;}


HexOutStream::HexOutStream(OutStream& os, int buflen)
HexOutStream::HexOutStream(OutStream& os, size_t buflen)
: out_stream(os), offset(0), bufSize(buflen ? buflen : DEFAULT_BUF_LEN) : out_stream(os), offset(0), bufSize(buflen ? buflen : DEFAULT_BUF_LEN)
{ {
if (bufSize % 2) if (bufSize % 2)
throw rdr::Exception("intToHex failed"); throw rdr::Exception("intToHex failed");
} }


char* HexOutStream::binToHexStr(const char* data, int length) {
char* HexOutStream::binToHexStr(const char* data, size_t length) {
char* buffer = new char[length*2+1]; char* buffer = new char[length*2+1];
for (int i=0; i<length; i++) {
for (size_t i=0; i<length; i++) {
buffer[i*2] = intToHex((data[i] >> 4) & 15); buffer[i*2] = intToHex((data[i] >> 4) & 15);
buffer[i*2+1] = intToHex((data[i] & 15)); buffer[i*2+1] = intToHex((data[i] & 15));
if (!buffer[i*2] || !buffer[i*2+1]) { if (!buffer[i*2] || !buffer[i*2+1]) {
out_stream.check(2); out_stream.check(2);
U8* optr = out_stream.getptr(); U8* optr = out_stream.getptr();
U8* oend = out_stream.getend(); U8* oend = out_stream.getend();
int length = min(ptr-pos, (oend-optr)/2);
size_t length = min(ptr-pos, (oend-optr)/2);


for (int i=0; i<length; i++) {
for (size_t i=0; i<length; i++) {
optr[i*2] = intToHex((pos[i] >> 4) & 0xf); optr[i*2] = intToHex((pos[i] >> 4) & 0xf);
optr[i*2+1] = intToHex(pos[i] & 0xf); optr[i*2+1] = intToHex(pos[i] & 0xf);
} }
ptr = start; ptr = start;
} }


int HexOutStream::length()
size_t HexOutStream::length()
{ {
return offset + ptr - start; return offset + ptr - start;
} }
out_stream.flush(); out_stream.flush();
} }


int
HexOutStream::overrun(int itemSize, int nItems) {
size_t
HexOutStream::overrun(size_t itemSize, size_t nItems) {
if (itemSize > bufSize) if (itemSize > bufSize)
throw Exception("HexOutStream overrun: max itemSize exceeded"); throw Exception("HexOutStream overrun: max itemSize exceeded");


writeBuffer(); writeBuffer();


if (itemSize * nItems > end - ptr)
if (itemSize * nItems > (size_t)(end - ptr))
nItems = (end - ptr) / itemSize; nItems = (end - ptr) / itemSize;


return nItems; return nItems;

+ 6
- 6
common/rdr/HexOutStream.h View File

class HexOutStream : public OutStream { class HexOutStream : public OutStream {
public: public:


HexOutStream(OutStream& os, int buflen=0);
HexOutStream(OutStream& os, size_t buflen=0);
virtual ~HexOutStream(); virtual ~HexOutStream();


void flush(); void flush();
int length();
size_t length();


static char intToHex(int i); static char intToHex(int i);
static char* binToHexStr(const char* data, int length);
static char* binToHexStr(const char* data, size_t length);


private: private:
void writeBuffer(); void writeBuffer();
int overrun(int itemSize, int nItems);
size_t overrun(size_t itemSize, size_t nItems);


OutStream& out_stream; OutStream& out_stream;


U8* start; U8* start;
int offset;
int bufSize;
size_t offset;
size_t bufSize;
}; };


} }

+ 8
- 8
common/rdr/InStream.h View File

// for the bytes, zero is returned if the bytes are not immediately // for the bytes, zero is returned if the bytes are not immediately
// available. // available.


inline int check(int itemSize, int nItems=1, bool wait=true)
inline size_t check(size_t itemSize, size_t nItems=1, bool wait=true)
{ {
if (ptr + itemSize * nItems > end) { if (ptr + itemSize * nItems > end) {
if (ptr + itemSize > end) if (ptr + itemSize > end)
// be read without blocking. It returns true if this is the case, false // be read without blocking. It returns true if this is the case, false
// otherwise. The length must be "small" (less than the buffer size). // otherwise. The length must be "small" (less than the buffer size).


inline bool checkNoWait(int length) { return check(length, 1, false)!=0; }
inline bool checkNoWait(size_t length) { return check(length, 1, false)!=0; }


// readU/SN() methods read unsigned and signed N-bit integers. // readU/SN() methods read unsigned and signed N-bit integers.




static U32 maxStringLength; static U32 maxStringLength;


inline void skip(int bytes) {
inline void skip(size_t bytes) {
while (bytes > 0) { while (bytes > 0) {
int n = check(1, bytes);
size_t n = check(1, bytes);
ptr += n; ptr += n;
bytes -= n; bytes -= n;
} }


// readBytes() reads an exact number of bytes. // readBytes() reads an exact number of bytes.


void readBytes(void* data, int length) {
void readBytes(void* data, size_t length) {
U8* dataPtr = (U8*)data; U8* dataPtr = (U8*)data;
U8* dataEnd = dataPtr + length; U8* dataEnd = dataPtr + length;
while (dataPtr < dataEnd) { while (dataPtr < dataEnd) {
int n = check(1, dataEnd - dataPtr);
size_t n = check(1, dataEnd - dataPtr);
memcpy(dataPtr, ptr, n); memcpy(dataPtr, ptr, n);
ptr += n; ptr += n;
dataPtr += n; dataPtr += n;


// pos() returns the position in the stream. // pos() returns the position in the stream.


virtual int pos() = 0;
virtual size_t pos() = 0;


// getptr(), getend() and setptr() are "dirty" methods which allow you to // getptr(), getend() and setptr() are "dirty" methods which allow you to
// manipulate the buffer directly. This is useful for a stream which is a // manipulate the buffer directly. This is useful for a stream which is a
// instead of blocking to wait for the bytes, zero is returned if the bytes // instead of blocking to wait for the bytes, zero is returned if the bytes
// are not immediately available. // are not immediately available.


virtual int overrun(int itemSize, int nItems, bool wait=true) = 0;
virtual size_t overrun(size_t itemSize, size_t nItems, bool wait=true) = 0;


protected: protected:



+ 4
- 4
common/rdr/MemInStream.h View File



public: public:


MemInStream(const void* data, int len, bool deleteWhenDone_=false)
MemInStream(const void* data, size_t len, bool deleteWhenDone_=false)
: start((const U8*)data), deleteWhenDone(deleteWhenDone_) : start((const U8*)data), deleteWhenDone(deleteWhenDone_)
{ {
ptr = start; ptr = start;
delete [] start; delete [] start;
} }


int pos() { return ptr - start; }
void reposition(int pos) { ptr = start + pos; }
size_t pos() { return ptr - start; }
void reposition(size_t pos) { ptr = start + pos; }


private: private:


int overrun(int itemSize, int nItems, bool wait) { throw EndOfStream(); }
size_t overrun(size_t itemSize, size_t nItems, bool wait) { throw EndOfStream(); }
const U8* start; const U8* start;
bool deleteWhenDone; bool deleteWhenDone;
}; };

+ 6
- 6
common/rdr/MemOutStream.h View File

delete [] start; delete [] start;
} }


void writeBytes(const void* data, int length) {
void writeBytes(const void* data, size_t length) {
check(length); check(length);
memcpy(ptr, data, length); memcpy(ptr, data, length);
ptr += length; ptr += length;
} }


int length() { return ptr - start; }
size_t length() { return ptr - start; }
void clear() { ptr = start; }; void clear() { ptr = start; };
void clearAndZero() { memset(start, 0, ptr-start); clear(); } void clearAndZero() { memset(start, 0, ptr-start); clear(); }
void reposition(int pos) { ptr = start + pos; }
void reposition(size_t pos) { ptr = start + pos; }


// data() returns a pointer to the buffer. // data() returns a pointer to the buffer.


// overrun() either doubles the buffer or adds enough space for nItems of // overrun() either doubles the buffer or adds enough space for nItems of
// size itemSize bytes. // size itemSize bytes.


int overrun(int itemSize, int nItems) {
int len = ptr - start + itemSize * nItems;
if (len < (end - start) * 2)
size_t overrun(size_t itemSize, size_t nItems) {
size_t len = ptr - start + itemSize * nItems;
if (len < (size_t)(end - start) * 2)
len = (end - start) * 2; len = (end - start) * 2;


U8* newStart = new U8[len]; U8* newStart = new U8[len];

+ 10
- 10
common/rdr/OutStream.h View File

// itemSize bytes. Returns the number of items which fit (up to a maximum // itemSize bytes. Returns the number of items which fit (up to a maximum
// of nItems). // of nItems).


inline int check(int itemSize, int nItems=1)
inline size_t check(size_t itemSize, size_t nItems=1)
{ {
if (ptr + itemSize * nItems > end) { if (ptr + itemSize * nItems > end) {
if (ptr + itemSize > end) if (ptr + itemSize > end)
writeBytes(str, len); writeBytes(str, len);
} }


inline void pad(int bytes) {
inline void pad(size_t bytes) {
while (bytes-- > 0) writeU8(0); while (bytes-- > 0) writeU8(0);
} }


inline void skip(int bytes) {
inline void skip(size_t bytes) {
while (bytes > 0) { while (bytes > 0) {
int n = check(1, bytes);
size_t n = check(1, bytes);
ptr += n; ptr += n;
bytes -= n; bytes -= n;
} }


// writeBytes() writes an exact number of bytes. // writeBytes() writes an exact number of bytes.


void writeBytes(const void* data, int length) {
void writeBytes(const void* data, size_t length) {
const U8* dataPtr = (const U8*)data; const U8* dataPtr = (const U8*)data;
const U8* dataEnd = dataPtr + length; const U8* dataEnd = dataPtr + length;
while (dataPtr < dataEnd) { while (dataPtr < dataEnd) {
int n = check(1, dataEnd - dataPtr);
size_t n = check(1, dataEnd - dataPtr);
memcpy(ptr, dataPtr, n); memcpy(ptr, dataPtr, n);
ptr += n; ptr += n;
dataPtr += n; dataPtr += n;


// copyBytes() efficiently transfers data between streams // copyBytes() efficiently transfers data between streams


void copyBytes(InStream* is, int length) {
void copyBytes(InStream* is, size_t length) {
while (length > 0) { while (length > 0) {
int n = check(1, length);
size_t n = check(1, length);
is->readBytes(ptr, n); is->readBytes(ptr, n);
ptr += n; ptr += n;
length -= n; length -= n;


// length() returns the length of the stream. // length() returns the length of the stream.


virtual int length() = 0;
virtual size_t length() = 0;


// flush() requests that the stream be flushed. // flush() requests that the stream be flushed.


// the number of items which fit (up to a maximum of nItems). itemSize is // the number of items which fit (up to a maximum of nItems). itemSize is
// supposed to be "small" (a few bytes). // supposed to be "small" (a few bytes).


virtual int overrun(int itemSize, int nItems) = 0;
virtual size_t overrun(size_t itemSize, size_t nItems) = 0;


protected: protected:



+ 7
- 7
common/rdr/RandomStream.cxx View File



using namespace rdr; using namespace rdr;


const int DEFAULT_BUF_LEN = 256;
const size_t DEFAULT_BUF_LEN = 256;


unsigned int RandomStream::seed; unsigned int RandomStream::seed;


#endif #endif
} }


int RandomStream::pos() {
size_t RandomStream::pos() {
return offset + ptr - start; return offset + ptr - start;
} }


int RandomStream::overrun(int itemSize, int nItems, bool wait) {
size_t RandomStream::overrun(size_t itemSize, size_t nItems, bool wait) {
if (itemSize > DEFAULT_BUF_LEN) if (itemSize > DEFAULT_BUF_LEN)
throw Exception("RandomStream overrun: max itemSize exceeded"); throw Exception("RandomStream overrun: max itemSize exceeded");


offset += ptr - start; offset += ptr - start;
ptr = start; ptr = start;


int length = start + DEFAULT_BUF_LEN - end;
size_t length = start + DEFAULT_BUF_LEN - end;


#ifdef RFB_HAVE_WINCRYPT #ifdef RFB_HAVE_WINCRYPT
if (provider) { if (provider) {
#else #else
#ifndef WIN32 #ifndef WIN32
if (fp) { if (fp) {
int n = fread((U8*)end, length, 1, fp);
size_t n = fread((U8*)end, length, 1, fp);
if (n != 1) if (n != 1)
throw rdr::SystemException("reading /dev/urandom or /dev/random failed", throw rdr::SystemException("reading /dev/urandom or /dev/random failed",
errno); errno);
{ {
#endif #endif
#endif #endif
for (int i=0; i<length; i++)
for (size_t i=0; i<length; i++)
*(U8*)end++ = (int) (256.0*rand()/(RAND_MAX+1.0)); *(U8*)end++ = (int) (256.0*rand()/(RAND_MAX+1.0));
} }


if (itemSize * nItems > end - ptr)
if (itemSize * nItems > (size_t)(end - ptr))
nItems = (end - ptr) / itemSize; nItems = (end - ptr) / itemSize;


return nItems; return nItems;

+ 3
- 3
common/rdr/RandomStream.h View File

RandomStream(); RandomStream();
virtual ~RandomStream(); virtual ~RandomStream();


int pos();
size_t pos();


protected: protected:
int overrun(int itemSize, int nItems, bool wait);
size_t overrun(size_t itemSize, size_t nItems, bool wait);


private: private:
U8* start; U8* start;
int offset;
size_t offset;


static unsigned int seed; static unsigned int seed;
#ifdef RFB_HAVE_WINCRYPT #ifdef RFB_HAVE_WINCRYPT

+ 5
- 5
common/rdr/TLSInStream.cxx View File

delete[] start; delete[] start;
} }


int TLSInStream::pos()
size_t TLSInStream::pos()
{ {
return offset + ptr - start; return offset + ptr - start;
} }


int TLSInStream::overrun(int itemSize, int nItems, bool wait)
size_t TLSInStream::overrun(size_t itemSize, size_t nItems, bool wait)
{ {
if (itemSize > bufSize) if (itemSize > bufSize)
throw Exception("TLSInStream overrun: max itemSize exceeded"); throw Exception("TLSInStream overrun: max itemSize exceeded");
ptr = start; ptr = start;


while (end < start + itemSize) { while (end < start + itemSize) {
int n = readTLS((U8*) end, start + bufSize - end, wait);
size_t n = readTLS((U8*) end, start + bufSize - end, wait);
if (!wait && n == 0) if (!wait && n == 0)
return 0; return 0;
end += n; end += n;
} }


if (itemSize * nItems > end - ptr)
if (itemSize * nItems > (size_t)(end - ptr))
nItems = (end - ptr) / itemSize; nItems = (end - ptr) / itemSize;


return nItems; return nItems;
} }


int TLSInStream::readTLS(U8* buf, int len, bool wait)
size_t TLSInStream::readTLS(U8* buf, size_t len, bool wait)
{ {
int n; int n;



+ 5
- 5
common/rdr/TLSInStream.h View File

TLSInStream(InStream* in, gnutls_session_t session); TLSInStream(InStream* in, gnutls_session_t session);
virtual ~TLSInStream(); virtual ~TLSInStream();


int pos();
size_t pos();


private: private:
int overrun(int itemSize, int nItems, bool wait);
int readTLS(U8* buf, int len, bool wait);
size_t overrun(size_t itemSize, size_t nItems, bool wait);
size_t readTLS(U8* buf, size_t len, bool wait);
static ssize_t pull(gnutls_transport_ptr_t str, void* data, size_t size); static ssize_t pull(gnutls_transport_ptr_t str, void* data, size_t size);


gnutls_session_t session; gnutls_session_t session;
InStream* in; InStream* in;
int bufSize;
int offset;
size_t bufSize;
size_t offset;
U8* start; U8* start;
}; };
}; };

+ 5
- 5
common/rdr/TLSOutStream.cxx View File

delete [] start; delete [] start;
} }


int TLSOutStream::length()
size_t TLSOutStream::length()
{ {
return offset + ptr - start; return offset + ptr - start;
} }
{ {
U8* sentUpTo = start; U8* sentUpTo = start;
while (sentUpTo < ptr) { while (sentUpTo < ptr) {
int n = writeTLS(sentUpTo, ptr - sentUpTo);
size_t n = writeTLS(sentUpTo, ptr - sentUpTo);
sentUpTo += n; sentUpTo += n;
offset += n; offset += n;
} }
out->flush(); out->flush();
} }


int TLSOutStream::overrun(int itemSize, int nItems)
size_t TLSOutStream::overrun(size_t itemSize, size_t nItems)
{ {
if (itemSize > bufSize) if (itemSize > bufSize)
throw Exception("TLSOutStream overrun: max itemSize exceeded"); throw Exception("TLSOutStream overrun: max itemSize exceeded");


flush(); flush();


if (itemSize * nItems > end - ptr)
if (itemSize * nItems > (size_t)(end - ptr))
nItems = (end - ptr) / itemSize; nItems = (end - ptr) / itemSize;


return nItems; return nItems;
} }


int TLSOutStream::writeTLS(const U8* data, int length)
size_t TLSOutStream::writeTLS(const U8* data, size_t length)
{ {
int n; int n;



+ 5
- 5
common/rdr/TLSOutStream.h View File

virtual ~TLSOutStream(); virtual ~TLSOutStream();


void flush(); void flush();
int length();
size_t length();


protected: protected:
int overrun(int itemSize, int nItems);
size_t overrun(size_t itemSize, size_t nItems);


private: private:
int writeTLS(const U8* data, int length);
size_t writeTLS(const U8* data, size_t length);
static ssize_t push(gnutls_transport_ptr_t str, const void* data, size_t size); static ssize_t push(gnutls_transport_ptr_t str, const void* data, size_t size);


gnutls_session_t session; gnutls_session_t session;
OutStream* out; OutStream* out;
int bufSize;
size_t bufSize;
U8* start; U8* start;
int offset;
size_t offset;
}; };
}; };



+ 8
- 8
common/rdr/ZlibInStream.cxx View File



enum { DEFAULT_BUF_SIZE = 16384 }; enum { DEFAULT_BUF_SIZE = 16384 };


ZlibInStream::ZlibInStream(int bufSize_)
ZlibInStream::ZlibInStream(size_t bufSize_)
: underlying(0), bufSize(bufSize_ ? bufSize_ : DEFAULT_BUF_SIZE), offset(0), : underlying(0), bufSize(bufSize_ ? bufSize_ : DEFAULT_BUF_SIZE), offset(0),
zs(NULL), bytesIn(0) zs(NULL), bytesIn(0)
{ {
delete [] start; delete [] start;
} }


void ZlibInStream::setUnderlying(InStream* is, int bytesIn_)
void ZlibInStream::setUnderlying(InStream* is, size_t bytesIn_)
{ {
underlying = is; underlying = is;
bytesIn = bytesIn_; bytesIn = bytesIn_;
ptr = end = start; ptr = end = start;
} }


int ZlibInStream::pos()
size_t ZlibInStream::pos()
{ {
return offset + ptr - start; return offset + ptr - start;
} }
zs = NULL; zs = NULL;
} }


int ZlibInStream::overrun(int itemSize, int nItems, bool wait)
size_t ZlibInStream::overrun(size_t itemSize, size_t nItems, bool wait)
{ {
if (itemSize > bufSize) if (itemSize > bufSize)
throw Exception("ZlibInStream overrun: max itemSize exceeded"); throw Exception("ZlibInStream overrun: max itemSize exceeded");
end -= ptr - start; end -= ptr - start;
ptr = start; ptr = start;


while (end - ptr < itemSize) {
while ((size_t)(end - ptr) < itemSize) {
if (!decompress(wait)) if (!decompress(wait))
return 0; return 0;
} }


if (itemSize * nItems > end - ptr)
if (itemSize * nItems > (size_t)(end - ptr))
nItems = (end - ptr) / itemSize; nItems = (end - ptr) / itemSize;


return nItems; return nItems;
zs->next_out = (U8*)end; zs->next_out = (U8*)end;
zs->avail_out = start + bufSize - end; zs->avail_out = start + bufSize - end;


int n = underlying->check(1, 1, wait);
size_t n = underlying->check(1, 1, wait);
if (n == 0) return false; if (n == 0) return false;
zs->next_in = (U8*)underlying->getptr(); zs->next_in = (U8*)underlying->getptr();
zs->avail_in = underlying->getend() - underlying->getptr(); zs->avail_in = underlying->getend() - underlying->getptr();
if ((int)zs->avail_in > bytesIn)
if (zs->avail_in > bytesIn)
zs->avail_in = bytesIn; zs->avail_in = bytesIn;


int rc = inflate(zs, Z_SYNC_FLUSH); int rc = inflate(zs, Z_SYNC_FLUSH);

+ 7
- 7
common/rdr/ZlibInStream.h View File



public: public:


ZlibInStream(int bufSize=0);
ZlibInStream(size_t bufSize=0);
virtual ~ZlibInStream(); virtual ~ZlibInStream();


void setUnderlying(InStream* is, int bytesIn);
void setUnderlying(InStream* is, size_t bytesIn);
void flushUnderlying(); void flushUnderlying();
int pos();
size_t pos();
void reset(); void reset();


private: private:
void init(); void init();
void deinit(); void deinit();


int overrun(int itemSize, int nItems, bool wait);
size_t overrun(size_t itemSize, size_t nItems, bool wait);
bool decompress(bool wait); bool decompress(bool wait);


InStream* underlying; InStream* underlying;
int bufSize;
int offset;
size_t bufSize;
size_t offset;
z_stream_s* zs; z_stream_s* zs;
int bytesIn;
size_t bytesIn;
U8* start; U8* start;
}; };



+ 5
- 5
common/rdr/ZlibOutStream.cxx View File



enum { DEFAULT_BUF_SIZE = 16384 }; enum { DEFAULT_BUF_SIZE = 16384 };


ZlibOutStream::ZlibOutStream(OutStream* os, int bufSize_, int compressLevel)
ZlibOutStream::ZlibOutStream(OutStream* os, size_t bufSize_, int compressLevel)
: underlying(os), compressionLevel(compressLevel), newLevel(compressLevel), : underlying(os), compressionLevel(compressLevel), newLevel(compressLevel),
bufSize(bufSize_ ? bufSize_ : DEFAULT_BUF_SIZE), offset(0) bufSize(bufSize_ ? bufSize_ : DEFAULT_BUF_SIZE), offset(0)
{ {
newLevel = level; newLevel = level;
} }


int ZlibOutStream::length()
size_t ZlibOutStream::length()
{ {
return offset + ptr - start; return offset + ptr - start;
} }
ptr = start; ptr = start;
} }


int ZlibOutStream::overrun(int itemSize, int nItems)
size_t ZlibOutStream::overrun(size_t itemSize, size_t nItems)
{ {
#ifdef ZLIBOUT_DEBUG #ifdef ZLIBOUT_DEBUG
vlog.debug("overrun"); vlog.debug("overrun");


checkCompressionLevel(); checkCompressionLevel();


while (end - ptr < itemSize) {
while ((size_t)(end - ptr) < itemSize) {
zs->next_in = start; zs->next_in = start;
zs->avail_in = ptr - start; zs->avail_in = ptr - start;


} }
} }


if (itemSize * nItems > end - ptr)
if (itemSize * nItems > (size_t)(end - ptr))
nItems = (end - ptr) / itemSize; nItems = (end - ptr) / itemSize;


return nItems; return nItems;

+ 5
- 5
common/rdr/ZlibOutStream.h View File



public: public:


ZlibOutStream(OutStream* os=0, int bufSize=0, int compressionLevel=-1);
ZlibOutStream(OutStream* os=0, size_t bufSize=0, int compressionLevel=-1);
virtual ~ZlibOutStream(); virtual ~ZlibOutStream();


void setUnderlying(OutStream* os); void setUnderlying(OutStream* os);
void setCompressionLevel(int level=-1); void setCompressionLevel(int level=-1);
void flush(); void flush();
int length();
size_t length();


private: private:


int overrun(int itemSize, int nItems);
size_t overrun(size_t itemSize, size_t nItems);
void deflate(int flush); void deflate(int flush);
void checkCompressionLevel(); void checkCompressionLevel();


OutStream* underlying; OutStream* underlying;
int compressionLevel; int compressionLevel;
int newLevel; int newLevel;
int bufSize;
int offset;
size_t bufSize;
size_t offset;
z_stream_s* zs; z_stream_s* zs;
U8* start; U8* start;
}; };

+ 3
- 3
common/rfb/Configuration.cxx View File

// -=- BinaryParameter // -=- BinaryParameter


BinaryParameter::BinaryParameter(const char* name_, const char* desc_, BinaryParameter::BinaryParameter(const char* name_, const char* desc_,
const void* v, int l, ConfigurationObject co)
const void* v, size_t l, ConfigurationObject co)
: VoidParameter(name_, desc_, co), value(0), length(0), def_value((char*)v), def_length(l) { : VoidParameter(name_, desc_, co), value(0), length(0), def_value((char*)v), def_length(l) {
if (l) { if (l) {
value = new char[l]; value = new char[l];
return rdr::HexInStream::hexStrToBin(v, &value, &length); return rdr::HexInStream::hexStrToBin(v, &value, &length);
} }


void BinaryParameter::setParam(const void* v, int len) {
void BinaryParameter::setParam(const void* v, size_t len) {
LOCK_CONFIG; LOCK_CONFIG;
if (immutable) return; if (immutable) return;
vlog.debug("set %s(Binary)", getName()); vlog.debug("set %s(Binary)", getName());
return rdr::HexOutStream::binToHexStr(value, length); return rdr::HexOutStream::binToHexStr(value, length);
} }


void BinaryParameter::getData(void** data_, int* length_) const {
void BinaryParameter::getData(void** data_, size_t* length_) const {
LOCK_CONFIG; LOCK_CONFIG;
if (length_) *length_ = length; if (length_) *length_ = length;
if (data_) { if (data_) {

+ 7
- 6
common/rfb/Configuration.h View File



class BinaryParameter : public VoidParameter { class BinaryParameter : public VoidParameter {
public: public:
BinaryParameter(const char* name_, const char* desc_, const void* v, int l,
ConfigurationObject co=ConfGlobal);
BinaryParameter(const char* name_, const char* desc_,
const void* v, size_t l,
ConfigurationObject co=ConfGlobal);
using VoidParameter::setParam; using VoidParameter::setParam;
virtual ~BinaryParameter(); virtual ~BinaryParameter();
virtual bool setParam(const char* value); virtual bool setParam(const char* value);
virtual void setParam(const void* v, int l);
virtual void setParam(const void* v, size_t l);
virtual char* getDefaultStr() const; virtual char* getDefaultStr() const;
virtual char* getValueStr() const; virtual char* getValueStr() const;


// getData() will return length zero if there is no data // getData() will return length zero if there is no data
// NB: data may be set to zero, OR set to a zero-length buffer // NB: data may be set to zero, OR set to a zero-length buffer
void getData(void** data, int* length) const;
void getData(void** data, size_t* length) const;


protected: protected:
char* value; char* value;
int length;
size_t length;
char* def_value; char* def_value;
int def_length;
size_t def_length;
}; };


// -=- ParameterIterator // -=- ParameterIterator

+ 3
- 3
common/rfb/Password.cxx View File

PlainPasswd::PlainPasswd(char* pwd) : CharArray(pwd) { PlainPasswd::PlainPasswd(char* pwd) : CharArray(pwd) {
} }


PlainPasswd::PlainPasswd(int len) : CharArray(len) {
PlainPasswd::PlainPasswd(size_t len) : CharArray(len) {
} }


PlainPasswd::PlainPasswd(const ObfuscatedPasswd& obfPwd) : CharArray(9) { PlainPasswd::PlainPasswd(const ObfuscatedPasswd& obfPwd) : CharArray(9) {
ObfuscatedPasswd::ObfuscatedPasswd() : length(0) { ObfuscatedPasswd::ObfuscatedPasswd() : length(0) {
} }


ObfuscatedPasswd::ObfuscatedPasswd(int len) : CharArray(len), length(len) {
ObfuscatedPasswd::ObfuscatedPasswd(size_t len) : CharArray(len), length(len) {
} }


ObfuscatedPasswd::ObfuscatedPasswd(const PlainPasswd& plainPwd) : CharArray(8), length(8) { ObfuscatedPasswd::ObfuscatedPasswd(const PlainPasswd& plainPwd) : CharArray(8), length(8) {
int l = strlen(plainPwd.buf), i;
size_t l = strlen(plainPwd.buf), i;
for (i=0; i<8; i++) for (i=0; i<8; i++)
buf[i] = i<l ? plainPwd.buf[i] : 0; buf[i] = i<l ? plainPwd.buf[i] : 0;
deskey(d3desObfuscationKey, EN0); deskey(d3desObfuscationKey, EN0);

+ 3
- 3
common/rfb/Password.h View File

public: public:
PlainPasswd(); PlainPasswd();
PlainPasswd(char* pwd); PlainPasswd(char* pwd);
PlainPasswd(int len);
PlainPasswd(size_t len);
PlainPasswd(const ObfuscatedPasswd& obfPwd); PlainPasswd(const ObfuscatedPasswd& obfPwd);
~PlainPasswd(); ~PlainPasswd();
void replaceBuf(char* b); void replaceBuf(char* b);
class ObfuscatedPasswd : public CharArray { class ObfuscatedPasswd : public CharArray {
public: public:
ObfuscatedPasswd(); ObfuscatedPasswd();
ObfuscatedPasswd(int l);
ObfuscatedPasswd(size_t l);
ObfuscatedPasswd(const PlainPasswd& plainPwd); ObfuscatedPasswd(const PlainPasswd& plainPwd);
~ObfuscatedPasswd(); ~ObfuscatedPasswd();
int length;
size_t length;
}; };


} }

+ 1
- 1
common/rfb/util.h View File

public: public:
CharArray() : buf(0) {} CharArray() : buf(0) {}
CharArray(char* str) : buf(str) {} // note: assumes ownership CharArray(char* str) : buf(str) {} // note: assumes ownership
CharArray(int len) {
CharArray(size_t len) {
buf = new char[len](); buf = new char[len]();
} }
~CharArray() { ~CharArray() {

+ 5
- 5
tests/perf/encperf.cxx View File

public: public:
DummyOutStream(); DummyOutStream();


virtual int length();
virtual size_t length();
virtual void flush(); virtual void flush();


private: private:
virtual int overrun(int itemSize, int nItems);
virtual size_t overrun(size_t itemSize, size_t nItems);


int offset; int offset;
rdr::U8 buf[131072]; rdr::U8 buf[131072];
end = buf + sizeof(buf); end = buf + sizeof(buf);
} }


int DummyOutStream::length()
size_t DummyOutStream::length()
{ {
flush(); flush();
return offset; return offset;
ptr = buf; ptr = buf;
} }


int DummyOutStream::overrun(int itemSize, int nItems)
size_t DummyOutStream::overrun(size_t itemSize, size_t nItems)
{ {
flush(); flush();
if (itemSize * nItems > end - ptr)
if (itemSize * nItems > (size_t)(end - ptr))
nItems = (end - ptr) / itemSize; nItems = (end - ptr) / itemSize;
return nItems; return nItems;
} }

+ 3
- 3
win/rfb_win32/Registry.cxx View File

if (result != ERROR_SUCCESS) throw rdr::SystemException("setString", result); if (result != ERROR_SUCCESS) throw rdr::SystemException("setString", result);
} }


void RegKey::setBinary(const TCHAR* valname, const void* value, int length) const {
void RegKey::setBinary(const TCHAR* valname, const void* value, size_t length) const {
LONG result = RegSetValueEx(key, valname, 0, REG_BINARY, (const BYTE*)value, length); LONG result = RegSetValueEx(key, valname, 0, REG_BINARY, (const BYTE*)value, length);
if (result != ERROR_SUCCESS) throw rdr::SystemException("setBinary", result); if (result != ERROR_SUCCESS) throw rdr::SystemException("setBinary", result);
} }
} }
} }


void RegKey::getBinary(const TCHAR* valname, void** data, int* length) const {
void RegKey::getBinary(const TCHAR* valname, void** data, size_t* length) const {
TCharArray hex(getRepresentation(valname)); TCharArray hex(getRepresentation(valname));
if (!rdr::HexInStream::hexStrToBin(CStr(hex.buf), (char**)data, length)) if (!rdr::HexInStream::hexStrToBin(CStr(hex.buf), (char**)data, length))
throw rdr::Exception("getBinary failed"); throw rdr::Exception("getBinary failed");
} }
void RegKey::getBinary(const TCHAR* valname, void** data, int* length, void* def, int deflen) const {
void RegKey::getBinary(const TCHAR* valname, void** data, size_t* length, void* def, size_t deflen) const {
try { try {
getBinary(valname, data, length); getBinary(valname, data, length);
} catch(rdr::Exception&) { } catch(rdr::Exception&) {

+ 3
- 3
win/rfb_win32/Registry.h View File



void setExpandString(const TCHAR* valname, const TCHAR* s) const; void setExpandString(const TCHAR* valname, const TCHAR* s) const;
void setString(const TCHAR* valname, const TCHAR* s) const; void setString(const TCHAR* valname, const TCHAR* s) const;
void setBinary(const TCHAR* valname, const void* data, int length) const;
void setBinary(const TCHAR* valname, const void* data, size_t length) const;
void setInt(const TCHAR* valname, int i) const; void setInt(const TCHAR* valname, int i) const;
void setBool(const TCHAR* valname, bool b) const; void setBool(const TCHAR* valname, bool b) const;


TCHAR* getString(const TCHAR* valname) const; TCHAR* getString(const TCHAR* valname) const;
TCHAR* getString(const TCHAR* valname, const TCHAR* def) const; TCHAR* getString(const TCHAR* valname, const TCHAR* def) const;


void getBinary(const TCHAR* valname, void** data, int* length) const;
void getBinary(const TCHAR* valname, void** data, int* length, void* def, int deflength) const;
void getBinary(const TCHAR* valname, void** data, size_t* length) const;
void getBinary(const TCHAR* valname, void** data, size_t* length, void* def, size_t deflength) const;


int getInt(const TCHAR* valname) const; int getInt(const TCHAR* valname) const;
int getInt(const TCHAR* valname, int def) const; int getInt(const TCHAR* valname, int def) const;

Loading…
Cancel
Save