// ----------------------------------------------------------
// File:	ni_sc.c
//
// Contents:	main module for ni_sc.dll.
//				ni_sc.dll is the DLL to provide  
//				password obtaining module from CyberFlex JavaCard
//				for ni_pam .
// 
// History:		9-22-97	Naomaru Itoi	created

//#include "ni_sc.h"

#include <stdio.h>
#include <windows.h>
#include "ni_common2.h"
// smart card specific
#include "pc3comm.h"
#include "scio.h"

#define CommandClass 0x01
#define SCStrLen 32
int ni_send(LPSTR str, int len);
int ni_recv();
int ni_select(char r0, char r1);
int ni_readbinary(int len, char *recv);

// global valuables. 
HINSTANCE	hDllInstance;	// my instance

// functions

BOOL
WINAPI
DllMain(
		HINSTANCE hInstance,
		DWORD dwReason,
		LPVOID lpReserved)
{
    switch (dwReason)
    {
        case DLL_PROCESS_ATTACH:
            DisableThreadLibraryCalls ( hInstance );
            hDllInstance = hInstance;

        case DLL_PROCESS_DETACH:
        default:
            return(TRUE);
    }
}

/*
 ni_sm_obtainpass()
 History :	Created by Naomaru Itoi, 9-22-1997.
 Usage :	Read username and password from CyberFlex JavaCard.
			username is stored in file 3f00/7777/7701
			password is stored in file 3f00/7777/7702.
			port number is speficied in niStruct.value.
			*/
BOOL
WINAPI
ni_sm_obtainpass(NISTRUCT *nistruct)
{		
	char cmd[64], buf[100], recv[SCStrLen];
	INT rtn = 1;
    unsigned short len, r1, r2;
	
	printf("ni_sc : ni_sm_obtainpass(%d) called. \n", nistruct->value);
	
	/* open reader */
    stuff_cmd(COMM, cmd);
    cmd[2] = nistruct->value - 1;	// assign port number
    len = 0;
    SCBios(cmd, buf, &len, &r1, &r2);
    if (r2) {
		printf("can't open reader\n");
		goto futz;
    }

    /* reset the reader */
    stuff_cmd(RESET, cmd);
    len = cmd[4];
    SCBios(cmd, buf, &len, &r1, &r2);
    if (r2) {
		printf("Slag!\n");
		goto futz;
    }

	// open 3f.00 
			
	if (ni_select(0x3f, 0x00) < 0) {
		printf("cannot select 3f.00\n");
		goto futz;
	}
	printf("selected 3f.00\n");

	if (ni_select(0x77, 0x77) < 0) {
		printf("cannot select 77.77\n");
		goto futz;
	}
	printf("selected 77.77\n");

	if (ni_select(0x77, 0x01) < 0) {
		printf("cannot select 77.01\n");
		goto futz;
	}
	printf("selected 77.01\n");
	
	ni_readbinary(SCStrLen, recv);
	MultiByteToWideChar(CP_ACP, 0, recv, strlen(recv), 
		nistruct->username, SCStrLen);
		
	if (ni_select(0x77, 0x02) < 0) {
		printf("cannot select 77.02\n");
		goto futz;
	}
	printf("selected 77.02\n");

	ni_readbinary(SCStrLen, recv);
	MultiByteToWideChar(CP_ACP, 0, recv, strlen(recv), 
		nistruct->password, SCStrLen);
				
	wprintf(L"username : %s\n", nistruct->username);
	//wprintf(L"password : %s\n", nistruct->password);
	// NI : close the port ...
	SCBclose();
	return NI_SUCCESS;

	futz:
    SCBclose();
	return NI_FAILURE;
}

/*
 ni_send(), ni_recv, ni_select(), ni_readbinary(), ni_writebinary()
 These are the functions I wrote to access CyberFlex javaCard.
 They call pc3comm.dll library
 */

int ni_send(LPSTR str, int len)
{
	int i, rtn;
	for (i=0; i<len; i++){
		rtn = scsend(&str[i], 1, 1/*==NO_LRC*/) ;
	}
	return rtn;
}

int ni_recv()
{
	int rtn;
	char recv[2];

	rtn = screcv(recv, 2, 1/*==NO_LRC*/);
	//printf("%x.%x\n", recv[0], recv[1]);
	if (recv[0] != (char)0x90 || recv[1] != (char)0) return -1;
	else return 0;
}

int ni_select(char r0, char r1)
{
	char str[7];
	
	str[0] = (char)0xc0;
	str[1] = (char)0xa4;
	str[2] = (char)0x00;
	str[3] = (char)0x00;
	str[4] = (char)0x02;
	str[5] = r0;
	str[6] = r1;
	ni_send(str, 7);
	return ni_recv(); 
}

int ni_readbinary(int len, char *recv)
{
	char str[5];
	int i;

	str[0] = (char)0xf0;
	str[1] = (char)0xb0;
	str[2] = (char)0x00;
	str[3] = (char)0x00;
	str[4] = (char)len;
	
	ni_send(str, 5);
	// the first byte of reply is command number (0xb0).
	//recv = (char *)malloc((len)*sizeof(char));
	screcv(recv, 1, 1);
	screcv(recv, len, 1/*==NO_LRC*/);
	//printf("%x.%x\n", recv[0], recv[1]);
	for (i=0; i<len; i++){
		recv[i] = recv[i] & 0xff;
		//printf("%x ", recv[i]);
	}
	puts("");
	return 0;
}

int ni_writebinary(LPSTR send_data, int len)
{
	int i;
	char str[5+SCStrLen];

	str[0] = (char)0xf0;
	str[1] = (char)0xd6;
	str[2] = (char)0x00;
	str[3] = (char)0x00;
	str[4] = len;
	
	for (i=0; i<len; i++){
		str[5+i] = send_data[i];
	}

	ni_send(str, 5+len);
	return ni_recv(); 
}

