This is an example of using files and timers in an threaded application.
#include "ofc/config.h"
#include "ofc/libc.h"
#include "ofc/thread.h"
#include "ofc/event.h"
#include "ofc/console.h"
#include "ofc/process.h"
#if defined(OFC_PERF_STATS)
#include "ofc/perf.h"
#endif
#define OFC_FS_TEST_INTERVAL 1000
#define OFC_FILE_TEST_COUNT 1
#define FS_TEST_READ TSTR("copy.from")
#define FS_TEST_WRITE TSTR("copy.to")
#define FS_TEST_DELETE TSTR("delete.me")
#define FS_TEST_RENAME TSTR("directory\\rename.me")
#define FS_TEST_RENAMETO TSTR("directory\\new.me")
#define FS_TEST_RENAMETO_ROOT TSTR("new.me")
#define FS_TEST_FLUSH TSTR("flush.me")
#define FS_TEST_DIRECTORY TSTR("directory")
#define FS_TEST_SETEOF TSTR("seteof.txt")
#define FS_TEST_GETEX TSTR("getex.txt")
#define BUFFER_SIZE OFC_MAX_IO
#define NUM_FILE_BUFFERS 10
typedef enum {
BUFFER_STATE_IDLE,
BUFFER_STATE_READ,
BUFFER_STATE_WRITE
} BUFFER_STATE;
typedef struct {
BUFFER_STATE state;
} OFC_FILE_BUFFER;
typedef enum {
ASYNC_RESULT_DONE,
ASYNC_RESULT_ERROR,
ASYNC_RESULT_EOF,
ASYNC_RESULT_PENDING
} ASYNC_RESULT;
static ASYNC_RESULT
{
ASYNC_RESULT result;
buffer->state = BUFFER_STATE_READ;
{
if (*((
OFC_ULONG *)(buffer->data)) != buffer->offset)
ofc_printf("got bad buffer in async read 0x%08x, 0x%08x\n",
*((
OFC_ULONG *)(buffer->data)), buffer->offset);
result = ASYNC_RESULT_DONE;
}
else
{
{
result = ASYNC_RESULT_PENDING;
}
else
{
result = ASYNC_RESULT_EOF;
else
result = ASYNC_RESULT_ERROR;
buffer->state = BUFFER_STATE_IDLE;
}
}
return (result);
}
static ASYNC_RESULT AsyncReadResult(
OFC_HANDLE wait_set,
OFC_FILE_BUFFER *buffer,
{
ASYNC_RESULT result;
{
if (*dwLen == 0)
{
result = ASYNC_RESULT_EOF;
}
else
{
if (*((
OFC_ULONG *)(buffer->data)) != buffer->offset)
{
ofc_printf("got bad buffer in async read result 0x%0x, 0x%0x\n",
*((
OFC_ULONG*)(buffer->data)), buffer->offset);
ofc_process_crash("foobar");
}
result = ASYNC_RESULT_DONE;
}
}
else
{
result = ASYNC_RESULT_PENDING;
else
{
{
ofc_printf("Read Error %d\n", dwLastError);
result = ASYNC_RESULT_ERROR;
}
else
result = ASYNC_RESULT_EOF;
}
}
if (result != ASYNC_RESULT_PENDING)
{
buffer->state = BUFFER_STATE_IDLE;
}
return (result);
}
{
ASYNC_RESULT result;
buffer->offset);
buffer->state = BUFFER_STATE_WRITE;
buffer->writeOverlapped);
result = ASYNC_RESULT_DONE;
{
result = ASYNC_RESULT_PENDING;
else
{
result = ASYNC_RESULT_ERROR;
buffer->state = BUFFER_STATE_IDLE;
}
}
return (result);
}
static ASYNC_RESULT AsyncWriteResult(
OFC_HANDLE wait_set,
OFC_FILE_BUFFER *buffer,
{
ASYNC_RESULT result;
result = ASYNC_RESULT_DONE;
else
{
result = ASYNC_RESULT_PENDING;
else
{
ofc_printf("Write Error %d\n", dwLastError);
result = ASYNC_RESULT_ERROR;
}
}
if (result != ASYNC_RESULT_PENDING)
{
buffer->state = BUFFER_STATE_IDLE;
}
return (result);
}
{
devlen = ofc_tastrlen (device);
namelen = ofc_tastrlen (name);
filename =
p = filename;
ofc_tastrcpy (p, device);
p += devlen;
if (devlen > 0)
ofc_tastrcpy (p, name);
p += namelen;
return (filename);
}
#if 1
#define CREATE_SIZE (64*1024)
#else
#define CREATE_SIZE (64*1024*1024)
#endif
{
#if defined(OFC_PERF_STATS)
struct perf_queue *pqueue;
struct perf_rt *prt;
#endif
OFC_FILE_BUFFER *buffer;
ASYNC_RESULT result;
wfilename = MakeFilename(device, FS_TEST_READ);
#if defined(OFC_PERF_STATS)
pqueue = perf_queue_create(g_measurement,
TSTR(
"App Write"), 0);
prt = perf_rt_create(g_measurement,
TSTR(
"App Create"), 0);
measurement_start(g_measurement);
#endif
{
ofc_printf("Failed to open Copy Destination %A, %s(%d)\n",
wfilename,
}
else
{
pending = 0;
#if defined(OFC_PERF_STATS)
perf_rt_start(prt);
#endif
size = 0;
for (i = 0; i < NUM_FILE_BUFFERS && size < CREATE_SIZE && !eof; i++)
{
{
ofc_printf("test_file: Failed to alloc buffer context\n");
}
else
{
{
ofc_printf("test_file: Failed to allocate "
"memory buffer\n");
}
else
{
buffer->offset = offset;
ofc_process_crash("An Overlapped Handle is NULL");
dwLen = BUFFER_SIZE;
for (i = 0; i < (BUFFER_SIZE /
sizeof(
OFC_ULONG)); i++)
{
*p++ = size;
}
size += BUFFER_SIZE;
pending++;
#if defined(OFC_PERF_STATS)
perf_request_start(g_measurement, pqueue);
#endif
result = AsyncWrite(wait_set, write_file, buffer, dwLen);
if (result != ASYNC_RESULT_PENDING)
{
#if defined(OFC_PERF_STATS)
perf_request_stop(g_measurement, pqueue, 0);
#endif
pending--;
if (result == ASYNC_RESULT_ERROR)
{
}
}
#if defined(OFC_64BIT_INTEGER)
offset += BUFFER_SIZE;
#else
offset.low += BUFFER_SIZE ;
#endif
}
}
}
while (pending > 0)
{
{
if (buffer->state == BUFFER_STATE_WRITE)
{
result = AsyncWriteResult(wait_set, write_file,
buffer, &dwLen);
if (result == ASYNC_RESULT_EOF)
{
pending--;
#if defined(OFC_PERF_STATS)
perf_request_stop(g_measurement, pqueue, 0);
#endif
}
else if (result == ASYNC_RESULT_ERROR)
{
pending--;
#if defined(OFC_PERF_STATS)
perf_request_stop(g_measurement, pqueue, 0);
#endif
}
else if (result == ASYNC_RESULT_DONE)
{
pending--;
#if defined(OFC_PERF_STATS)
perf_request_stop(g_measurement, pqueue, dwLen);
#endif
#if 0
if (buffer->offset % (1024 * 1024) == 0)
ofc_printf("Wrote %d MB\n",
(buffer->offset / (1024 * 1024)) + 1);
#endif
#if defined(OFC_64BIT_INTEGER)
offset += BUFFER_SIZE;
#else
offset.low += BUFFER_SIZE ;
#endif
if (size < CREATE_SIZE && ret ==
OFC_TRUE)
{
for (i = 0; i < (BUFFER_SIZE /
sizeof(
OFC_ULONG)); i++)
{
*p++ = size;
}
size += BUFFER_SIZE;
pending++;
#if defined(OFC_PERF_STATS)
perf_request_start(g_measurement, pqueue);
#endif
result = AsyncWrite(wait_set, write_file,
buffer, BUFFER_SIZE);
if (result != ASYNC_RESULT_PENDING)
{
#if defined(OFC_PERF_STATS)
perf_request_stop(g_measurement, pqueue, 0);
#endif
}
}
}
}
}
}
#if defined(OFC_PERF_STATS)
perf_rt_stop(prt);
#endif
{
}
}
#if defined(OFC_PERF_STATS)
measurement_wait(g_measurement);
measurement_statistics(g_measurement);
perf_rt_destroy(g_measurement, prt);
perf_queue_destroy(g_measurement, pqueue);
#endif
ofc_printf("Create File Test Done, Elapsed Time %dms\n\n",
else
ofc_printf("Create File Test Failed\n\n");
return (ret);
}
{
wfilename = MakeFilename(device, FS_TEST_READ);
return (ret);
}
{
OFC_FILE_BUFFER *buffer;
ASYNC_RESULT result;
#if defined(OFC_PERF_STATS)
struct perf_queue *pqueue_read;
struct perf_queue *pqueue_write;
struct perf_rt *prt;
#endif
rfilename = MakeFilename(device, FS_TEST_READ);
wfilename = MakeFilename(device, FS_TEST_WRITE);
#if defined(OFC_PERF_STATS)
pqueue_read = perf_queue_create(g_measurement,
TSTR(
"App Read"), 0);
pqueue_write = perf_queue_create(g_measurement,
TSTR(
"App Write"), 0);
prt = perf_rt_create(g_measurement,
TSTR(
"App Copy"), 0);
measurement_start(g_measurement);
#endif
{
ofc_printf("Failed to open Copy Source %A, %s(%d)\n",
rfilename,
}
else
{
0,
{
ofc_printf("Failed to open Copy Destination %A, %s(%d)\n",
wfilename,
}
else
{
pending = 0;
for (i = 0; i < NUM_FILE_BUFFERS && ret ==
OFC_TRUE; i++)
{
{
ofc_printf("test_file: Failed to alloc buffer context\n");
}
else
{
{
ofc_printf("test_file: Failed to allocate "
"memory buffer\n");
}
else
{
buffer->offset = offset;
buffer->writeOverlapped =
ofc_process_crash("An Overlapped Handle is NULL");
}
}
}
#if defined(OFC_PERF_STATS)
perf_rt_start(prt);
#endif
{
{
dwLen = BUFFER_SIZE;
pending++;
#if defined(OFC_PERF_STATS)
perf_request_start(g_measurement, pqueue_read);
#endif
result = AsyncRead(wait_set, read_file, buffer, dwLen);
if (result != ASYNC_RESULT_PENDING)
{
#if defined(OFC_PERF_STATS)
perf_request_stop(g_measurement, pqueue_read, 0);
#endif
pending--;
if (result == ASYNC_RESULT_ERROR)
{
}
}
#if defined(OFC_64BIT_INTEGER)
offset += BUFFER_SIZE;
#else
offset.low += BUFFER_SIZE ;
#endif
}
}
while (pending > 0)
{
{
if (buffer->state == BUFFER_STATE_READ)
{
result = AsyncReadResult(wait_set, read_file,
buffer, &dwLen);
if (result == ASYNC_RESULT_EOF)
{
#if defined(OFC_PERF_STATS)
perf_request_stop(g_measurement, pqueue_read, 0);
#endif
}
else if (result == ASYNC_RESULT_ERROR)
{
#if defined(OFC_PERF_STATS)
perf_request_stop(g_measurement, pqueue_read, 0);
#endif
}
else if (result == ASYNC_RESULT_DONE)
{
#if defined(OFC_PERF_STATS)
perf_request_stop(g_measurement, pqueue_read,
dwLen);
perf_request_start(g_measurement, pqueue_write);
#endif
result = AsyncWrite(wait_set, write_file, buffer,
dwLen);
if (result == ASYNC_RESULT_ERROR)
{
#if defined(OFC_PERF_STATS)
perf_request_stop(g_measurement, pqueue_write,
0);
#endif
}
}
if (result == ASYNC_RESULT_ERROR ||
result == ASYNC_RESULT_EOF ||
(result == ASYNC_RESULT_DONE && status ==
OFC_FALSE))
{
pending--;
}
}
else
{
result = AsyncWriteResult(wait_set, write_file,
buffer, &dwLen);
if (result == ASYNC_RESULT_ERROR)
{
#if defined(OFC_PERF_STATS)
perf_request_stop(g_measurement, pqueue_write, 0);
#endif
}
else if (result == ASYNC_RESULT_DONE)
{
#if defined(OFC_PERF_STATS)
perf_request_stop(g_measurement, pqueue_write,
dwLen);
#endif
#if 0
if (buffer->offset % (1024 * 1024) == 0)
ofc_printf("Copied %d MB\n",
(buffer->offset / (1024 * 1024)) + 1);
#endif
#if defined(OFC_64BIT_INTEGER)
offset += BUFFER_SIZE;
#else
offset.low += BUFFER_SIZE ;
#endif
#if defined(OFC_PERF_STATS)
perf_request_start(g_measurement, pqueue_read);
#endif
result = AsyncRead(wait_set, read_file,
buffer, BUFFER_SIZE);
if (result != ASYNC_RESULT_PENDING)
{
#if defined(OFC_PERF_STATS)
perf_request_stop(g_measurement, pqueue_read,
0);
#endif
}
}
if (result != ASYNC_RESULT_PENDING)
{
if (result == ASYNC_RESULT_ERROR)
pending--;
}
}
}
}
#if defined(OFC_PERF_STATS)
perf_rt_stop(prt);
#endif
{
}
}
}
#if defined(OFC_PERF_STATS)
measurement_wait(g_measurement);
measurement_statistics(g_measurement);
perf_rt_destroy(g_measurement, prt);
perf_queue_destroy(g_measurement, pqueue_read);
perf_queue_destroy(g_measurement, pqueue_write);
#endif
ofc_printf("Copy Test Done, Elapsed Time %dms\n\n",
else
ofc_printf("Copy Test Failed\n\n");
return (ret);
}
{
OFC_FILE_BUFFER *buffer;
ASYNC_RESULT result;
#if defined(OFC_PERF_STATS)
struct perf_queue *pqueue;
struct perf_rt *prt;
#endif
rfilename = MakeFilename(device, FS_TEST_READ);
#if defined(OFC_PERF_STATS)
pqueue = perf_queue_create(g_measurement,
TSTR(
"App Read"), 0);
prt = perf_rt_create(g_measurement,
TSTR(
"App Read"), 0);
measurement_start(g_measurement);
#endif
{
ofc_printf("Failed to open Copy Source %A, %s(%d)\n",
rfilename,
}
else
{
pending = 0;
#if defined(OFC_PERF_STATS)
perf_rt_start(prt);
#endif
for (i = 0; i < NUM_FILE_BUFFERS && !eof; i++)
{
{
ofc_printf("test_file: Failed to alloc buffer context\n");
}
else
{
{
ofc_printf("test_file: Failed to allocate "
"memory buffer\n");
}
else
{
buffer->offset = offset;
ofc_process_crash("An Overlapped Handle is NULL");
dwLen = BUFFER_SIZE;
pending++;
#if defined(OFC_PERF_STATS)
perf_request_start(g_measurement, pqueue);
#endif
result = AsyncRead(wait_set, read_file, buffer, dwLen);
if (result != ASYNC_RESULT_PENDING)
{
#if defined(OFC_PERF_STATS)
perf_request_stop(g_measurement, pqueue, 0);
#endif
pending--;
if (result == ASYNC_RESULT_ERROR)
{
}
}
#if defined(OFC_64BIT_INTEGER)
offset += BUFFER_SIZE;
#else
offset.low += BUFFER_SIZE ;
#endif
}
}
}
while (pending > 0)
{
{
if (buffer->state == BUFFER_STATE_READ)
{
result = AsyncReadResult(wait_set, read_file,
buffer, &dwLen);
if (result == ASYNC_RESULT_EOF)
{
#if defined(OFC_PERF_STATS)
perf_request_stop(g_measurement, pqueue, 0);
#endif
}
else if (result == ASYNC_RESULT_ERROR)
{
#if defined(OFC_PERF_STATS)
perf_request_stop(g_measurement, pqueue, 0);
#endif
}
else if (result == ASYNC_RESULT_DONE)
{
#if defined(OFC_PERF_STATS)
perf_request_stop(g_measurement, pqueue, dwLen);
#endif
#if 0
if (buffer->offset % (1024 * 1024) == 0)
ofc_printf("Read %d MB\n",
(buffer->offset / (1024 * 1024)) + 1);
#endif
#if defined(OFC_64BIT_INTEGER)
offset += BUFFER_SIZE;
#else
offset.low += BUFFER_SIZE ;
#endif
#if defined(OFC_PERF_STATS)
perf_request_start(g_measurement, pqueue);
#endif
result = AsyncRead(wait_set, read_file,
buffer, BUFFER_SIZE);
if (result != ASYNC_RESULT_PENDING)
{
#if defined(OFC_PERF_STATS)
perf_request_stop(g_measurement, pqueue, 0);
#endif
}
}
if (result == ASYNC_RESULT_ERROR ||
result == ASYNC_RESULT_EOF ||
(result == ASYNC_RESULT_DONE && status ==
OFC_FALSE))
{
pending--;
}
}
}
}
#if defined(OFC_PERF_STATS)
perf_rt_stop(prt);
#endif
{
}
}
#if defined(OFC_PERF_STATS)
measurement_wait(g_measurement);
measurement_statistics(g_measurement);
perf_rt_destroy(g_measurement, prt);
perf_queue_destroy(g_measurement, pqueue);
#endif
ofc_printf("Read Test Done, Elapsed Time %dms\n\n",
else
ofc_printf("Read Test Failed\n\n");
return (ret);
}
{
filename = MakeFilename(device, FS_TEST_DELETE);
{
ofc_printf("Failed to create delete file %A, %s(%d)\n",
filename,
}
else
{
len = BUFFER_SIZE;
while (len > 0)
{
len -= ofc_snprintf(buffer + (BUFFER_SIZE - len), len,
"This Text begins at offset %d\n",
BUFFER_SIZE - len);
}
status =
OfcWriteFile(write_file, buffer, BUFFER_SIZE, &dwBytesWritten,
{
ofc_printf("Write to Delete File Failed with %s(%d)\n",
dwLastError);
}
else
{
{
ofc_printf("Close of Delete File Failed with %s(%d)\n",
dwLastError);
}
else
{
write_file =
{
ofc_printf("Failed to create delete on close file %A, "
"%s(%d)\n",
filename,
}
else
{
{
ofc_printf("Close of Delete on close File "
"Failed with %s(%d)\n",
dwLastError);
}
else
ofc_printf("Delete on Close Test Succeeded\n");
}
}
}
}
return (ret);
}
{
dirname = MakeFilename(device, FS_TEST_DIRECTORY);
{
filename = MakeFilename(device, FS_TEST_RENAME);
tofilename = MakeFilename(device, FS_TEST_RENAMETO);
{
ofc_printf("Failed to create rename file %A, %s(%d)\n",
filename,
}
else
{
len = BUFFER_SIZE;
while (len > 0)
{
len -= ofc_snprintf(buffer + (BUFFER_SIZE - len), len,
"This Text begins at offset %d\n",
BUFFER_SIZE - len);
}
{
ofc_printf("Write to Rename File Failed with %s(%d)\n",
dwLastError);
}
else
{
{
ofc_printf("Close of Rename File Failed with %s(%d)\n",
dwLastError);
}
else
{
{
ofc_printf("Rename Test Succeeded\n");
else
{
ofc_printf("Delete Rename File Failed with %s(%d)\n",
dwLastError);
}
}
else
{
ofc_printf("Rename File Failed with %s(%d)\n",
dwLastError);
}
}
}
}
#if 0
{
ofc_printf("Couldn't delete directory, failed with %s(%d)\n",
dwLastError);
}
#else
{
ofc_printf("Failed to create delete on close dir %A, "
"%s(%d)\n",
dirname,
}
else
{
{
ofc_printf ("Close of Delete on close dir "
"Failed with %s(%d)\n",
dwLastError) ;
}
}
#endif
}
else
{
ofc_printf("Create of Directory Failed with %s(%d)\n",
dwLastError);
}
return (ret);
}
{
dirname = MakeFilename(device, FS_TEST_DIRECTORY);
{
filename = MakeFilename(device, FS_TEST_RENAME);
fulltofilename = MakeFilename(device, FS_TEST_RENAMETO);
tofilename = ofc_tastrdup (FS_TEST_RENAMETO_ROOT);
{
ofc_printf("Failed to create rename file %A, %s(%d)\n",
filename,
}
else
{
len = BUFFER_SIZE;
while (len > 0)
{
len -= ofc_snprintf(buffer + (BUFFER_SIZE - len), len,
"This Text begins at offset %d\n",
BUFFER_SIZE - len);
}
status =
OfcWriteFile(rename_file, buffer, BUFFER_SIZE, &dwBytesWritten,
{
ofc_printf("Write to Rename File Failed with %s(%d)\n",
dwLastError);
}
else
{
{
ofc_printf("Close of Rename File Failed with %s(%d)\n",
dwLastError);
}
else
{
0,
{
ofc_printf("Failed to create rename file %S, "
"%s(%d)\n",
filename,
}
else
{
newlen = ofc_tstrlen(tofilename);
(newlen * sizeof(OFC_WCHAR));
tofilename, newlen);
status =
rename_info,
{
ofc_printf("Set File Info on rename File "
"Failed with %s(%d)\n",
dwLastError);
}
{
ofc_printf("Close of rename File after Rename"
"Failed with %s(%d)\n",
dwLastError);
}
ofc_printf("Rename Test Succeeded\n");
else
{
ofc_printf("Delete Rename File Failed with %s(%d)\n",
dwLastError);
}
}
}
}
}
#if 0
{
ofc_printf("Couldn't delete directory, failed with %s(%d)\n",
dwLastError);
}
#else
{
ofc_printf ("Failed to create delete on close dir %A, "
"%s(%d)\n",
dirname,
}
else
{
{
ofc_printf ("Close of Delete on close dir "
"Failed with %s(%d)\n",
dwLastError) ;
}
}
#endif
}
else
{
ofc_printf("Create of Directory Failed with %s(%d)\n",
dwLastError);
}
return (ret);
}
{
filename = MakeFilename(device, FS_TEST_FLUSH);
{
ofc_printf("Failed to create flush file %A, %s(%d)\n",
filename,
}
else
{
for (i = 0; i < 10 && status ==
OFC_TRUE; i++)
{
len = ofc_snprintf(buffer, BUFFER_SIZE,
"This is the Text for line %d\n", i);
{
ofc_printf("Write to Flush File Failed with %s(%d)\n",
dwLastError);
}
else
{
{
ofc_printf("Flush to Flush File Failed with %s(%d)\n",
dwLastError);
}
}
}
{
ofc_printf("Close of Flush File Failed with %s(%d)\n",
dwLastError);
}
else
{
ofc_printf("Flush Test Succeeded\n");
else
{
ofc_printf("Delete of Flush File Failed with %s(%d)\n",
dwLastError);
}
}
}
return (ret);
}
{
filename = MakeFilename(device, FS_TEST_DIRECTORY);
ofc_printf("Create Directory Test Succeeded\n");
else
{
ofc_printf("Create of Directory Failed with %s(%d)\n",
dwLastError);
}
return (ret);
}
{
filename = MakeFilename(device, FS_TEST_DIRECTORY);
#if 0
{
ofc_printf("Couldn't delete directory, failed with %s(%d)\n",
dwLastError);
}
#else
{
ofc_printf ("Failed to create delete on close dir %A, "
"%s(%d)\n",
filename,
}
else
{
{
ofc_printf ("Close of Delete on close dir "
"Failed with %s(%d)\n",
dwLastError) ;
}
else
ofc_printf ("Delete Directory Test Succeeded\n") ;
}
#endif
return (ret);
}
{
filename = MakeFilename(device, FS_TEST_SETEOF);
{
ofc_printf("Failed to create seteof file %A, %s(%d)\n",
filename,
}
else
{
len = BUFFER_SIZE;
while (len > 0)
{
len -= ofc_snprintf(buffer + (BUFFER_SIZE - len), len,
"This Text begins at offset %d\n",
BUFFER_SIZE - len);
}
status =
OfcWriteFile(seteof_file, buffer, BUFFER_SIZE, &dwBytesWritten,
{
ofc_printf("Write to SetEOF File Failed with %s(%d)\n",
dwLastError);
}
else
{
{
ofc_printf("Close of SetEOF File Failed with %s(%d)\n",
dwLastError);
}
else
{
{
ofc_printf("Failed to open seteof file %A, "
"%s(%d)\n",
filename,
}
else
{
BUFFER_SIZE / 2,
{
ofc_printf("SetFilePosition Failed with %s(%d)\n",
dwLastError);
}
else
{
{
ofc_printf("Set End Of File Failed with %s(%d)\n",
dwLastError);
}
#if 0
else
{
(seteof_file,
&standard_info,
{
ofc_printf ("Cannot get end of file position %s(%d)\n",
dwLastError) ;
}
else
{
if (standard_info.
EndOfFile != BUFFER_SIZE / 2)
{
ofc_printf
("End Of File Doesn't Match. Expected %d, Got %d\n",
BUFFER_SIZE / 2,
}
}
}
#endif
}
{
ofc_printf("Close of SetEOF File "
"after pos Failed with %s(%d)\n",
dwLastError);
}
}
ofc_printf("SetEOF Test Succeeded\n");
else
{
ofc_printf("SetEOF Delete File Failed with %s(%d)\n",
dwLastError);
}
}
}
}
return (ret);
}
{
"RO",
"HID",
"SYS",
"",
"DIR",
"ARV",
"",
"NRM",
"TMP",
"SPR",
"",
"CMP",
"OFF",
"",
"ENC",
""
"VIRT",
};
{
ofc_printf("File: %A\n", find_data->cFileName);
ofc_printf("Alternate Name: %.14A\n", find_data->cAlternateFileName);
ofc_printf("Attributes: 0x%08x\n", find_data->dwFileAttributes);
mask = 0x0001;
str[0] = '\0';
p = str;
for (i = 0; i < 16; i++, mask <<= 1)
{
if (find_data->dwFileAttributes & mask)
{
if (first)
else
{
ofc_strcpy(p, ", ");
p += 2;
}
ofc_strcpy(p, Attr2Str[i]);
p += ofc_strlen(Attr2Str[i]);
}
}
*p = '\0';
ofc_printf(" %s\n", str);
&fat_date, &fat_time);
&month, &day, &year, &hour, &min, &sec);
ofc_printf("Create Time: %02d/%02d/%04d %02d:%02d:%02d GMT\n",
month, day, year, hour, min, sec);
&fat_date, &fat_time);
&month, &day, &year, &hour, &min, &sec);
ofc_printf("Last Access Time: %02d/%02d/%04d %02d:%02d:%02d GMT\n",
month, day, year, hour, min, sec);
&fat_date, &fat_time);
&month, &day, &year, &hour, &min, &sec);
ofc_printf("Last Write Time: %02d/%02d/%04d %02d:%02d:%02d GMT\n",
month, day, year, hour, min, sec);
ofc_printf("File Size High: 0x%08x, Low: 0x%08x\n",
find_data->nFileSizeHigh, find_data->nFileSizeLow);
ofc_printf("\n");
}
{
mask = 0x0001;
str[0] = '\0';
p = str;
for (i = 0; i < 16; i++, mask <<= 1)
{
{
if (first)
else
{
ofc_strcpy(p, ", ");
p += 2;
}
ofc_strcpy(p, Attr2Str[i]);
p += ofc_strlen(Attr2Str[i]);
}
}
*p = '\0';
ofc_printf(" %s\n", str);
&fat_date, &fat_time);
&month, &day, &year, &hour, &min, &sec);
ofc_printf("Create Time: %02d/%02d/%04d %02d:%02d:%02d GMT\n",
month, day, year, hour, min, sec);
&fat_date, &fat_time);
&month, &day, &year, &hour, &min, &sec);
ofc_printf("Last Access Time: %02d/%02d/%04d %02d:%02d:%02d GMT\n",
month, day, year, hour, min, sec);
&fat_date, &fat_time);
&month, &day, &year, &hour, &min, &sec);
ofc_printf("Last Write Time: %02d/%02d/%04d %02d:%02d:%02d GMT\n",
month, day, year, hour, min, sec);
ofc_printf("File Size High: 0x%08x, Low: 0x%08x\n",
}
{
count = 0;
{
filename = MakeFilename(device,
TSTR(
"*"));
else
{
ofc_printf("Failed to list dir %A, %s(%d)\n",
filename,
last_error);
{
ofc_printf("Please Authenticate\n");
ofc_printf("Username: ");
ofc_read_line(username, 80);
if (ofc_strlen(username) == 0)
else
{
tusername = ofc_cstr2tastr (username);
ofc_printf("Domain: ");
ofc_read_line(domain, 80);
tdomain = ofc_cstr2tastr (domain);
ofc_printf("Password: ");
ofc_read_password(password, 80);
tpassword = ofc_cstr2tastr (password);
tpassword, tdomain);
}
}
else
{
}
}
}
{
count++;
OfcFSPrintFindData(&find_data);
{
&find_data,
&more);
{
count++;
OfcFSPrintFindData(&find_data);
}
else
{
{
ofc_printf("Failed to Find Next, %s(%d)\n",
last_error);
}
}
}
}
ofc_printf("Total Number of Files in Directory %d\n", count);
return (ret);
}
{
filename = MakeFilename(device, FS_TEST_GETEX);
{
ofc_printf("Failed to create getex file %A, %s(%d)\n",
filename,
}
else
{
len = BUFFER_SIZE;
while (len > 0)
{
len -= ofc_snprintf(buffer + (BUFFER_SIZE - len), len,
"This Text begins at offset %d\n",
BUFFER_SIZE - len);
}
status =
OfcWriteFile(getex_file, buffer, BUFFER_SIZE, &dwBytesWritten,
{
ofc_printf("Write to GetEX File Failed with %s(%d)\n",
dwLastError);
}
else
{
{
ofc_printf("Close of GetEX File Failed with %s(%d)\n",
dwLastError);
}
else
{
&fInfo);
{
ofc_printf("GetEx Get File Info Failed with %s(%d)\n",
dwLastError);
}
else
{
ofc_printf("Get File Info for %A\n", filename);
OfcFSPrintFileAttributeData(&fInfo);
}
{
ofc_printf("GetEx Delete File Failed with %s(%d)\n",
dwLastError);
}
}
}
}
return (ret);
}
{
filename = MakeFilename(device,
TSTR(
":"));
&BytesPerSector, &NumberOfFreeClusters,
&TotalNumberOfClusters);
{
ofc_printf("Failed to get disk free space on %A, %s(%d)\n",
filename,
}
else
{
ofc_printf("Free Space On %A\n", filename);
ofc_printf(" Sectors Per Cluster: %d\n", SectorsPerCluster);
ofc_printf(" Bytes Per Sector: %d\n", BytesPerSector);
ofc_printf(" Number of Free Clusters: %d\n", NumberOfFreeClusters);
ofc_printf(" Total Number of Clusters: %d\n", TotalNumberOfClusters);
}
return (ret);
}
{
filename = MakeFilename(device,
TSTR(
":"));
VolumeNameBuffer,
&VolumeSerialNumber,
&MaximumComponentLength,
&FileSystemFlags,
FileSystemName,
{
ofc_printf("Failed to get volume info on %A, %s(%d)\n",
filename,
ofc_printf("Not supported on reverse connections, "
"see code comment\n");
}
else
{
ofc_printf("Volume Info for %A\n", filename);
ofc_printf(" Volume Name: %A\n", VolumeNameBuffer);
ofc_printf(" Volume Serial Number: 0x%08x\n", VolumeSerialNumber);
ofc_printf(" Max Component Length: %d\n", MaximumComponentLength);
ofc_printf(" File System Flags: 0x%08x\n", FileSystemFlags);
ofc_printf(" File System Name: %A\n", FileSystemName);
}
return (ret);
}
struct _test_path
{
};
static struct _test_path test_paths[] =
{
{
"Valid Path",
"user", "password", "workgroup",
"tester", "openfiles", "mydir",
},
{
"Non-existent SMB Server",
"user", "password", "workgroup",
"bogus", "openfiles", "mydir",
},
{
"Non-existent SMB Share",
"user", "password", "workgroup",
"tester", "bogus", "mydir",
},
{
"Bad Passwowrd",
"user", "bogus", "workgroup",
"tester", "openfiles", "mydir",
},
{
"Non-existent Subdirectory",
"user", "password", "workgroup",
"tester", "openfiles", "bogus",
},
{
"Read-Only Share",
"user", "password", "workgroup",
"tester", "roshare", "mydir",
},
{
"Read-Only Subdirectory",
"user", "password", "workgroup",
"tester", "openfiles", "rodir",
},
{
}
};
{
char *tmpfilename;
for (i = 0; test_paths[i].description !=
OFC_NULL; i++)
{
ofc_printf("\n");
ofc_printf("Test %d, %s\n", i, test_paths[i].description);
tmpfilename = &uncfilename[0];
test_paths[i].username,
test_paths[i].password,
test_paths[i].domain,
test_paths[i].smbserver,
test_paths[i].sharefolder,
test_paths[i].subdirectory,
ofc_printf("Writeable Directory Mode\n");
ofc_printf("Testing Write Access to %s\n", uncfilename);
{
}
else
{
}
if (test_paths[i].expected_error1 != lasterror &&
test_paths[i].expected_error2 != lasterror)
{
}
ofc_printf("%s: last error %s(%d), expected error %s(%d) or %s(%d)\n",
test_status ==
OFC_TRUE ?
"SUCCESS" :
"FAILURE",
lasterror,
test_paths[i].expected_error1,
test_paths[i].expected_error2);
tmpfilename = &uncfilename[0];
test_paths[i].username,
test_paths[i].password,
test_paths[i].domain,
test_paths[i].smbserver,
test_paths[i].sharefolder,
test_paths[i].subdirectory,
"uniquefile");
ofc_printf("Writeable Temporary File Mode\n");
ofc_printf("Testing Write Access to %s\n", uncfilename);
{
}
else
{
}
if (test_paths[i].expected_error1 != lasterror &&
test_paths[i].expected_error2 != lasterror)
{
}
ofc_printf("%s: last error %s(%d), expected error %s(%d) or %s(%d)\n",
test_status ==
OFC_TRUE ?
"SUCCESS" :
"FAILURE",
lasterror,
test_paths[i].expected_error1,
test_paths[i].expected_error2);
}
return (ret);
}
{
device = ofc_cstr2tstr(test_root);
else
{
rem = 0;
rem = path_size + 1;
ptr = device;
}
ofc_printf("Starting File Test with %S\n\n", device);
{
ofc_printf("Failed to Validate Destination %S, %s(%d)\n",
count = OFC_FILE_TEST_COUNT;
}
else
{
count = 0;
}
while (count != OFC_FILE_TEST_COUNT)
{
#if 0
{
ofc_printf("Trying an OfcGetFileAttributesExW on /\n");
&fadFile);
{
ofc_printf ("%s: OfcGetFileAttributesExW failed for %S, %s(%d)\n",
}
else
ofc_printf("Succeeded\n");
}
#endif
#if 1
ofc_printf("Create File Test\n");
{
ofc_printf(" *** Create File Test Failed *** \n");
}
#endif
#if 0
ofc_printf(" Dismount Test\n");
{
ofc_printf(" *** Dismount Test Failed ***\n");
}
#if 0
ofc_printf(" Dismount Test with No connection\n");
OfcDismountTest(device);
#else
#endif
#endif
#if 1
ofc_printf("Read File Test\n");
{
ofc_printf(" *** Read File Test Failed *** \n");
}
#endif
#if 1
ofc_printf("Copy File Test\n");
{
ofc_printf(" *** Copy File Test Failed *** \n");
}
#endif
#if 1
ofc_printf(" List Directory Test\n");
{
ofc_printf(" *** List Directory Test Failed *** \n");
}
#endif
#if 1
ofc_printf(" Delete File Test\n");
{
ofc_printf(" *** Delete File Test Failed ***\n");
}
#endif
#if 0
ofc_printf (" Rename File Test\n") ;
{
ofc_printf (" *** Rename File Test Failed ***\n") ;
ofc_printf (" Failures expected on SMBv1 Systems\n") ;
}
#endif
ofc_printf(" Move File Test\n");
{
ofc_printf(" *** Move File Test Failed ***\n");
}
ofc_printf(" Flush File Test\n");
{
ofc_printf(" *** Flush File Test Failed ***\n");
}
ofc_printf(" Create Directory Test\n");
if (OfcCreateDirectoryTest(device) ==
OFC_FALSE)
{
ofc_printf(" *** Create Directory Test Failed ***\n");
}
ofc_printf(" Delete Directory Test\n");
if (OfcDeleteDirectoryTest(device) ==
OFC_FALSE)
{
ofc_printf(" *** Delete Directory Test Failed ***\n");
}
ofc_printf(" Set File Pointer and Set EOF Test\n");
{
ofc_printf(" *** Set EOF Test Failed ***\n");
}
ofc_printf(" Get File Attributes Test\n");
if (OfcGetFileAttributesTest(device) ==
OFC_FALSE)
{
ofc_printf(" *** Get File Attributes Test Failed ***\n");
}
ofc_printf(" Get Disk Free Space Test\n");
if (OfcGetDiskFreeSpaceTest(device) ==
OFC_FALSE)
{
ofc_printf(" *** Get Disk Free Space Failed ***\n");
}
ofc_printf(" Get Volume Information Test\n");
if (OfcGetVolumeInformationTest(device) ==
OFC_FALSE)
{
ofc_printf(" *** Get Volume Information Failed ***\n");
}
ofc_printf("*** File Test Failed ***\n");
else
ofc_printf("File Test Succeeded\n\n");
count++;
if (count != OFC_FILE_TEST_COUNT)
ofc_sleep(OFC_FS_TEST_INTERVAL);
}
return (0);
}
#define OfcGetDiskFreeSpace
Definition: file.h:2633
@ OFC_FILE_BEGIN
Definition: file.h:1479
@ OFC_ERROR_LOGON_FAILURE
Definition: file.h:1602
@ OFC_ERROR_BAD_NETPATH
Definition: file.h:1540
@ OFC_ERROR_SUCCESS
Definition: file.h:1508
@ OFC_ERROR_INVALID_PASSWORD
Definition: file.h:1548
@ OFC_ERROR_HANDLE_EOF
Definition: file.h:1534
@ OFC_ERROR_NO_MORE_FILES
Definition: file.h:1521
@ OFC_ERROR_FILE_EXISTS
Definition: file.h:1546
@ OFC_ERROR_ALREADY_EXISTS
Definition: file.h:1568
@ OFC_ERROR_ACCESS_DENIED
Definition: file.h:1513
@ OFC_ERROR_PATH_NOT_FOUND
Definition: file.h:1511
@ OFC_ERROR_IO_PENDING
Definition: file.h:1591
@ OFC_ERROR_BAD_NET_NAME
Definition: file.h:1536
@ OFC_ERROR_FILE_NOT_FOUND
Definition: file.h:1510
#define OFC_MAX_PATH
Definition: file.h:119
#define OfcDismount
Definition: file.h:2635
#define OfcCreateDirectory
Definition: file.h:2624
#define OfcGetFileAttributesEx
Definition: file.h:2629
OFC_CORE_LIB OFC_BOOL OfcCloseHandle(OFC_HANDLE hObject)
struct _OFC_FILE_RENAME_INFO OFC_FILE_RENAME_INFO
#define OfcMoveFile
Definition: file.h:2630
@ OfcGetFileExInfoStandard
Definition: file.h:729
@ OfcFileStandardInfo
Definition: file.h:463
@ OfcFileRenameInfo
Definition: file.h:475
#define OfcFindNextFile
Definition: file.h:2628
OFC_CORE_LIB const OFC_CHAR * ofc_get_error_string(OFC_DWORD dwerr)
OFC_CORE_LIB OFC_BOOL OfcDismountA(OFC_LPCSTR lpFileName)
#define OfcGetVolumeInformation
Definition: file.h:2634
OFC_CORE_LIB OFC_DWORD OfcGetLastError(OFC_VOID)
#define OfcRemoveDirectory
Definition: file.h:2626
OFC_CORE_LIB OFC_BOOL OfcSetEndOfFile(OFC_HANDLE hFile)
#define OFC_WIN32_FIND_DATA
Definition: file.h:2639
@ OFC_FILE_SHARE_READ
Definition: file.h:240
@ OFC_FILE_SHARE_DELETE
Definition: file.h:230
@ OFC_FILE_SHARE_NONE
Definition: file.h:225
@ OFC_FILE_SHARE_WRITE
Definition: file.h:235
OFC_CORE_LIB OFC_BOOL OfcGetFileInformationByHandleEx(OFC_HANDLE hFile, OFC_FILE_INFO_BY_HANDLE_CLASS FileInformationClass, OFC_LPVOID lpFileInformation, OFC_DWORD dwBufferSize)
OFC_CORE_LIB OFC_BOOL OfcGetOverlappedResult(OFC_HANDLE hFile, OFC_HANDLE hOverlapped, OFC_LPDWORD lpNumberOfBytesTransferred, OFC_BOOL bWait)
OFC_CORE_LIB OFC_VOID OfcDestroyOverlapped(OFC_HANDLE hFile, OFC_HANDLE hOverlapped)
#define OfcFindFirstFile
Definition: file.h:2627
OFC_CORE_LIB OFC_BOOL OfcReadFile(OFC_HANDLE hFile, OFC_LPVOID lpBuffer, OFC_DWORD nNumberOfBytesToRead, OFC_LPDWORD lpNumberOfBytesRead, OFC_HANDLE hOverlapped)
#define OfcCreateFile
Definition: file.h:2623
OFC_CORE_LIB OFC_BOOL OfcWriteFile(OFC_HANDLE hFile, OFC_LPCVOID lpBuffer, OFC_DWORD nNumberOfBytesToWrite, OFC_LPDWORD lpNumberOfBytesWritten, OFC_HANDLE hOverlapped)
@ OFC_OPEN_EXISTING
Definition: file.h:258
@ OFC_CREATE_NEW
Definition: file.h:250
@ OFC_CREATE_ALWAYS
Definition: file.h:254
OFC_CORE_LIB OFC_BOOL OfcFlushFileBuffers(OFC_HANDLE hFile)
#define OfcDeleteFile
Definition: file.h:2625
OFC_CORE_LIB OFC_HANDLE OfcCreateFileA(OFC_LPCSTR lpFileName, OFC_DWORD dwDesiredAccess, OFC_DWORD dwShareMode, OFC_LPSECURITY_ATTRIBUTES lpSecurityAttributes, OFC_DWORD dwCreationDisposition, OFC_DWORD dwFlagsAndAttributes, OFC_HANDLE hTemplateFile)
OFC_CORE_LIB OFC_VOID OfcSetOverlappedOffset(OFC_HANDLE hFile, OFC_HANDLE hOverlapped, OFC_OFFT offset)
OFC_CORE_LIB OFC_BOOL OfcFindClose(OFC_HANDLE hFindFile)
OFC_CORE_LIB OFC_DWORD OfcSetFilePointer(OFC_HANDLE hFile, OFC_LONG lDistanceToMove, OFC_PLONG lpDistanceToMoveHigh, OFC_DWORD dwMoveMethod)
OFC_CORE_LIB OFC_BOOL OfcGetFileAttributesExW(OFC_LPCTSTR lpFileName, OFC_GET_FILEEX_INFO_LEVELS fInfoLevelId, OFC_LPVOID lpFileInformation)
@ OFC_FILE_ATTRIBUTE_NORMAL
Definition: file.h:298
@ OFC_FILE_ATTRIBUTE_TEMPORARY
Definition: file.h:302
@ OFC_FILE_ATTRIBUTE_DIRECTORY
Definition: file.h:290
@ OFC_FILE_FLAG_DELETE_ON_CLOSE
Definition: file.h:364
@ OFC_FILE_FLAG_OVERLAPPED
Definition: file.h:380
OFC_CORE_LIB OFC_HANDLE OfcCreateOverlapped(OFC_HANDLE hFile)
@ OFC_GENERIC_WRITE
Definition: file.h:211
@ OFC_GENERIC_READ
Definition: file.h:204
@ OFC_FILE_DELETE
Definition: file.h:194
OFC_CORE_LIB OFC_BOOL OfcSetFileInformationByHandle(OFC_HANDLE hFile, OFC_FILE_INFO_BY_HANDLE_CLASS FileInformationClass, OFC_LPVOID lpFileInformation, OFC_DWORD dwBufferSize)
#define OFC_INVALID_SET_FILE_POINTER
Definition: file.h:1502
#define OFC_HANDLE_NULL
Definition: handle.h:64
OFC_CORE_LIB OFC_HANDLE ofc_handle_get_app(OFC_HANDLE hHandle)
OFC_DWORD_PTR OFC_HANDLE
Definition: handle.h:43
#define OFC_INVALID_HANDLE_VALUE
Definition: handle.h:52
OFC_CORE_LIB OFC_VOID ofc_free(OFC_LPVOID mem)
OFC_CORE_LIB OFC_LPVOID ofc_malloc(OFC_SIZET size)
OFC_CORE_LIB OFC_SIZET ofc_path_make_urlA(OFC_LPSTR *filename, OFC_SIZET *rem, OFC_LPCSTR username, OFC_LPCSTR password, OFC_LPCSTR domain, OFC_LPCSTR server, OFC_LPCSTR share, OFC_LPCSTR path, OFC_LPCSTR file)
OFC_CORE_LIB OFC_SIZET ofc_path_printW(OFC_PATH *path, OFC_LPTSTR *filename, OFC_SIZET *rem)
OFC_CORE_LIB OFC_PATH * ofc_path_map_deviceW(OFC_LPCTSTR lpDevice)
#define ofc_path_get_root
Definition: path.h:849
#define ofc_path_update_credentials
Definition: path.h:842
OFC_VOID OFC_PATH
Definition: path.h:122
OFC_CORE_LIB OFC_HANDLE ofc_queue_create(OFC_VOID)
OFC_CORE_LIB OFC_VOID ofc_queue_destroy(OFC_HANDLE qHead)
OFC_CORE_LIB OFC_VOID ofc_enqueue(OFC_HANDLE qHead, OFC_VOID *qElement)
OFC_CORE_LIB OFC_VOID * ofc_queue_next(OFC_HANDLE qHead, OFC_VOID *qElement)
OFC_CORE_LIB OFC_VOID * ofc_dequeue(OFC_HANDLE qHead)
OFC_CORE_LIB OFC_VOID * ofc_queue_first(OFC_HANDLE qHead)
OFC_WCHAR FileName[1]
Definition: file.h:911
OFC_BOOL ReplaceIfExists
Definition: file.h:899
OFC_HANDLE RootDirectory
Definition: file.h:903
OFC_DWORD FileNameLength
Definition: file.h:907
OFC_LARGE_INTEGER EndOfFile
Definition: file.h:856
OFC_DWORD nFileSizeLow
Definition: file.h:714
OFC_FILETIME ftLastAccessTime
Definition: file.h:702
OFC_DWORD dwFileAttributes
Definition: file.h:694
OFC_FILETIME ftLastWriteTime
Definition: file.h:706
OFC_DWORD nFileSizeHigh
Definition: file.h:710
OFC_FILETIME ftCreateTime
Definition: file.h:698
OFC_CORE_LIB OFC_VOID ofc_dos_date_time_to_elements(OFC_WORD FatDate, OFC_WORD FatTime, OFC_UINT16 *month, OFC_UINT16 *day, OFC_UINT16 *year, OFC_UINT16 *hour, OFC_UINT16 *min, OFC_UINT16 *sec)
OFC_CORE_LIB OFC_MSTIME ofc_time_get_now(OFC_VOID)
OFC_CORE_LIB OFC_BOOL ofc_file_time_to_dos_date_time(const OFC_FILETIME *lpFileTime, OFC_WORD *lpFatDate, OFC_WORD *lpFatTime)
@ OFC_FALSE
Definition: types.h:632
@ OFC_TRUE
Definition: types.h:636
#define OFC_LARGE_INTEGER_LOW(x)
Definition: types.h:250
void OFC_VOID
Definition: types.h:159
#define TCHAR_EOS
Definition: types.h:523
unsigned int OFC_UINT32
Definition: types.h:176
#define TCHAR(x)
Definition: types.h:541
OFC_UINT8 OFC_BOOL
Definition: types.h:624
OFC_UINT32 OFC_DWORD
Definition: types.h:430
OFC_WCHAR OFC_TCHAR
Definition: types.h:463
OFC_UINT16 OFC_WORD
Definition: types.h:426
#define OFC_NULL
Definition: types.h:656
unsigned long OFC_ULONG
Definition: types.h:364
char OFC_CHAR
Definition: types.h:143
OFC_INT32 OFC_MSTIME
Definition: types.h:506
OFC_INT64 OFC_LARGE_INTEGER
Definition: types.h:229
const OFC_CHAR * OFC_LPCSTR
Definition: types.h:422
const OFC_WCHAR OFC_CTCHAR
Definition: types.h:467
#define TSTR(x)
Definition: types.h:534
int OFC_INT
Definition: types.h:119
long int OFC_SIZET
Definition: types.h:115
#define OFC_LARGE_INTEGER_SET(x, y, z)
Definition: types.h:283
unsigned short int OFC_UINT16
Definition: types.h:183
#define OFC_LARGE_INTEGER_ASSIGN(x, y)
Definition: types.h:265
OFC_CORE_LIB OFC_VOID ofc_waitset_remove(OFC_HANDLE hSet, OFC_HANDLE hEvent)
OFC_CORE_LIB OFC_HANDLE ofc_waitset_create(OFC_VOID)
OFC_CORE_LIB OFC_VOID ofc_waitset_add(OFC_HANDLE hSet, OFC_HANDLE hApp, OFC_HANDLE hEvent)
OFC_CORE_LIB OFC_VOID ofc_waitset_destroy(OFC_HANDLE handle)
OFC_CORE_LIB OFC_HANDLE ofc_waitset_wait(OFC_HANDLE handle)