Added support for building emulation in Windows.

It has not been tested but it should not break any linux build.

Signed-off-by: Pol Henarejos <pol.henarejos@cttc.es>
This commit is contained in:
Pol Henarejos
2024-01-01 01:54:49 +01:00
parent adf53b4231
commit a9dc6fd7f8
22 changed files with 681 additions and 269 deletions

View File

@@ -56,7 +56,7 @@ void process_fci(const file_t *pe, int fmd) {
res_APDU[res_APDU_size++] = 2;
if (pe->data) {
if ((pe->type & FILE_DATA_FUNC) == FILE_DATA_FUNC) {
uint16_t len = ((int (*)(const file_t *, int))(pe->data))(pe, 0);
uint16_t len = (uint16_t)((int (*)(const file_t *, int))(pe->data))(pe, 0);
res_APDU[res_APDU_size++] = (len >> 8) & 0xff;
res_APDU[res_APDU_size++] = len & 0xff;
}
@@ -100,17 +100,17 @@ void process_fci(const file_t *pe, int fmd) {
memcpy(res_APDU + res_APDU_size, "\x8A\x01\x05", 3); //life-cycle (5 -> activated)
res_APDU_size += 3;
uint8_t *meta_data = NULL;
uint8_t meta_size = meta_find(pe->fid, &meta_data);
uint16_t meta_size = meta_find(pe->fid, &meta_data);
if (meta_size > 0 && meta_data != NULL) {
res_APDU[res_APDU_size++] = 0xA5;
res_APDU[res_APDU_size++] = 0x81;
res_APDU[res_APDU_size++] = meta_size;
res_APDU[res_APDU_size++] = (uint8_t )meta_size;
memcpy(res_APDU + res_APDU_size, meta_data, meta_size);
res_APDU_size += meta_size;
}
res_APDU[1] = res_APDU_size - 2;
res_APDU[1] = (uint8_t)res_APDU_size - 2;
if (fmd) {
res_APDU[3] = res_APDU_size - 4;
res_APDU[3] = (uint8_t )res_APDU_size - 4;
}
}
@@ -352,14 +352,14 @@ file_t *file_new(uint16_t fid) {
//memset((uint8_t *)f->acl, 0x90, sizeof(f->acl));
return f;
}
int meta_find(uint16_t fid, uint8_t **out) {
uint16_t meta_find(uint16_t fid, uint8_t **out) {
file_t *ef = search_by_fid(EF_META, NULL, SPECIFY_EF);
if (!ef) {
return CCID_ERR_FILE_NOT_FOUND;
return 0;
}
uint16_t tag = 0x0;
uint8_t *tag_data = NULL, *p = NULL, *data = file_get_data(ef);
size_t tag_len = 0, data_len = file_get_size(ef);
uint16_t tag_len = 0, data_len = file_get_size(ef);
while (walk_tlv(data, data_len, &p, &tag, &tag_len, &tag_data)) {
if (tag_len < 2) {
continue;
@@ -381,7 +381,7 @@ int meta_delete(uint16_t fid) {
}
uint16_t tag = 0x0;
uint8_t *tag_data = NULL, *p = NULL, *data = file_get_data(ef);
size_t tag_len = 0, data_len = file_get_size(ef);
uint16_t tag_len = 0, data_len = file_get_size(ef);
uint8_t *fdata = NULL;
while (walk_tlv(data, data_len, &p, &tag, &tag_len, &tag_data)) {
uint8_t *tpos = p - tag_len - format_tlv_len(tag_len, NULL) - 1;
@@ -390,7 +390,7 @@ int meta_delete(uint16_t fid) {
}
uint16_t cfid = (tag_data[0] << 8 | tag_data[1]);
if (cfid == fid) {
size_t new_len = data_len - 1 - tag_len - format_tlv_len(tag_len, NULL);
uint16_t new_len = data_len - 1 - tag_len - format_tlv_len(tag_len, NULL);
if (new_len == 0) {
flash_clear_file(ef);
}
@@ -425,7 +425,7 @@ int meta_add(uint16_t fid, const uint8_t *data, uint16_t len) {
memcpy(fdata, file_get_data(ef), ef_size);
uint16_t tag = 0x0;
uint8_t *tag_data = NULL, *p = NULL;
size_t tag_len = 0;
uint16_t tag_len = 0;
while (walk_tlv(fdata, ef_size, &p, &tag, &tag_len, &tag_data)) {
if (tag_len < 2) {
continue;
@@ -479,7 +479,7 @@ int meta_add(uint16_t fid, const uint8_t *data, uint16_t len) {
*f++ = fid >> 8;
*f++ = fid & 0xff;
memcpy(f, data, len);
r = flash_write_data_to_file(ef, fdata, ef_size + asn1_len_tag(fid & 0x1f, len + 2));
r = flash_write_data_to_file(ef, fdata, ef_size + (uint16_t)asn1_len_tag(fid & 0x1f, len + 2));
free(fdata);
if (r != CCID_OK) {
return CCID_EXEC_ERROR;

View File

@@ -25,9 +25,10 @@
#else
#include <stdbool.h>
#include <stdint.h>
#include "compat.h"
#endif
#define FILE_TYPE_UNKNOWN 0x00
#define FILE_TYPE_NOT_KNOWN 0x00
#define FILE_TYPE_DF 0x04
#define FILE_TYPE_INTERNAL_EF 0x03
#define FILE_TYPE_WORKING_EF 0x01
@@ -68,7 +69,7 @@
#define MAX_DEPTH 4
typedef struct file {
PACK(typedef struct file {
const uint16_t fid;
const uint8_t parent; //entry number in the whole table!!
const uint8_t *name;
@@ -76,7 +77,7 @@ typedef struct file {
const uint8_t ef_structure;
uint8_t *data; //should include 2 bytes len at begining
const uint8_t acl[7];
} __attribute__((packed)) file_t;
}) file_t;
extern bool file_has_data(file_t *);
@@ -119,7 +120,7 @@ extern int delete_dynamic_file(file_t *f);
extern bool isUserAuthenticated;
extern int meta_find(uint16_t, uint8_t **out);
extern uint16_t meta_find(uint16_t, uint8_t **out);
extern int meta_delete(uint16_t fid);
extern int meta_add(uint16_t fid, const uint8_t *data, uint16_t len);
extern int delete_file(file_t *ef);

View File

@@ -28,8 +28,19 @@
#include "pico/sem.h"
#include "pico/multicore.h"
#else
#ifdef _MSC_VER
#include <windows.h>
#include <io.h>
#define O_RDWR _O_RDWR
#define open _open
#define write _write
#define mode_t unsigned short
#define lseek _lseek
#include "mman.h"
#else
#include <unistd.h>
#include <sys/mman.h>
#endif
#include <fcntl.h>
#define FLASH_SECTOR_SIZE 4096
#define PICO_FLASH_SIZE_BYTES (8 * 1024 * 1024)

184
src/fs/mman.c Normal file
View File

@@ -0,0 +1,184 @@
#include <windows.h>
#include <errno.h>
#include <io.h>
#include "mman.h"
#ifndef FILE_MAP_EXECUTE
#define FILE_MAP_EXECUTE 0x0020
#endif /* FILE_MAP_EXECUTE */
static int __map_mman_error(const DWORD err, const int deferr)
{
(void)deferr;
if (err == 0)
return 0;
//TODO: implement
return err;
}
static DWORD __map_mmap_prot_page(const int prot)
{
DWORD protect = 0;
if (prot == PROT_NONE)
return protect;
if ((prot & PROT_EXEC) != 0)
{
protect = ((prot & PROT_WRITE) != 0) ?
PAGE_EXECUTE_READWRITE : PAGE_EXECUTE_READ;
}
else
{
protect = ((prot & PROT_WRITE) != 0) ?
PAGE_READWRITE : PAGE_READONLY;
}
return protect;
}
static DWORD __map_mmap_prot_file(const int prot)
{
DWORD desiredAccess = 0;
if (prot == PROT_NONE)
return desiredAccess;
if ((prot & PROT_READ) != 0)
desiredAccess |= FILE_MAP_READ;
if ((prot & PROT_WRITE) != 0)
desiredAccess |= FILE_MAP_WRITE;
if ((prot & PROT_EXEC) != 0)
desiredAccess |= FILE_MAP_EXECUTE;
return desiredAccess;
}
void* mmap(void* addr, size_t len, int prot, int flags, int fildes, off_t off)
{
(void)addr;
HANDLE fm, h;
void* map = MAP_FAILED;
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable: 4293)
#endif
const DWORD dwFileOffsetLow = (sizeof(off_t) <= sizeof(DWORD)) ?
(DWORD)off : (DWORD)(off & 0xFFFFFFFFL);
const DWORD dwFileOffsetHigh = (sizeof(off_t) <= sizeof(DWORD)) ?
(DWORD)0 : (DWORD)((off >> 32) & 0xFFFFFFFFL);
const DWORD protect = __map_mmap_prot_page(prot);
const DWORD desiredAccess = __map_mmap_prot_file(prot);
const off_t maxSize = off + (off_t)len;
const DWORD dwMaxSizeLow = (sizeof(off_t) <= sizeof(DWORD)) ?
(DWORD)maxSize : (DWORD)(maxSize & 0xFFFFFFFFL);
const DWORD dwMaxSizeHigh = (sizeof(off_t) <= sizeof(DWORD)) ?
(DWORD)0 : (DWORD)((maxSize >> 32) & 0xFFFFFFFFL);
#ifdef _MSC_VER
#pragma warning(pop)
#endif
errno = 0;
if (len == 0
/* Unsupported flag combinations */
|| (flags & MAP_FIXED) != 0
/* Usupported protection combinations */
|| prot == PROT_EXEC)
{
errno = EINVAL;
return MAP_FAILED;
}
h = ((flags & MAP_ANONYMOUS) == 0) ?
(HANDLE)_get_osfhandle(fildes) : INVALID_HANDLE_VALUE;
if ((flags & MAP_ANONYMOUS) == 0 && h == INVALID_HANDLE_VALUE)
{
errno = EBADF;
return MAP_FAILED;
}
fm = CreateFileMapping(h, NULL, protect, dwMaxSizeHigh, dwMaxSizeLow, NULL);
if (fm == NULL)
{
errno = __map_mman_error(GetLastError(), EPERM);
return MAP_FAILED;
}
map = MapViewOfFile(fm, desiredAccess, dwFileOffsetHigh, dwFileOffsetLow, len);
CloseHandle(fm);
if (map == NULL)
{
errno = __map_mman_error(GetLastError(), EPERM);
return MAP_FAILED;
}
return map;
}
int munmap(void* addr, size_t len)
{
(void)len;
if (UnmapViewOfFile(addr))
return 0;
errno = __map_mman_error(GetLastError(), EPERM);
return -1;
}
int mprotect(void* addr, size_t len, int prot)
{
DWORD newProtect = __map_mmap_prot_page(prot);
DWORD oldProtect = 0;
if (VirtualProtect(addr, len, newProtect, &oldProtect))
return 0;
errno = __map_mman_error(GetLastError(), EPERM);
return -1;
}
int msync(void* addr, size_t len, int flags)
{
(void)flags;
if (FlushViewOfFile(addr, len))
return 0;
errno = __map_mman_error(GetLastError(), EPERM);
return -1;
}
int mlock(const void* addr, size_t len)
{
if (VirtualLock((LPVOID)addr, len))
return 0;
errno = __map_mman_error(GetLastError(), EPERM);
return -1;
}
int munlock(const void* addr, size_t len)
{
if (VirtualUnlock((LPVOID)addr, len))
return 0;
errno = __map_mman_error(GetLastError(), EPERM);
return -1;
}

55
src/fs/mman.h Normal file
View File

@@ -0,0 +1,55 @@
/*
* sys/mman.h
* mman-win32
*/
#ifndef _SYS_MMAN_H_
#define _SYS_MMAN_H_
#ifndef _WIN32_WINNT // Allow use of features specific to Windows XP or later.
#define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target other versions of Windows.
#endif
/* All the headers include this file. */
#ifndef _MSC_VER
#include <_mingw.h>
#endif
#include <sys/types.h>
#ifdef __cplusplus
extern "C" {
#endif
#define PROT_NONE 0
#define PROT_READ 1
#define PROT_WRITE 2
#define PROT_EXEC 4
#define MAP_FILE 0
#define MAP_SHARED 1
#define MAP_PRIVATE 2
#define MAP_TYPE 0xf
#define MAP_FIXED 0x10
#define MAP_ANONYMOUS 0x20
#define MAP_ANON MAP_ANONYMOUS
#define MAP_FAILED ((void *)-1)
/* Flags for msync. */
#define MS_ASYNC 1
#define MS_SYNC 2
#define MS_INVALIDATE 4
void* mmap(void* addr, size_t len, int prot, int flags, int fildes, off_t off);
int munmap(void* addr, size_t len);
int mprotect(void* addr, size_t len, int prot);
int msync(void* addr, size_t len, int flags);
int mlock(const void* addr, size_t len);
int munlock(const void* addr, size_t len);
#ifdef __cplusplus
};
#endif
#endif /* _SYS_MMAN_H_ */