The following demonstrates how to use C language to download random data from a SwiftRNG device when used with Entropy Server for Windows and utilizing a named pipe. The following code will only work when running SwiftRNG Entropy Server. This is the recommended way for achieving maximum concurrent speed and performance. Before using the following example, make sure the SwiftRNG device is plugged into one of USB ports available and entropy-server.exe is running on same system.

A C sample source code (it has been tested with Microsoft Visual Studio Community 2019) for retrieving random values from SwiftRNG device when using Entropy Server for Windows through a named pipe connection.


#include <windows.h>
#include <stdio.h>

#define ENTROPY_BUFFER_SIZE 100000
#define CMD_ENTROPY_RETRIEVE_ID 0

//
// Functions
//

int openNamedPipe();
int closeNamedPipe();
int readEntropyFromPipe(DWORD commandId, unsigned char* rcvBuff, DWORD len);
int retrieveEntropyFromServer(DWORD commandId, unsigned char* rcvBuff, DWORD len);

//
// Data section
//

typedef struct
{
	DWORD cmd;
	DWORD cbReqData;
} REQCMD;


REQCMD reqCmd;
HANDLE hPipe;
LPCWSTR defaultPipeEndpoint = L"\\\\.\\pipe\\SwiftRNG";
BOOL fSuccess = FALSE;
DWORD cbRead, cbWritten, cbToWrite, dwMode;
unsigned char entropyBuffer[ENTROPY_BUFFER_SIZE];

int main()
{
	int status = 0;
	int i;

	printf("Retrieving random %d bytes from entropy server ................ ", ENTROPY_BUFFER_SIZE);
	status = retrieveEntropyFromServer(CMD_ENTROPY_RETRIEVE_ID, entropyBuffer, ENTROPY_BUFFER_SIZE);
	if (status == 0) {
		printf("SUCCESS\n");
	}
	else {
		printf(" failed\n");
		printf("Is entropy server running?\n");
		return status;
	}

	printf("Printing the first 10 random bytes:\n");
	for (i = 1; i <= 10; i++) {
		printf("rnd[% d] = %d\n", i, entropyBuffer[i]);
	}
}

/*
* Retrieve entropy data from the entropy server
* @param commandId - command to send to the entropy server
* @param rcvBuff buffer for incoming data
* @param len - number of bytes to receive
* @return 0 - success
*/
int retrieveEntropyFromServer(DWORD commandId, unsigned char* rcvBuff, DWORD len) {
	int status = openNamedPipe();
	if (status == 0) {
		status = readEntropyFromPipe(commandId, rcvBuff, len);
		closeNamedPipe();
	}
	return status;
}

/*
* Open named pipe to the entropy server
*
* @return 0 - success
*/
int openNamedPipe() {
	while (1) {
		hPipe = CreateFile(
			defaultPipeEndpoint,   // pipe name
			GENERIC_READ |  // read and write access
			GENERIC_WRITE,
			0,              // no sharing
			NULL,           // default security attributes
			OPEN_EXISTING,  // opens existing pipe
			0,              // default attributes
			NULL);          // no template file

		if (hPipe != INVALID_HANDLE_VALUE) {
			break;
		}

		if (GetLastError() != ERROR_PIPE_BUSY) {
			return -1;
		}

		if (!WaitNamedPipe(defaultPipeEndpoint, 20000)) {
			return -1;
		}
	}

	dwMode = PIPE_READMODE_BYTE;
	fSuccess = SetNamedPipeHandleState(
		hPipe,    // pipe handle
		&dwMode,  // new pipe mode
		NULL,     // don't set maximum bytes
		NULL);    // don't set maximum time
	if (!fSuccess) {
		return -1;
	}
	return 0;
}


/*
* Close named pipe to the entropy server
*
* @return 0 - success
*/
int closeNamedPipe() {
	CloseHandle(hPipe);
	return 0;
}

/*
* Read entropy data from named pipe
* @param commandId - command to send to the entropy server
* @param rcvBuff buffer for incoming data
* @param len - number of bytes to receive
* @return 0 - success
*/
int readEntropyFromPipe(DWORD commandId, unsigned char* rcvBuff, DWORD len) {
	cbToWrite = sizeof(REQCMD);
	reqCmd.cmd = commandId;
	reqCmd.cbReqData = len;

	fSuccess = WriteFile(
		hPipe,                  // pipe handle
		&reqCmd,             // bytes
		cbToWrite,              // bytes length
		&cbWritten,             // bytes written
		NULL);                  // not overlapped

	if (!fSuccess) {
		return -1;
	}
	do {
		fSuccess = ReadFile(
			hPipe,    // pipe handle
			rcvBuff,    // buffer to receive reply
			len,  // size of buffer
			&cbRead,  // number of bytes read
			NULL);    // not overlapped

		if (!fSuccess && GetLastError() != ERROR_MORE_DATA) {
			break;
		}
	} while (!fSuccess);  // repeat loop if ERROR_MORE_DATA

	if (!fSuccess) {
		return -1;
	}
	return 0;
}