Pagina 1 di 7 Blocchi funzione: FbSle44x2Card 29/02/2008 mk

Transcript

Pagina 1 di 7 Blocchi funzione: FbSle44x2Card 29/02/2008 mk
Blocchi funzione: FbSle44x2Card
Pagina 1 di 7
MNL041Q000
ELSIST Srl, www.elsist.it
Blocchi funzione
FbSle44x2Card
Questo blocco funzione permette la gestione in lettura e scrittura fino ad un massimo di 256 bytes di dati su chip cards tipo Sle4432 e
Sle4442 utilizzando sistemi Netreader sia basati su processore P89C664 che P89C664. L'FB gestisce l'accesso ai dati della chip card
in modo normale o avanzato.
In modo normale la chip card viene letta e scritta senza effettuare alcun controllo di congruità sui dati. L'area di memoria
disponibile per i dati è 256 bytes
In modo avanzato viene utilizzata una doppia struttura dati con un CRC di controllo su ogni struttura, in questo modo la chip card
può essere estratta dal lettore/scrittore in qualsiasi momento anche durante le operazioni di lettura o scrittura, senza deteriorare i
dati in essa memorizzati. L'area di memoria disponibile per i dati è 110 bytes
L'FB gestisce automaticamente il LED posto sul lettore, all'inserimento della scheda se letta correttamente il LED si accende, durante
la scrittura il LED viene spento. In caso di anomalia in base al numero di lampeggi fornisce indicazione sulla anomalia riscontrata.
1: La scheda inserita è vergine.
2: La scheda inserita ha un codice ATR errato.
3: La scheda inserita ha l'area dati in errore, è impossibile leggerla. I dati presenti sulla chip card sono stati comunque trasferiti nel
buffer definito dal cliente.
4: Controllo PSC in scrittura errato, il PSC della scheda è diverso da quello indicato. Non viene scritto alcun dato sulla chip card.
Dopo 3 errori di PSC la chip card diventa inutilizzabile.
5: Errore scrittura dati su scheda.
Utilizzando l'FB da programma C sono rese disponibili una serie di funzioni per l'accesso a basso livello sulla chip card, sarà possibile
gestire l'intera area di memoria di 256 bytes, proteggere alcune aree in scrittura e modificare il codice PSC di accesso (solo Sle4442).
Per un esempio di utilizzo della FB in linguaggio C viene fornito un programma dimostrativo Sfw111. Questo programma accetta una
serie di comandi da linea seriale con i quali è possibile sbloccare la carta (tramite codice PSC), leggere e scrivere la memoria di
protezione e la memoria principale, eseguire la duplicazione della carta.
Code:PFB063
History report
Prototype
FbSle44x2Card.h
Declaration
void FbSle44x2Card(FBSLE44X2CARDDATA* S);
Parameters
FBSLE44X2CARDDATA* S Data structure address (Range from 0x0000 to 0xFFFF)
Return value
None
Struttura dati
Il blocco funzione utilizza una struttura dati di 40 bytes di cui forniamo prototipo. I membri riportati sotto l'indicazione Internal use only
members sono utilizzati internamente dal blocco funzione e non devono essere modificati dal programma utente.
typedef struct
{
// --------------------------[Members that can be managed by user program]-struct
{
BOOL Enable:1; //Enable chip card management
BOOL WriteData:1; //Write data to chip card
BOOL DisableLEDMng:1; //Disable LED management
BOOL ChipCardLED:1; //LED on chip card reader
BOOL AdvancedMode:1; //Advanced mode selection
BOOL DisablePSC:1; //Disable PSC management
}Command;
struct
{
BOOL
BOOL
BOOL
BOOL
ReadDataOk:1; //Chip card read data ok
ReadDataError:1; //Chip card read data error
WriteDataOk:1; //Chip card write data ok
WriteDataError:1; //Chip card write data error
mk:@MSITStore:U:\Cd-048\04099.013\Mnl041\Mnl041q000\Remoter.chm::/Source/... 29/02/2008
Blocchi funzione: FbSle44x2Card
BOOL
BOOL
BOOL
BOOL
Pagina 2 di 7
bC:1;
bD:1;
bE:1;
bF:1;
BOOL
BOOL
BOOL
BOOL
BOOL
BOOL
BOOL
BOOL
}Status;
CardIn:1; //Chip card has been inserted
CardReadEnd:1; //Chip card has been read
CardWriteEnd:1; //Chip card has been write
WrongATR:1; //Chip card with wrong ATR
VirginCard:1; //Chip card is virgin
NoPSCCard:1; //Chip card without PSC code
PSCFault:1; //PSC test fault
b7:1;
unsigned
unsigned
unsigned
unsigned
char
char
char
char
ChipCardStart; //Chip card start address
CardDataLength; //Card data length
PSCCheckAddress; //PSC check address
xdata* CardData; //Card data buffer address
unsigned char ATRCode[4]; //Chip card ATR code
unsigned char ProtectionMem[4]; //Protection memory data
unsigned char SecurityMem[4]; //Security memory data
void (*CardReset)(void);
unsigned char (*PSCVerification)(void);
unsigned char (*UpdateSecurityMemory)(void);
unsigned char (*MainMemoryRead)(unsigned char Address, unsigned char* Data);
unsigned char (*MainMemoryWrite)(unsigned char Address, unsigned char Data);
void (*ProtectionMemoryRead)(void);
unsigned char (*ProtectionMemoryWrite)(unsigned char Address, unsigned char Data);
// --------------------------------------------[Internal use only members]-unsigned char Im[6]; //Internal members area
}FBSLE44X2CARDDATA;
00 Command
Bits di comando del blocco funzione, il programma utente può gestire questi bits in funzione delle proprie necessità.
0 Enable
FALSE: Disabilita l'FB, si azzerano tutti i bits di Status.
TRUE: Abilita l'FB.
1 WriteData
TRUE: Forza la scrittura della chip card con i dati del buffer di memoria puntato da CardData. Si resetta in
modo automatico all'inizio scrittura o se la chip card viene estratta dal lettore.
2 DisableLEDMng TRUE: Disabilita la gestione automatica del LED posto sul lettore chip card.
3 ChipCardLED Comanda lo stato del LED posto sul lettore chip card. Il comando è applicabile solo se gestione automatica
del LED disabilitata Command.DisableLEDMng=TRUE. Altrimenti il LED viene gestito automaticamente
dalla FB.
4 AdvancedMode FALSE: Normal mode, nessun controllo sui dati. Possono essere gestiti fino a 256 bytes.
TRUE: Advanced mode, doppia scrittura dati con CRC di controllo. Possono essere gestiti fino a 126 bytes.
5 DisablePSC
TRUE: Disabilita il controllo del PSC, da utilizzarsi per le carte Sle4432 evita che il controllo del PSC possa
deteriorare i dati presenti sulla carta.
01 Status
Bits di stato del blocco funzione, il programma utente può testare questi bits.
0 CardIn
TRUE: Indica che la chip card è stata inserita nel lettore.
1 CardReadEnd Attivata per un loop di programma al termine della lettura dati dalla chip card. Alla sua attivazione possono
essere verificati i bit: Status.WrongATR, Status.NoPSCCard, Status.VirginCard, Status.ReadDataOk,
Status.ReadDataError.
2 CardWriteEnd Attivata per un loop di programma al termine della scrittura dei dati sulla chip card. Alla sua attivazione
possono essere verificati i bit: Status.PSCFault, Status.WriteDataOk, Status.WriteDataError.
3 WrongATR
TRUE: Indica che la carta inserita nel lettore ha un codice ATR diverso da quello accettato 0xA2, 0x13, 0x10,
0x91 la carta non viene letta. Viene azzerato estraendo la carta dal lettore o con Command.Enable=FALSE.
4 VirginCard
TRUE: Indica che la carta inserita nel lettore è vergine. Viene azzerato estraendo la carta dal lettore o con
Command.Enable=FALSE.
5 NoPSCCard
TRUE: Indica che la carta inserita nel lettore non gestisce la protezione dei dati con codice PSC (è una
Sle4432). Tutte le operazioni di accesso alla carta sono comunque garantite. Viene azzerato estraendo la
carta dal lettore o con Command.Enable=FALSE.
6 PSCFault
TRUE: Indica che l'operazione di sblocco carta con codice PSC per permetterne la scrittura, non è andato a
buon fine. Il valore di PSC non è corretto.
mk:@MSITStore:U:\Cd-048\04099.013\Mnl041\Mnl041q000\Remoter.chm::/Source/... 29/02/2008
Blocchi funzione: FbSle44x2Card
Pagina 3 di 7
ATTENZIONE! Dopo 3 operazioni errate di sblocco la carta diventa inservibile. Viene azzerato ad ogni
comando di scrittura Command.WriteData=TRUE, estraendo la carta dal lettore o con
Command.Enable=FALSE.
8 ReadDataOk TRUE: Indica che la lettura della carta inserita nel lettore ha avuto esito positivo, i dati sono stati trasferiti dalla
chip card nel buffer di memoria puntato da CardData. Viene azzerato estraendo la carta dal lettore o con
Command.Enable=FALSE.
9 ReadDataError TRUE: Indica che la lettura della carta inserita nel lettore non ha avuto esito positivo. Viene azzerato
estraendo la carta dal lettore o con Command.Enable=FALSE.
A WriteDataOk TRUE: Indica che la scrittura della carta ha avuto esito positivo, , i dati sono stati trasferiti dal buffer di
memoria puntato da CardData nella chip card. Viene azzerato estraendo la carta dal lettore, con
Command.Enable=FALSE o ad ogni attivazione del bit Command.WriteData.
B WriteDataError TRUE: Indica che la scrittura della carta non ha avuto esito positivo. Viene azzerato estraendo la carta dal
lettore, con Command.Enable=FALSE o ad ogni attivazione del bit Command.WriteData.
03 ChipCardStart
Caricato dal programma utente, definisce l'indirizzo di inizio allocazione dati utente nella memoria della chip card (Range da 0x00
a 0xFF).
04 CardDataLength
Caricato dal programma utente, definisce la lunghezza dei dati utenti da gestire su chip card (Range da 0x00 a 0xFF).
05 PSCCheckAddress
Caricato dal programma utente, definisce l'indirizzo su chip card a cui verrà effettuato il controllo del PSC. Nel caso un
programma preveda l'accettazione di entrambi i tipi di carta (con PSC e senza) per evitare che il controllo del PSC possa
deteriorare i dati presenti sulla carta é possibile definire un indirizzo al di fuori del banco dati utilizzato. Non è utilizzato se
Command.DisablePSC=TRUE (Range da 0x00 a 0xFF).
06 CardData
Caricato dal programma utente, definisce l'indirizzo del buffer di memoriadove l'FB appoggia i dati letti o preleva i dati da scrivere
su chip card, occorre definire un buffer di lunghezza uguale ai dati da gestire su chip card CardDataLength in memoria RAM
(Range da 0x0000 a 0xFFFF).
08 ATRCode[4]
Contiene i 4 bytes codice ATR letto dalla chip card, il codice è 0xA2, 0x13, 0x10, 0x91.
0C ProtectionMem[4]
Buffer copia dati protection memory su chip card. La funzione ProtectionMemoryRead ritorna il valore dei 32 bits di protezione
nei 4 bytes del buffer.
10 SecurityMem[4]
Buffer copia dati security memory su chip card. La funzione PSCVerification compara il valore dei 3 bytes SecurityMem[1-2-3]
con il codice PSC della chip card e se uguali sblocca la chip card in scrittura. La funzione UpdateSecurityMemory sostituisce il
codice PSC attuale della chip card con il valore presente nei 3 bytes SecurityMem[1-2-3].
14 CardReset
Ritorna l'indirizzo della funzione di reset della chip card. Questa funzione legge il codice ATR e lo ritorna in ATRCode[4]. La
funzione và normalmente eseguita su inserzione carta nel lettore.
void CardReset(void);
Parameters
None
Return value
None
16 PSCVerification
Ritorna l'indirizzo della funzione di verifica PSC. Questa funzione confronta il valore del codice riportato in SecurityMem[1-2-3]
con il codice PSC della chip card. Se i codici corrispondono la chip card viene sbloccata in scrittura. ATTENZIONE! Dopo 3
operazioni errate di sblocco la carta si blocca irreversibilmente.
unsigned char PSCVerification(void);
Parameters
None
Return value
unsigned char 0
1
2
3
PSC code verified
Write start error
Write timeout error
Write protected area
4 Code verify error
5 Chip card locked
6 Procedure error
18 UpdateSecurityMemory
Ritorna l'indirizzo della funzione
utilizzando il valore riportato
precedentemente sbloccata con
essere sbloccata fino a quando
nuovo codice PSC definito.
di modifica del valore PSC su chip card. Questa funzione modifica il codice PSC della chip card
in SecurityMem[1-2-3]. Naturalmente l'operazione è possibile solo se la carta è stata
la funzione PSCVerification. ATTENZIONE! Dopo aver modificato il codice, la carta continua ad
non viene estratta dal lettore. Al successivo reinserimento, per sbloccarla occorrerà utilizzare il
unsigned char UpdateSecurityMemory(void);
mk:@MSITStore:U:\Cd-048\04099.013\Mnl041\Mnl041q000\Remoter.chm::/Source/... 29/02/2008
Blocchi funzione: FbSle44x2Card
Pagina 4 di 7
Parameters
None
Return value
unsigned char 0 PSC code verified
1 Write start error
2 Write timeout error
3 Write protected area
1A MainMemoryRead
Ritorna l'indirizzo della funzione di lettura main memory. Questa funzione esegue la lettura di un byte dalla memoria principale
della chip card.
unsigned char MainMemoryRead(unsigned char Address, unsigned char* Data);
Parameters
unsigned char Address
unsigned char* Data
Address di lettura dato su chip card (Da 0x00 a 0xFF)
Address buffer di memorizzazione dato letto (Da 0x0000 a 0xFFFF)
Return value
unsigned char
Dato letto da chip card (Da 0x00 a 0xFF)
1C MainMemoryWrite
Ritorna l'indirizzo della funzione di scrittura main memory. Questa funzione esegue la scrittura di un byte nella memoria principale
della chip card. Naturalmente l'operazione è possibile solo se la carta è stata precedentemente sbloccata con la funzione
PSCVerification. Prima di eseguire la scrittura viene verificato se dato già presente, in tal caso non viene scritto minimizzando il
numero di accessi in scrittura della memoria.
unsigned char MainMemoryWrite(unsigned char Address, unsigned char Data);
Parameters
unsigned char Address
unsigned char Data
Return value
unsigned char
Address di scrittura dato su chip card (Da 0x00 a 0xFF)
Dato da scrivere su chip card (Da 0x00 a 0xFF)
0 Write ok
1 Write start error
2 Write timeout error
3 Write protected area
4 Error improper write
1E ProtectionMemoryRead
Ritorna l'indirizzo della funzione di lettura protection memory. Questa funzione esegue la lettura dei 4 bytes di memoria di
protezione della chip card e trasferisce il valore letto nel buffer ProtectionMem[4].
void ProtectionMemoryRead(void);
Parameters
None
Return value
None
20 ProtectionMemoryWrite
Indirizzo funzione di scrittura di un byte di memoria di protezione sulla chip card. Naturalmente l'operazione è possibile solo se la
carta è stata precedentemente sbloccata con la funzione PSCVerification.
unsigned char ProtectionMemoryWrite(unsigned char Address, unsigned char Data);
Parameters
unsigned char Address
unsigned char Data
Return value
unsigned char
Address di scrittura dato su chip card (Da 0x00 a 0x1F)
Dato da scrivere su chip card (Da 0x00 a 0xFF)
0 Write ok
1 Write start error
2 Write timeout error
3 Write protected area
Esempio RIL
Nel seguente esempio viene eseguita la gestione di un lettore per chip card. I dati della chip card sono memorizzati a partire dal byte
Y 0000 fino al byte Y 000F. All'inserimento della chip card nel lettore essa viene automaticamente letta e se i dati contenuti sono
corretti il LED sul lettore si accende. In caso contrario esso lampeggerà con il numero dell'errore riscontrato.
Attivando l'ingresso I 0000 viene gestita la scrittura dei dati sulla chip card, naturalmente occorrerà settare il corretto valore di codice
PSC in SecurityMem[1-2-3] prima di eseguire il comando. Nell'esempio si ipotizza l'impiego di una scheda vergine il cui PSC è 0xFF,
0xFF, 0xFF.
;
;
;
;
-----------------------------------------------------------------------------@Section("Local definitions")
-----------------------------------------------------------------------------FbSle44x2Card function block, data structure.
mk:@MSITStore:U:\Cd-048\04099.013\Mnl041\Mnl041q000\Remoter.chm::/Source/... 29/02/2008
Blocchi funzione: FbSle44x2Card
;
;
;
;
;
DEFG
DEFG
DEFG
Y
Y
W
Chc
ChcCommand
ChcStatus
DEFG
DEFG
DEFG
DEFG
Y
Y
Y
W
DEFG
DEFG
DEFG
DEFG
DEFG
DEFG
DEFG
DEFG
DEFG
DEFG
KD
Y
Y
40
Chc
Chc
KH
KH
0000
0001
;Chc.Command
;Chc.Status
ChcChipCardStart Y Chc
ChcCardDataLength Y Chc
ChcPSCCheckAddress Y Chc
ChcCardData Y
Chc
KH
KH
KH
KH
0003
0004
0005
0006
;Chc.ChipCardStart
;Chc.CardDataLength
;Chc.PSCCheckAddress
;Chc.CardData
DW
DW
DW
ChcATRCode Y
Chc
ChcProtectionMem Y Chc
ChcSecurityMem Y Chc
KH
KH
KH
0008
000C
0010
;Chc.ATRCode
;Chc.ProtectionMem
;Chc.SecurityMem
W
W
W
W
W
W
W
ChcCardReset Y Chc
KH 0014
ChcPSCVerification Y Chc
KH 0016
ChcUpdateSecurityMemory Y Chc KH 0018
ChcMainMemoryRead Y Chc
KH 001A
ChcMainMemoryWrite Y Chc
KH 001C
ChcProtectionMemoryRead Y Chc KH 001E
ChcProtectionMemoryWrite Y Chc KH 0020
;Chc.CardReset
;Chc.PSCVerification
;Chc.UpdateSecurityMemory
;Chc.MainMemoryRead
;Chc.MainMemoryWrite
;Chc.ProtectionMemoryRead
;Chc.ProtectionMemoryWrite
-----------------------------------------------------------------------------@Section("Program init")
-----------------------------------------------------------------------------FbSle44x2Card function block, variables settings.
Set the chip card data buffer at address Y 0000.
ORGR
LODT
MOVA
MOVI
MOVI
LTCH
LTCH
;
;
;
;
;
Pagina 5 di 7
F
W
Y
Y
Y
Y
PLCFirstLoop
ChcCardData Y
0000
ChcChipCardStart KH 0020
ChcCardDataLength KD 16
ChcCommand BD 4
ChcCommand BD 0
;Chc.CardData
;Chc.ChipCardStart
;Chc.CardDataLength
;Chc.Command.AdvancedMode
;Chc.Command.Enable
-----------------------------------------------------------------------------@Section("FbSle44x2Card function block management")
-----------------------------------------------------------------------------When card is inseterted in the reader the chip card data from 0x20 to 0x2F are
automatically copied to the memory from Y 0000 to Y 000F.
ORGR
SETR
TASK
L
FbSle44x2Card Y Chc
;Sle44x2Card management
; By activating the input I 0000 the data from Y 0000 to Y 000F are stored in the
; chip card from address 0x20 to 0x2F.
ORGR
LODT
PULS
MOVI
LTCH
I
0000
DW
Y
ChcSecurityMem KH FFFFFF
ChcCommand BD 1
;Chc.SecurityMem
;Chc.Command.WriteData
; [End of file]
Esempio "C"
Nel seguente esempio viene eseguita la gestione di un lettore per chip card. I dati letti dalla chip card sono memorizzati nel buffer
CardData. All'inserimento della chip card nel lettore essa viene automaticamente letta e se i dati contenuti sono corretti il LED sul
lettore si accende. In caso contrario esso lampeggerà con il numero dell'errore riscontrato.
Attivando l'ingresso I 0000 viene gestita la scrittura dei dati sulla chip card, naturalmente occorrerà settare il corretto valore di codice
PSC in SecurityMem[1-2-3] prima di eseguire il comando. Nell'esempio si ipotizza l'impiego di una scheda vergine il cui PSC è 0xFF,
0xFF, 0xFF.
Attivando l'ingresso I 0001 viene modificato il codice PSC della carta impostandolo a 0x12, 0x34, 0x56. Il nuovo codice sarà valido
solo dopo aver estratto la carta dal lettore. ATTENZIONE! non eseguire comandi di scrittura sulla carta I 0000 con il codice PSC
modificato, dopo 3 tentativi la carta diventa inutilizzabile.
mk:@MSITStore:U:\Cd-048\04099.013\Mnl041\Mnl041q000\Remoter.chm::/Source/... 29/02/2008
Blocchi funzione: FbSle44x2Card
Pagina 6 di 7
Attivando l'ingresso I 0002 viene modificato il codice PSC della carta riportandolo a quello di di una scheda vergine 0xFF, 0xFF,
0xFF.
// ----------------------------------------------------------------------------// FILE INCLUSIONS
// ----------------------------------------------------------------------------#include
#include
#include
#include
#include
<stdio.h>
<string.h>
<ElSystemLib.h>
<ElPLCLib.h>
<FbSle44x2Card.h>
// ----------------------------------------------------------------------------// EXAMPLE PROGRAM
// ----------------------------------------------------------------------------void Example(void)
{
// Local variable definitions.
unsigned char ErrorCode; //Error code
static unsigned char LogInput; //Logic inputs
static unsigned char OneShot; //Logic inputs one shot
static unsigned char CardData[110]; //Chip card data buffer
static FBSLE44X2CARDDATA Chc; //Chip card data structure
//
//
//
//
------------------------------------------------------------------------PROGRAM INIT
------------------------------------------------------------------------At first program loop initialize all variables.
if (PLCFirstLoop)
{
Chc.CardData=&CardData; //Card data address
Chc.ChipCardStart=0x20; //Chip card start address
Chc.CardDataLength=sizeof(CardData); //Card data length
Chc.PSCCheckAddress=0x20; //PSC check address
Chc.Command.AdvancedMode=TRUE; //Advanced mode selection
Chc.Command.DisablePSC=FALSE; //Disable PSC management
Chc.Command.Enable=TRUE; //Enable chip card management
}
//
//
//
//
------------------------------------------------------------------------CHIP CARD MANAGEMENT
------------------------------------------------------------------------Execute the logic input read and manages the one shot buffer.
OneShot=LogInput; //Logic inputs one shot
PeripheralInp(0, 0, &LogInput);
// Execute the chip card reader management.
ErrorCode=0; //Error code
FbSle44x2Card(&Chc); //Chip card management
// By activating the logic input I 0000 the chip card is written using data
// from "CardData" buffer.
if (((LogInput^OneShot)&LogInput)&0x01)
{
// Set the PSC code to unlock the chip card and command the data write.
memcpy(&Chc.SecurityMem[1], "\xFF\xFF\xFF", 3);
Chc.Command.WriteData=TRUE; //Write data to chip card
}
// By activating the logic input I 0001 the chip card PSC is modified from
// the previous value 0xFF, 0xFF, 0xFF to the new value 0x12, 0x34, 0x56.
mk:@MSITStore:U:\Cd-048\04099.013\Mnl041\Mnl041q000\Remoter.chm::/Source/... 29/02/2008
Blocchi funzione: FbSle44x2Card
Pagina 7 di 7
if (((LogInput^OneShot)&LogInput)&0x02)
{
// Set the previous PSC code and unlock the chip card.
memcpy(&Chc.SecurityMem[1], "\xFF\xFF\xFF", 3);
ErrorCode|=Chc.PSCVerification(); //Error code
// Set the new PSC code on the chip card.
memcpy(&Chc.SecurityMem[1], "\x12\x34\x56", 3);
ErrorCode|=Chc.UpdateSecurityMemory(); //Error code
}
// By activating the logic input I 0002 the chip card PSC is modified from
// the previous value 0x12, 0x34, 0x56 to the new value 0xFF, 0xFF, 0xFF.
if (((LogInput^OneShot)&LogInput)&0x04)
{
// Set the previous PSC code and unlock the chip card.
memcpy(&Chc.SecurityMem[1], "\x12\x34\x56", 3);
ErrorCode|=Chc.PSCVerification(); //Error code
// Set the new PSC code on the chip card.
memcpy(&Chc.SecurityMem[1], "\xFF\xFF\xFF", 3);
ErrorCode|=Chc.UpdateSecurityMemory(); //Error code
}
// Printout a message if an error is detected.
if (ErrorCode)
{
SetTermIOVectors(IOSerialPortA); //Set the serial port A as I/O console
printf("An error is detected.\r\n");
}
}
// [End of file]
mk:@MSITStore:U:\Cd-048\04099.013\Mnl041\Mnl041q000\Remoter.chm::/Source/... 29/02/2008