Why can fread() not work (skipping bytes) under Msys/MinGw? - c

Trying to build Xuggler under Windows. Xuggler is core native code functions wrapped into Java for sound processing purposes (including ffmpeg).
My Windows is x64 Win 7 prof, but all used libraries are 32bit. I am running build procedure under MinGW/MSys, from under Msys shell with the followinf script:
#!/bin/sh
export JAVA_HOME=/C/Program\ Files\ \(x86\)/Java/jdk1.6.0_25
export XUGGLE_HOME=/C/Xuggler
PATH=$XUGGLE_HOME/bin:/C/Program\ Files\ \(x86\)/Java/jdk1.6.0_25/bin:/d/APPS/msysgit/msysgit/bin/git:/D/APPS/MinGW/bin:/bin:/D/APPS/apa che-ant-1.8.2/bin:/D/Users/Dims/Design/MinGW/Util:$PATH
ant -Dbuild.m64=no run-tests
Ant target contains some tests at the end, which give an error. The error follows
[exec] Running 6 tests..
[exec] In StdioURLProtocolHandlerTest::testRead:
[exec] ../../../../../../../../../test/csrc/com/xuggle/xuggler/io/StdioURLProtocolHandlerTest.cpp:108: Error: Expected (4546420 == totalBytes), found (4546420 != 1042)
[exec] In StdioURLProtocolHandlerTest::testReadWrite:
[exec] ../../../../../../../../../test/csrc/com/xuggle/xuggler/io/StdioURLProtocolHandlerTest.cpp:185: Error: Expected (4546420 == totalBytes), found (4546420 != 1042)
[exec] In StdioURLProtocolHandlerTest::testSeek:
[exec] ../../../../../../../../../test/csrc/com/xuggle/xuggler/io/StdioURLProtocolHandlerTest.cpp:139: Error: Expected (4546420 == totalBytes), found (4546420 != 1042)
[exec] .
[exec] Failed 3 of 6 tests
[exec] Success rate: 50%
[exec] FAIL: xugglerioTestStdioURLProtocolHandler.exe
UPDATE 1
The test code is follows:
int32_t totalBytes = 0;
do {
unsigned char buf[2048];
retval = handler->url_read(buf, (int)sizeof(buf));
if (retval > 0)
totalBytes+= retval;
} while (retval > 0);
VS_TUT_ENSURE_EQUALS("", 4546420, totalBytes);
While the url_read code is follows:
int
StdioURLProtocolHandler :: url_read(unsigned char* buf, int size)
{
if (!mFile)
return -1;
return (int) fread(buf, 1, size, mFile);
}
I don't understand, under what circumstances it can return 1042??? May be 64 bits play here somehow?
UPDATE 2
I printed out filename used and it was
d:/......./../../../test/fixtures/testfile.flv
the path is correct, but started with d:/ not with /d/
Can this play a role under Msys?
UPDATE 3
I have compared the readen bytes with real content of the test file and found, that fread() skips some bytes for some reason. Don't know which bytes yet, probably these are CR/LF
UPDATE 4
Not related with CR/LF I guess.
Original bytes are
46 4C 56 01 05 00 00 00 09 00 00 00 00 12 00 00 F4 00 00 00 00 00 00 00 02 00 0A 6F 6E 4D 65 74 61 44 61 74 61 08 00 00 ...
readen bytes are
46 4C 56 15 00 09 00 00 12 00 F4 00 00 00 02 0A 6F 6E 4D 65 74 61 44 61 74 61 80 00 B0 86 47 57 26 17 46 96 F6 E0 40 62 ...
This is FLV file begin. I don't understand the ptinciple of corruption.
How can 01 05 00 00 transform to just 15???
UPDATE 5
File opening done like following
void
StdioURLProtocolHandlerTest :: testRead()
{
StdioURLProtocolManager::registerProtocol("test");
URLProtocolHandler* handler = StdioURLProtocolManager::findHandler("test:foo", 0,0);
VS_TUT_ENSURE("", handler);
int retval = 0;
retval = handler->url_open(mSampleFile, URLProtocolHandler::URL_RDONLY_MODE);
VS_TUT_ENSURE("", retval >= 0);
int32_t totalBytes = 0;
printf("Bytes:\n");
do {
//...
url_open() function follows:
int StdioURLProtocolHandler :: url_open(const char *url, int flags)
{
if (!url || !*url)
return -1;
reset();
const char * mode;
switch(flags) {
case URLProtocolHandler::URL_RDONLY_MODE:
mode="r";
break;
case URLProtocolHandler::URL_WRONLY_MODE:
mode="w";
break;
case URLProtocolHandler::URL_RDWR_MODE:
mode="r+";
break;
default:
return -1;
}
// The URL MAY contain a protocol string. Find it now.
char proto[256];
const char* protocol = URLProtocolManager::parseProtocol(proto, sizeof(proto), url);
if (protocol)
{
size_t protoLen = strlen(protocol);
// skip past it
url = url + protoLen;
if (*url == ':' || *url == ',')
++url;
}
// fprintf(stderr, "protocol: %s; url: %s; mode: %s\n", protocol, url, mode);
mFile = fopen(url, mode);
if (!mFile)
return -1;
return 0;
}

Should be fixed in the GIT repository on the cross_compile branch as of today. I will roll this into tip of tree later this week / early next week.
Now the stdio handler opens all files as binary.

Related

Windows Cmd: cannot get the input character properly

I cannot get my input character value properly. Here is my code:
#include <stdlib.h>
void main()
{
char buf_in[32] = { 0 };
printf("input: ");
gets_s(buf_in, 32);
for (int i = 0; i < 32; i++)
printf("%02x ", buf_in[i]);
getchar();
}
I input the character by <alt-254>, but the result is 74 00 00 ..., not fe 00 00 ....
Here is my local environment: chcp 936.
And I test in some different local environments (ANSI code page 936):
1. OEM code page 936 result : 74 00 00 ...
2. OEM code page 65001 result : 00 00 00 ... (weird)
3. OEM code page 1250 result : 3f 00 00 ...
4. OEM code page 437 result : 5f 00 00 ...
I think ALT-codes are not supported by windows console. Please look here:
Alt Codes in Batch
You can try to put ALT-code (or any other data...) in file and then redirect input to Your program:
./prog.exe < input.txt
To be sure that you put proper value in file i suggest to use hex editor (like XVI32)
Does it work for other characters?

Creating a DER formatted ECDSA signature from raw r and s

I have a raw ECDSA signature: R and S values. I need a DER-encoded version of the signature. Is there a straightforward way to do this in openssl using the c interface?
My current attempt is to use i2d_ECDSA_SIG(const ECDSA_SIG *sig, unsigned char **pp) to populate an ECDSA_SIG*. The call returns non-zero but the target buffer doesn't seem to be changed.
I'm intiailly filling my ECDSA_SIG wtih r and s values. I don't see any errors. The man page says r and s should be allocated when I call ECDSA_SIG_new
ECDSA_SIG* ec_sig = ECDSA_SIG_new();
if (NULL == BN_bin2bn(sig, 32, (ec_sig->r))) {
dumpOpenSslErrors();
}
DBG("post r :%s\n", BN_bn2hex(ec_sig->r));
if (NULL == BN_bin2bn(sig + 32, 32, (ec_sig->s))) {
dumpOpenSslErrors();
}
DBG("post s :%s\n", BN_bn2hex(ec_sig->s));
S and R are now set:
post r :397116930C282D1FCB71166A2D06728120CF2EE5CF6CCD4E2D822E8E0AE24A30
post s :9E997D4718A7603942834FBDD22A4B856FC4083704EDE62033CF1A77CB9822A9
now to make the encoded signature.
int sig_size = i2d_ECDSA_SIG(ec_sig, NULL);
if (sig_size > 255) {
DBG("signature is too large wants %d\n", sig_size);
}
DBG("post i2d:%s\n", BN_bn2hex(ec_sig->s));
s hasn't changed:
post i2d:9E997D4718A7603942834FBDD22A4B856FC4083704EDE62033CF1A77CB9822A9
At this point I have more than enough bytes ready and I set the target to all 6s so it's easy to see what changes.
unsigned char* sig_bytes = new unsigned char[256];
memset(sig_bytes, 6, 256);
sig_size = i2d_ECDSA_SIG(ec_sig, (&sig_bytes));
DBG("New size %d\n", sig_size);
DBG("post i2d:%s\n", BN_bn2hex(ec_sig->s));
hexDump("Sig ", (const byte*)sig_bytes, sig_size);
The new size is 71
New size 71 and s iis stiill the same:
`post i2d:9E997D4718A7603942834FBDD22A4B856FC4083704EDE62033CF1A77CB9822A9`
The hex dump is all 6s.
--Sig --
0x06: 0x06: 0x06: 0x06: 0x06: 0x06: 0x06: 0x06:
0x06: ...
The dump is still all 6s even though the call didn't return 0. What am I missing tying to DER encode this raw signature?
i2d_ECDSA_SIG modifies its second argument, increasing it by the size of the signature. From ecdsa.h:
/** DER encode content of ECDSA_SIG object (note: this function modifies *pp
* (*pp += length of the DER encoded signature)).
* \param sig pointer to the ECDSA_SIG object
* \param pp pointer to a unsigned char pointer for the output or NULL
* \return the length of the DER encoded ECDSA_SIG object or 0
*/
int i2d_ECDSA_SIG(const ECDSA_SIG *sig, unsigned char **pp);
So you need to keep track of the original value of sig_bytes when you call i2d_ECDSA_SIG:
int sig_size = i2d_ECDSA_SIG(ec_sig, NULL);
unsigned char *sig_bytes = malloc(sig_size);
unsigned char *p;
memset(sig_bytes, 6, sig_size);
p = sig_bytes;
new_sig_size = i2d_ECDSA_SIG(_sig, &p);
// The value of p is now sig_bytes + sig_size, and the signature resides at sig_bytes
Output:
30 45 02 20 39 71 16 93 0C 28 2D 1F CB 71 16 6A
2D 06 72 81 20 CF 2E E5 CF 6C CD 4E 2D 82 2E 8E
0A E2 4A 30 02 21 00 9E 99 7D 47 18 A7 60 39 42
83 4F BD D2 2A 4B 85 6F C4 08 37 04 ED E6 20 33
CF 1A 77 CB 98 22 A9

fread only reading in from the first time I ran the program

When I first run I would add 3 records, which gives me a count of 3. Then I fwrite the count into a bin file, and the records into a bin file, then I close the program.
When I reopen it and then I fread in and it will give me my 3 records and a count of 3. But from there on, no matter if I back up or when I read in, it will give me the same count 3 and 3 records, though since the count isn't being updated either this may be why fread is only reading in the first time records.
I am not sure why the counter isn't updating. Both fread and fwrite are returning = success so I am not sure what`s up.
void backUp(PAYROLL employee[], long int *pCounter)
{
FILE *counter;
errno_t result1 = fopen_s(&counter, "c:\\myFiles\\counter.bin", "a+b");
if (result1 == 0){
fwrite(pCounter, sizeof(long int), 1, counter);
fclose(counter);
}
else
printf("Back up of counter failed! error:%d",result1);
FILE *record;
errno_t result2 = fopen_s(&record, "c:\\myFiles\\record.bin", "a+b");
if (result2 == 0){
fwrite(employee, *pCounter *sizeof(PAYROLL), 1, record);
fclose(record);
}
else
printf("Back up of record failed! error:%d", result2);
}
void upload(PAYROLL employee[], long int *pCounter)
{
FILE *counter;
errno_t result1 = fopen_s(&counter, "c:\\myFiles\\counter.bin", "a+b");
if (result1 == 0){
result = fread(pCounter, sizeof(long int), 1, counter);
fclose(counter);
printf("Counter:%d", *pCounter);
}
else
printf("Upload up of counter failed!");
FILE *record;
errno_t result2 = fopen_s(&record, "c:\\myFiles\\record.bin", "r+b");
if (result2 == 0)
{
result2 = fread(employee, *pCounter *sizeof(PAYROLL), 1, record);
printf("Upload successful!\n");
fclose(record);
}
else
printf("Error opening file!");
}
Transferring the most salient comments into an answer.
Weathervane commented:
How do you know that fread and fwrite are returning "success" when you have not checked their return value?
Jude commented:
I look through the debugger and step in to the function, result is giving me their success return values (if that's how it works).
Weathervane commented:
You still need that in the program. Without that sort of checking, your code will be blown over by a puff of wind.
Dmitri correctly observed:
Looks like everywhere you open in append mode "a+b" you should probably be using something else ("rb" in upload() and "wb" in backUp() possibly?)
Jude commented:
I don't understand, is there a specific function for error checking? As I had always thought that error checking was just looking at what goes in the value of result and then I can go check what the value means?
Look at the specification of fread() and
fwrite(). They return the number of records written or read, which may be less than the number requested. If you get a short write, then you have a problem — maybe out of disk space. If you get a short read, it may be that you requested 100 records but there were only 1 or 10 or 99 available to read (or there was an error). If you don't capture and check the return value, you've no idea what happened.
Jude commented:
I see they read and write 1, but it still stores the first 3 elements of my struct array. I assume it's one because it's only writing my array?
fread() (and fwrite() too) give you considerable flexibility because you can supply the size of an item and the number of items separately. You use:
result2 = fread(employee, *pCounter *sizeof(PAYROLL), 1, record);
This tells fread() to read 1 item of size *pCounter * sizeof(PAYROLL). You will get a result of 1 (success) or 0 (failure). You could have specified:
result2 = fread(employee, sizeof(PAYROLL), *pCounter, record);
which would tell you how many records of size sizeof(PAYROLL) were read, up to a maximum of the value in *pCounter. You might get 0 or 1 or …
Here is some workable code that does more or less what's required. The main() program demonstrates working with 1, 2 and 3 records (and the names are a few kings and queens of England, along with the year of their ascension to the throne as their employee ID number). I had to create a minimal payroll structure since the question didn't provide one.
#include <stdio.h>
#include <string.h>
#include <errno.h>
typedef struct PAYROLL
{
long emp_id;
char emp_name[32];
} PAYROLL;
static const char counter_bin[] = "counter.bin";
static const char records_bin[] = "records.bin";
static
void backUp(PAYROLL employee[], long int *pCounter)
{
FILE *counter = fopen(counter_bin, "wb");
if (counter != 0){
fwrite(pCounter, sizeof(long int), 1, counter);
fclose(counter);
}
else
fprintf(stderr, "Back up of counter failed! error: %d %s\n", errno, strerror(errno));
FILE *record = fopen(records_bin, "wb");
if (record != 0){
fwrite(employee, *pCounter *sizeof(PAYROLL), 1, record);
fclose(record);
}
else
fprintf(stderr, "Back up of records failed! error: %d %s\n", errno, strerror(errno));
}
static
void upload(PAYROLL employee[], long int *pCounter)
{
FILE *counter = fopen(counter_bin, "rb");
if (counter != 0){
size_t result = fread(pCounter, sizeof(long int), 1, counter);
fclose(counter);
if (result != 0)
printf("Counter: %ld\n", *pCounter);
else
fprintf(stderr, "Failed to read counter\n");
}
else
fprintf(stderr, "Upload up of counter failed!\n");
FILE *record = fopen(records_bin, "r+b");
if (record != 0)
{
size_t result2 = fread(employee, *pCounter * sizeof(PAYROLL), 1, record);
if (result2 == 1)
printf("Upload successful!\n");
else
fprintf(stderr, "Failed to read records!\n");
fclose(record);
}
else
fprintf(stderr, "Error opening file!");
}
int main(void)
{
PAYROLL emps[] =
{
{ 1066, "William the Conqueror" },
{ 1819, "Victoria" },
{ 1689, "William and Mary" },
};
for (int i = 1; i <= 3; i++)
{
long emp_count = i;
printf("Employee count = %ld\n", emp_count);
backUp(emps, &emp_count);
upload(emps, &emp_count);
for (int j = 0; j < emp_count; j++)
printf("%4ld: %s\n", emps[j].emp_id, emps[j].emp_name);
}
return 0;
}
Note that I've factored out the file names so that you only have to change a single line to change the files used. Sample output:
$ Employee count = 1
Counter: 1
Upload successful!
1066: William the Conqueror
Employee count = 2
Counter: 2
Upload successful!
1066: William the Conqueror
1819: Victoria
Employee count = 3
Counter: 3
Upload successful!
1066: William the Conqueror
1819: Victoria
1689: William and Mary
$ odx counter.bin
0x0000: 03 00 00 00 00 00 00 00 ........
0x0008:
$ odx records.bin
0x0000: 2A 04 00 00 00 00 00 00 57 69 6C 6C 69 61 6D 20 *.......William
0x0010: 74 68 65 20 43 6F 6E 71 75 65 72 6F 72 00 00 00 the Conqueror...
0x0020: 00 00 00 00 00 00 00 00 1B 07 00 00 00 00 00 00 ................
0x0030: 56 69 63 74 6F 72 69 61 00 00 00 00 00 00 00 00 Victoria........
0x0040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x0050: 99 06 00 00 00 00 00 00 57 69 6C 6C 69 61 6D 20 ........William
0x0060: 61 6E 64 20 4D 61 72 79 00 00 00 00 00 00 00 00 and Mary........
0x0070: 00 00 00 00 00 00 00 00 ........
0x0078:
$
(odx is just a hex dump program. Pick your own program that does an equivalent job — od -c is a fallback, though I don't particularly like its formatting.)
I see many faults in your program.
Firstly, you are writing long ints and PAYROLL structures directly to a file. You should never do that, as structures and integers have a machine-dependent representation and if you write the files on one machine (let's say 32-bit machine) and read them on another machine (let's say 64-bit machine) then you might run into problems.
Secondly, you're not checking the return value of fread(). It should be always checked.
Thirdly, you're assigning the return value of fread() to an errno_t. Are you sure you really want to do that?
If you want to have the answer to the actual problem, consider updating the source code to fix the mistakes I pointed out and consider improving the English language in your question. Furthermore, you should provide a complete example, i.e. one that contains the definition of PAYROLL. When you know the actual return value of fread(), perhaps the problem will be easier to track down then.

PC/SC: "Card not transacted" when using C-API Calls

A few weeks ago I began experimenting with smart cards for an university project. The exercise was as easy as using a health insurance card (the German one, "eGK") and find out what's saved on it and read out the "public" parts which can be read out without prior authenticating in any way.
Fourtunately the structure of the card is well documented and the documentation can easily be downloaded from the internet. What I basically want to to now is selecting the EF (MF / DF.HCA / EF.VD) and read out the data. The file I want to read out is a binary file. According to the documentation, the first 2x4 bytes represent the start/end-offsets of two parts of the file. Each part should be gzip-compressed XML.
At first, I used "scriptor" from the pcsc-lite tools to try out a few commands, to see if it works and if I get some reasonable results. This all worked out pretty well :)
$ scriptor
No reader given: using Towitoko Chipdrive USB 00 00
Using T=1 protocol
Reading commands from STDIN
reset
> RESET
< OK: 3B DD 97 FF 81 B1 FE 45 1F 03 00 64 04 05 08 03 73 96 21 D0 00 90 00 C8
00 a4 04 0c 06 d2 76 00 00 01 02 # Select DF
> 00 a4 04 0c 06 d2 76 00 00 01 02
< 90 00 : Normal processing.
00 a4 02 0c 02 d0 02 # Select EF
> 00 a4 02 0c 02 d0 02
< 90 00 : Normal processing.
00 b0 00 00 08 # Read out start/end offsets
> 00 b0 00 00 08
< 00 08 01 AD 01 AE 02 7C 90 00 : Normal processing.
As you can see, this would be over 400 Bytes to read out (and decompress them afterwards), so I decided I need to write some program which reads this out for me. With the help of this blogpost: http://ludovicrousseau.blogspot.de/2010/04/pcsc-sample-in-c.html I was quickly able to send my first commands to the card using C. The basic flow of my program is:
Establish a context
Get a reader (the program prints out the reader in use and it's the only and the right one ;) )
Get the card (protocol is T=1)
Reset the card
Tell PC/SC I need a transaction
Transmit the commands
End transaction
Here are the fields I send to the SC:
// CLA INS P1 P2 LEN_SEND
BYTE cmdSelectDF[] = {0x00, 0xA4, 0x04, 0x0C, 0x06,
// 00 SELECT DF/AID first/noanswer
// <- HEADER] ----- [DATA ->
// D6 D5 D4 D3 D2 D1
0xD2, 0x76, 0x00, 0x00, 0x01, 0x02};
// CLA INS P1 P2 LEN_SEND
BYTE cmdSelectEF[] = {0x00, 0xA4, 0x02, 0x0C, 0x02,
// 00 SELECT EF/FID first/noanswer
// <- HEADER] ----- [DATA ->
// D2 D1
0xD0, 0x02};
// CLA INS P1 P2 LEN_RECV
BYTE cmdReadOffsets[] = {0x00, 0xB0, 0x00, 0x00, 0x08};
// 00 READ BINARY OFFSET1 OFFSET2 BYTES
The first two commands transmit just fine and I always get a 0x90 0x00 back. Unfortunately, the ReadOffsets-Transmit returns with an error: "Transaction failed". The log says the following:
00000011 winscard.c:1613:SCardTransmit() Send Protocol: T=1
00042572 winscard.c:1658:SCardTransmit() UnrefReader() count was: 2
00000030 winscard_svc.c:656:ContextThread() TRANSMIT rv=0x0 for client 6
03000349 winscard_svc.c:356:ContextThread() Received command: TRANSMIT from client 6
00000043 readerfactory.c:798:RFReaderInfoById() RefReader() count was: 1
00000012 winscard.c:1613:SCardTransmit() Send Protocol: T=1
00055517 ifdwrapper.c:553:IFDTransmit() Card not transacted: 612
00000027 winscard.c:1638:SCardTransmit() Card not transacted: 0x80100016
00000010 winscard.c:1658:SCardTransmit() UnrefReader() count was: 2
00000031 winscard_svc.c:656:ContextThread() TRANSMIT rv=0x80100016 for client 6
00000297 winscard_svc.c:348:ContextThread() Client die: 6
00000029 winscard.c:230:SCardReleaseContext() Releasing Context: 0x420027B7
Does anyone have an idea what this means and why it happens? What am I doing wrong?
Thank you very much in advance!
Edit: I have some news for you. I found some #ifdefs in the towitoko driver source code for debugging purposes. Now, I have a much more detailed log file for you. The parts with [[[]]] are only in the error log file. As you can see, there isn't any difference in the bytes submitted and the bytes received at all!
01942065 winscard_svc.c:356:ContextThread() Received command: TRANSMIT from client 6
00000021 readerfactory.c:798:RFReaderInfoById() RefReader() count was: 1
00000008 winscard.c:1613:SCardTransmit() Send Protocol: T=1
IFD: Setting baudrate to 9600
IFD: Transmit: 0 40 7 0 A4 2 C 2 D0 2 3D
IO: Sending: 6F B 5 5A
IO: Sending: 0
IO: Sending: 40 7 0 A4 2 C 2 D0 2 3D
IO: Receiving: 0
IO: Receiving: 40 2 90
IFD: Receive: 0 40 2 90
IO: Receiving: 0 D2
IFD: Receive: 0 D2
00042861 winscard.c:1658:SCardTransmit() UnrefReader() count was: 2
00000011 winscard_svc.c:656:ContextThread() TRANSMIT rv=0x0 for client 6
IO: Sending: 3 7
IO: Receiving: 42 87
IFD: Status = card / no change
IO: Sending: 3 7
IO: Receiving: 40 83
IFD: Status = card / no change
[...]
02773187 winscard_svc.c:356:ContextThread() Received command: TRANSMIT from client 6
00000032 readerfactory.c:798:RFReaderInfoById() RefReader() count was: 1
00000009 winscard.c:1613:SCardTransmit() Send Protocol: T=1
IFD: Setting baudrate to 9600
IFD: Transmit: 0 0 5 0 B0 0 0 8 BD
IO: Sending: 6F 9 5 52
IO: Sending: 0
IO: Sending: 0 5 0 B0 0 0 8 BD
IO: Receiving: 0
IO: Receiving: 0 A 0
IFD: Receive: 0 0 A 0
IO: Receiving: 8 1 AD 1 AE 2 7C 90 0 EF
IFD: Receive: 8 1 AD 1 AE 2 7C 90 0 EF
[[[ 00054674 ifdwrapper.c:553:IFDTransmit() Card not transacted: 612
00000011 winscard.c:1638:SCardTransmit() Card not transacted: 0x80100016 ]]]
00054759 winscard.c:1658:SCardTransmit() UnrefReader() count was: 2
00000011 winscard_svc.c:656:ContextThread() TRANSMIT rv=0x0 for client 6
So, where does this error message come from?
Another thing I've learned is that this error doesn't seem to be reader specific. I've tried the program on a friend's internal card reader (Windows says it's a Broadcom reader), which yields to the same results. Because the only case I can think of is an error in my C program, here's the source code with the basic macros and the connection part:
// Parts taken from http://ludovicrousseau.blogspot.de/2010/04/pcsc-sample-in-c.html
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <PCSC/pcsclite.h>
#include <PCSC/winscard.h>
#include <PCSC/wintypes.h>
#define EGK_RECV_BUFSIZE 258
#define PCSC_ERROR(debugmsg, retval) \
if(retval != SCARD_S_SUCCESS) { \
fprintf(stderr, "PC/SC Error at %s: %s\n", debugmsg, pcsc_stringify_error(retval)); \
return 1; \
}
#define TRANS_RESPONSE \
printf("Command response: "); \
for(i = 0; i < dwRecvLen; i++) { \
printf("%02X ", recvBuffer[i]); \
} printf("\n");
#define CHECK_SUCCESS \
if(dwRecvLen >= 2) { \
if(recvBuffer[dwRecvLen-2] == 0x90 && recvBuffer[dwRecvLen-1] == 0x00) { \
printf("Command success!\n"); \
} \
}
#define SCARD_TRANSMIT(cmd) \
SCardTransmit(scHandle, &scSendProto, cmd, sizeof(cmd), NULL, recvBuffer, &dwRecvLen);
int main(void)
{
LONG retval = 0; // = long
SCARDCONTEXT scContext; // = LONG
LPTSTR scReaders; // = LPSTR = char *
SCARDHANDLE scHandle; // = LONG (specific smartcard)
DWORD dwReaders, dwCurProto, dwRecvLen; // = unsigned long
SCARD_IO_REQUEST scSendProto;
BYTE recvBuffer[EGK_RECV_BUFSIZE];
// BYTE cmdXXX[] = {...}; ... SEE ABOVE!
// Get Context
retval = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &scContext);
PCSC_ERROR("1 Establish Context", retval);
// Get Reader
retval = SCardListReaders(scContext, NULL, NULL, &dwReaders);
PCSC_ERROR("2.1 Get Readers", retval);
scReaders = calloc(dwReaders, sizeof(DWORD));
retval = SCardListReaders(scContext, NULL, scReaders, &dwReaders);
PCSC_ERROR("2.2 Get Readers", retval);
printf("Reader name: %s\n", scReaders);
// Get Card
retval = SCardConnect(scContext, scReaders, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, &scHandle, &dwCurProto);
PCSC_ERROR("3 SCardConnect", retval);
// Reset
retval = SCardReconnect(scHandle, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0 | SCARD_PROTOCOL_T1, SCARD_RESET_CARD, &dwCurProto);
PCSC_ERROR("4 RESET Card", retval);
dwRecvLen = EGK_RECV_BUFSIZE;
if(dwCurProto == SCARD_PROTOCOL_T0) {
scSendProto = *SCARD_PCI_T0;
} else if(dwCurProto == SCARD_PROTOCOL_T1) {
scSendProto = *SCARD_PCI_T1;
} else {
fprintf(stderr, "No known protocol selected\n");
return 1;
}
The Transmit-Part looks the same for every command. Example:
printf("READ BINARY -> First 8 Bytes (Offsets)\n");
retval = SCARD_TRANSMIT(cmdReadOffsets);
PCSC_ERROR("8 Transmit READ BINARY", retval);
TRANS_RESPONSE;
CHECK_SUCCESS; printf("\n");
Edit: Sorry this edit comes so late, I totally forgot about this post! I managed to get it working in the end by rewriting my program in Java. I know this is not quite a satisfying answer for those who may stumble upon this question. At least we can be sure now that the error lies somewhere inside the C code. Should anyone know why the program doesn't work, feel free to answer anyway, I would be really interested in knowing which mistake I made :) !

how to remove space between characters of a string using wide char to multibytes?

I have a file open in winhex look like follow.
1F 00 48 3A 18 00 00 00 53 00 70 00 6F 00 75 00
73 00 65 00 5F 00 61 00 7A 00 61 00 6D 00 00 00
I am reading the above hex data from file and write it to a text file . My code is as follow.
#include<stdlib.h>
#include<stdio.h>
#include<iostream.h>
int main()
{
FILE *pFile, *tempFile;
char *Main_buffer;
int nOfRecord, TotalSize, data=0;
pFile = fopen("C:\\wab files\\Main.wab", "rb");
if(pFile == NULL)
{
fputs("file error", stderr);
exit(1);
}
tempFile = fopen("C:\\myfile.text","wb");
if(tempFile == NULL)
{
fputs("file not open", stderr);
exit(2);
}
fread(&nOfRecord, 1, 4, pFile);
fread(&TotalSize, 1, 4, pFile);
data = TotalSize;
char* Main_buffer = (char*)malloc(data*sizeof(data));
fread(Main_buffer, 1, TotalSize, pFile);
fwrite(Main_buffer, 1, TotalSize, tempFile);
free(Main_buffer);
return 0;
}
This code gives a text file in which data is written as follow.
p a l # g m a i l . c o
In above data there is a space between each character . How to remove space from the data, and write in a text file . Please explain by writing some code as an example for wide char to multi bytes . Thanks you in advance .
There are basically 2 ways of doing it:
Manually removing spaces from the generated ASCII thing.
Use a library to do the work for you (of course if you are allowed to). My preference goes toward
http://en.wikipedia.org/wiki/Iconv
which (as said on the Wikipedia page) has a free implementation in GCC so you can try to play with it.
And here the link to the Linux lib:
http://www.gnu.org/software/libiconv/#TOCintroduction
UPDATE
Here is an example in C of how to use libiconv:
http://www.gnu.org/software/libc/manual/html_node/iconv-Examples.html
Try using strtok() from < string.h > .

Resources