a
This commit is contained in:
parent
f2769e094f
commit
5bdad6ebae
12
readme.md
12
readme.md
@ -18,14 +18,16 @@ To use it with a game, copy `aimeio.dll` to your `segatools` folder and add the
|
|||||||
|
|
||||||
```ini
|
```ini
|
||||||
[aimeio]
|
[aimeio]
|
||||||
path=aimeio.dll
|
path=aimeio.dll ;Path to aimeio.dll
|
||||||
scan=0x0D ;Sets the key which will be used to insert a card in game. The default is 'Return'
|
scan=0x0D ;Sets the key which will be used to insert a card in game. The default is 'Return'
|
||||||
|
|
||||||
|
|
||||||
;Everything below this line is optional.
|
;Everything below this line is optional.
|
||||||
|
|
||||||
;aimePath= ;Manually specify an aime.txt file
|
;readerOptional=1 ;Make reader optional, so that you can still use the keyboard
|
||||||
;felicaPath= ;Manually specify a felica.txt file
|
;readerName="" ;Force using a reader by setting it's name (in case multiple readers are detected)
|
||||||
;felicaGen=0 ;Generate a new random card if it's missing from the file
|
;aimePath="" ;Manually specify an aime.txt file
|
||||||
|
;felicaPath="" ;Manually specify a felica.txt file
|
||||||
;debug=0 ;Display function calls
|
;debug=0 ;Display function calls
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -33,8 +35,6 @@ scan=0x0D ;Sets the key which will be used to insert a card in game. The def
|
|||||||
|
|
||||||
If you scan a newer AIC-based Aime, its FeliCa IDm will be provided to the game. The game will not see the correct "access code," but the IDm should be unique to each card so that particular card can still track your plays.
|
If you scan a newer AIC-based Aime, its FeliCa IDm will be provided to the game. The game will not see the correct "access code," but the IDm should be unique to each card so that particular card can still track your plays.
|
||||||
|
|
||||||
As for Mifare cards, their access code won't be 1:1 with a real reader (i still need to fix this). You can still use them and they will work though !
|
|
||||||
|
|
||||||
## Inserting cards
|
## Inserting cards
|
||||||
|
|
||||||
By pressing the key you have set in segatools.ini and holding it for a few moments, you will insert a card set in either aime.txt or felica.txt
|
By pressing the key you have set in segatools.ini and holding it for a few moments, you will insert a card set in either aime.txt or felica.txt
|
||||||
|
65
src/aimeio.c
65
src/aimeio.c
@ -132,15 +132,15 @@ end:
|
|||||||
}
|
}
|
||||||
#pragma endregion
|
#pragma endregion
|
||||||
|
|
||||||
#pragma region READER SPECIFIC
|
#pragma region READER
|
||||||
static unsigned int __stdcall reader_poll_thread_proc(void *ctx)
|
static unsigned int __stdcall aime_io_poll_thread_proc(void *ctx)
|
||||||
{
|
{
|
||||||
if (aime_io_cfg.debug)
|
if (aime_io_cfg.debug)
|
||||||
printf("DEBUG: reader_poll_thread_proc(). \r\n");
|
printf("DEBUG: aime_io_poll_thread_proc(). \r\n");
|
||||||
while (!READER_POLL_STOP_FLAG)
|
while (!READER_POLL_STOP_FLAG)
|
||||||
{
|
{
|
||||||
if (card_data.card_type != 0) // Halting polling once a card is found, waiting for the game to read it's value.
|
if (card_data.card_type != 0) // Halting polling once a card is found, waiting for the game to read it's value.
|
||||||
scard_poll(&card_data);
|
scard_poll(&card_data); // We're trying to find a card. If we do, the card's id and type are written to card_data.
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -155,30 +155,25 @@ uint16_t aime_io_get_api_version(void)
|
|||||||
|
|
||||||
HRESULT aime_io_init(void)
|
HRESULT aime_io_init(void)
|
||||||
{
|
{
|
||||||
|
int ret = AllocConsole(); // At init we want to open a console...
|
||||||
// At init we want to open a console...
|
|
||||||
int ret = AllocConsole();
|
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
// someone might already allocated a console - seeing this on fufubot's segatools
|
|
||||||
if (ret != 0)
|
if (ret != 0) // someone might already allocated a console - seeing this on fufubot's segatools
|
||||||
freopen_s(&fp, "CONOUT$", "w", stdout); // only when we allocate a console, we need to redirect stdout
|
freopen_s(&fp, "CONOUT$", "w", stdout); // only when we allocate a console, we need to redirect stdout
|
||||||
|
|
||||||
memset(&card_data, 0, sizeof(card_data)); // Init card_data structure
|
memset(&card_data, 0, sizeof(card_data)); // We init the card_data structure
|
||||||
|
|
||||||
// We then read the segatools config file to get settings.
|
// We then read the segatools config file to get settings.
|
||||||
aime_io_config_read(&aime_io_cfg, L".\\segatools.ini");
|
aime_io_config_read(&aime_io_cfg, L".\\segatools.ini");
|
||||||
|
|
||||||
// Find and initialize reader(s)
|
printf("aime_io_init: Initializing SmartCard\n"); // Find and initialize reader(s)
|
||||||
printf("aime_io_init: Initializing SmartCard\n");
|
|
||||||
if (!scard_init(aime_io_cfg))
|
if (!scard_init(aime_io_cfg))
|
||||||
{
|
{
|
||||||
// If we couldn't init reader, error out.
|
printf("aime_io_init: Couldn't init SmartCard\n"); // If we couldn't init reader, error out.
|
||||||
printf("aime_io_init: Couldn't init SmartCard\n");
|
|
||||||
if (!aime_io_cfg.reader_optional)
|
if (!aime_io_cfg.reader_optional)
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
|
|
||||||
// If however the readerOptional flag is set to 1 in segatools.ini, continue with keyboard only.
|
printf("aime_io_init: Reader is optional, using keyboard only !\n"); // If however the readerOptional flag is set to 1 in segatools.ini, continue with keyboard only.
|
||||||
printf("aime_io_init: Reader is optional, using keyboard only !\n");
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -189,7 +184,7 @@ HRESULT aime_io_init(void)
|
|||||||
READER_POLL_THREAD = (HANDLE)_beginthreadex(
|
READER_POLL_THREAD = (HANDLE)_beginthreadex(
|
||||||
NULL,
|
NULL,
|
||||||
0,
|
0,
|
||||||
reader_poll_thread_proc,
|
aime_io_poll_thread_proc,
|
||||||
NULL,
|
NULL,
|
||||||
0,
|
0,
|
||||||
NULL);
|
NULL);
|
||||||
@ -205,15 +200,9 @@ HRESULT aime_io_nfc_poll(uint8_t unit_no)
|
|||||||
if (unit_no != 0)
|
if (unit_no != 0)
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
|
||||||
bool sense;
|
|
||||||
HRESULT hr;
|
|
||||||
|
|
||||||
// Don't do anything more if the scan key is not held
|
// Don't do anything more if the scan key is not held
|
||||||
sense = GetAsyncKeyState(aime_io_cfg.vk_scan) & 0x8000;
|
if (GetAsyncKeyState(aime_io_cfg.vk_scan) & 0x8000)
|
||||||
if (!sense)
|
|
||||||
{
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
|
||||||
|
|
||||||
// Set which card we want to read (we will read the x'th line in the card's file, x being determined by which key is pressed on the keypad).
|
// Set which card we want to read (we will read the x'th line in the card's file, x being determined by which key is pressed on the keypad).
|
||||||
int card = 0;
|
int card = 0;
|
||||||
@ -227,15 +216,11 @@ HRESULT aime_io_nfc_poll(uint8_t unit_no)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HRESULT hr;
|
||||||
printf("aime_io_nfc_poll: Attempting to read card %d from file. \r\n", card);
|
printf("aime_io_nfc_poll: Attempting to read card %d from file. \r\n", card);
|
||||||
|
|
||||||
// Try AiMe IC
|
// Try AiMe IC
|
||||||
hr = aime_io_read_id_file(
|
hr = aime_io_read_id_file(aime_io_cfg.aime_path, card_data.card_id, 10, card);
|
||||||
aime_io_cfg.aime_path,
|
|
||||||
card_data.card_id,
|
|
||||||
10,
|
|
||||||
card);
|
|
||||||
|
|
||||||
if (SUCCEEDED(hr) && hr != S_FALSE)
|
if (SUCCEEDED(hr) && hr != S_FALSE)
|
||||||
{
|
{
|
||||||
card_data.card_type = Mifare;
|
card_data.card_type = Mifare;
|
||||||
@ -243,17 +228,14 @@ HRESULT aime_io_nfc_poll(uint8_t unit_no)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Try FeliCa IC
|
// Try FeliCa IC
|
||||||
hr = aime_io_read_id_file(
|
hr = aime_io_read_id_file(aime_io_cfg.felica_path, card_data.card_id, 8, card);
|
||||||
aime_io_cfg.felica_path,
|
|
||||||
card_data.card_id,
|
|
||||||
8,
|
|
||||||
card);
|
|
||||||
|
|
||||||
if (SUCCEEDED(hr) && hr != S_FALSE)
|
if (SUCCEEDED(hr) && hr != S_FALSE)
|
||||||
{
|
{
|
||||||
card_data.card_type = FeliCa;
|
card_data.card_type = FeliCa;
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We found nothing.
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -271,7 +253,7 @@ HRESULT aime_io_nfc_get_aime_id(uint8_t unit_no, uint8_t *luid, size_t luid_size
|
|||||||
if (card_data.card_type == Mifare)
|
if (card_data.card_type == Mifare)
|
||||||
{
|
{
|
||||||
memcpy(luid, card_data.card_id, luid_size);
|
memcpy(luid, card_data.card_id, luid_size);
|
||||||
printf("aime_io_nfc_get_aime_id: Read Aime card from file with uid %02X%02X %02X%02X %02X%02X %02X%02X %02X%02X\r\n", card_data.card_id[0], card_data.card_id[1], card_data.card_id[2], card_data.card_id[3], card_data.card_id[4], card_data.card_id[5], card_data.card_id[6], card_data.card_id[7], card_data.card_id[8], card_data.card_id[9]);
|
printf("aime_io_nfc_get_aime_id: Sending Aime card with luID %02X%02X %02X%02X %02X%02X %02X%02X %02X%02X\r\n", card_data.card_id[0], card_data.card_id[1], card_data.card_id[2], card_data.card_id[3], card_data.card_id[4], card_data.card_id[5], card_data.card_id[6], card_data.card_id[7], card_data.card_id[8], card_data.card_id[9]);
|
||||||
|
|
||||||
memset(&card_data, 0, sizeof(card_data)); // Reset card_data structure
|
memset(&card_data, 0, sizeof(card_data)); // Reset card_data structure
|
||||||
return S_OK;
|
return S_OK;
|
||||||
@ -285,21 +267,18 @@ HRESULT aime_io_nfc_get_felica_id(uint8_t unit_no, uint64_t *IDm)
|
|||||||
if (aime_io_cfg.debug)
|
if (aime_io_cfg.debug)
|
||||||
printf("DEBUG: aime_io_nfc_get_felica_id(unit_no : %d). \r\n", unit_no);
|
printf("DEBUG: aime_io_nfc_get_felica_id(unit_no : %d). \r\n", unit_no);
|
||||||
|
|
||||||
uint64_t val;
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
assert(IDm != NULL);
|
assert(IDm != NULL);
|
||||||
if (unit_no != 0)
|
if (unit_no != 0)
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
|
|
||||||
if (card_data.card_type == FeliCa)
|
if (card_data.card_type == FeliCa)
|
||||||
{
|
{
|
||||||
val = 0;
|
uint64_t val = 0;
|
||||||
for (i = 0; i < 8; i++)
|
for (size_t i = 0; i < 8; i++)
|
||||||
val = (val << 8) | card_data.card_id[i];
|
val = (val << 8) | card_data.card_id[i];
|
||||||
|
|
||||||
*IDm = val;
|
*IDm = val;
|
||||||
printf("aime_io_nfc_get_felica_id: Read FeliCa card from file with uid %02X%02X %02X%02X %02X%02X %02X%02X\r\n", card_data.card_id[0], card_data.card_id[1], card_data.card_id[2], card_data.card_id[3], card_data.card_id[4], card_data.card_id[5], card_data.card_id[6], card_data.card_id[7]);
|
printf("aime_io_nfc_get_felica_id: Sending FeliCa card with IDm %02X%02X %02X%02X %02X%02X %02X%02X\r\n", card_data.card_id[0], card_data.card_id[1], card_data.card_id[2], card_data.card_id[3], card_data.card_id[4], card_data.card_id[5], card_data.card_id[6], card_data.card_id[7]);
|
||||||
|
|
||||||
memset(&card_data, 0, sizeof(card_data)); // Reset card_data structure
|
memset(&card_data, 0, sizeof(card_data)); // Reset card_data structure
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
@ -3,11 +3,8 @@
|
|||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
|
||||||
#include <time.h>
|
|
||||||
|
|
||||||
struct aime_io_config
|
struct aime_io_config
|
||||||
{
|
{
|
||||||
|
@ -210,9 +210,7 @@ void scard_update(struct card_data *card_data, SCARDCONTEXT _hContext, LPCTSTR _
|
|||||||
|
|
||||||
printf("scard_update: atr Return: len(%zu) = %02x (%08X)\n", sizeof(cByteAtr), (unsigned int)atr, cByteAtr);
|
printf("scard_update: atr Return: len(%zu) = %02x (%08X)\n", sizeof(cByteAtr), (unsigned int)atr, cByteAtr);
|
||||||
|
|
||||||
// Figure out if we should reverse the UID returned by the card based on the ATR protocol
|
|
||||||
BYTE cardProtocol = atr[12];
|
BYTE cardProtocol = atr[12];
|
||||||
|
|
||||||
if (cardProtocol == SCARD_ATR_PROTOCOL_ISO14443_PART3)
|
if (cardProtocol == SCARD_ATR_PROTOCOL_ISO14443_PART3)
|
||||||
{
|
{
|
||||||
printf("scard_update: Card protocol: ISO14443_PART3\n");
|
printf("scard_update: Card protocol: ISO14443_PART3\n");
|
||||||
@ -249,7 +247,6 @@ void scard_update(struct card_data *card_data, SCARDCONTEXT _hContext, LPCTSTR _
|
|||||||
else if (cbRecv > 8)
|
else if (cbRecv > 8)
|
||||||
printf("scard_update: taking first 8 bytes of len(uid) = %02X\n", cbRecv);
|
printf("scard_update: taking first 8 bytes of len(uid) = %02X\n", cbRecv);
|
||||||
|
|
||||||
card_data->card_id_len = 8;
|
|
||||||
memcpy(card_data->card_id, pbRecv, 8);
|
memcpy(card_data->card_id, pbRecv, 8);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,30 +25,20 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <winscard.h>
|
#include <winscard.h>
|
||||||
#include <windows.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <src/aimeio.h>
|
#include <src/aimeio.h>
|
||||||
|
|
||||||
/* card types */
|
// Card types
|
||||||
enum AIME_CARDTYPE
|
enum AIME_CARDTYPE
|
||||||
{
|
{
|
||||||
Mifare = 0x01,
|
Mifare = 0x01,
|
||||||
FeliCa = 0x02,
|
FeliCa = 0x02
|
||||||
};
|
};
|
||||||
|
|
||||||
// Structure containing card_type, card_id and card_id_len
|
// Structure containing card_type, card_id and card_id_len
|
||||||
struct card_data
|
struct card_data
|
||||||
{
|
{
|
||||||
/* CARDTYPE */
|
|
||||||
uint8_t card_type;
|
uint8_t card_type;
|
||||||
|
|
||||||
/* Card ID */
|
|
||||||
uint8_t card_id[32];
|
uint8_t card_id[32];
|
||||||
|
|
||||||
/* Card ID length */
|
|
||||||
uint8_t card_id_len;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
bool scard_init(struct aime_io_config config);
|
bool scard_init(struct aime_io_config config);
|
||||||
|
Loading…
Reference in New Issue
Block a user