Thursday, December 17, 2009

Identified the problem while WinXP installation


One day, my system has given a problem while booting. It was not booting and showing the reason that the file /windows/system32/config/system file is corrupted. I had Linux OS on the same machine and hence immediately I decided to copy the same file from other system. Also I got the system with XP. I tried to copy the file which is corrupted. But couldn’t. Because that may be the system process and which is in use. Hence XP didn’t allow me to copy the file.

Then, I thought the problem is not so simple. Also, the size of the corrupted file in my system was 7MB and the file which I have tried to copy was 4 MB, which is from Laptop.

After one week, I got other system which was also having WinXP and Linux OS. Hence I was able to get the file /windows/system32/config/system. Then I copied the file from Linux using Pen Drive and I tried to boot the system. But I got the new problem..!

After these, the error which was coming earlier didn’t come. But it was not booting properly. It was coming till the scrolling window if WinXP. Once again I failed to solve the problem.

Then I decided to reinstall the OS freshly. While installing bootable XP was not booting properly. After taking input from the user for booting from CD, screen was blank...! At the beginning I didn’t any solution. After some time, I have deleted the file /windows/system32/config/system which took from other system.

At last, I have succeeded in installing WinXP once again.

Then I asked one of my friends who is good in understanding the problems and he told that the corrupted file may me containing the hardware information or current process information which could be more specific for my system.

I also concluded as the same.
If anybody knows about this problem, please mail to pramoda.ma@gmail.com
Wish you good luck....
-

Sunday, November 22, 2009

On that day my mind thought about 'Global Static'


I had read the theory on static keyword, its role in the programming embedded systems. Also i taught in to some students about this. But till that, i never used 'static' in my real projects. At last, my mind throught about the use of 'static' keyword.

First i will tell you about the situation which made me to use the 'staitc' keyword.

I had a global function pointer say Gfptr( ) and in my INIT function of a module i was initializing the Gfptr() like following.

void (Gfptr)(void);

void INIT( )
{
void (*Lfunction)(void);
Lfunction = (FARPROC)GetprocAddress(hdll,"Adding");
Gfptr = (void*)function;
}

Here, Gfptr will be called moe than 1000 times ie., once for every 10ms. So that it can be called as 'reentrant'.

But, after some time, call to Gfptr() was failing. I was getting why...! After some time, i have printed the address of 'Gfptr' in the INIT itself, say 0x123456. Aslo i have printed the same before each call. Like,

printf("%x\n",Gfptr);
Gfptr();

I dont know why, after some time, address was printed wrongly...! Till that, address was still 0x123456. But after some time, it was not 0x123456....!

Then, 'global static' has come to mind and i made Gfptr as Global static. Then it was worked fine and i was happy...!!!

It was the first time, i thought the application of about GLOBAL STATICs.

From that time onwards, I thought to declare the global pointers as 'static'.

Friday, October 9, 2009

DLLs in Windows and Shared Objects in Linux

When first time i have worked on DLLs, creation and usage, i was felt like i have learnt a good thing of Windows. To know how to create DLLs itself i took 3 days. Usage of DLLs was necessary and also, i understood how DLLs are under use in Windows.

In my previous posts, i have already told about how to create DLLs using Visual Studio.

Now i will tell about how we use the same.

How can we use DLLs?

As for i know, DLL is nothing but executable with some memory area. Whatever functions are defined in DLLs, those will be executed in DLL's memory area. If u call a function defined in DLL, then the execution of that function will happen in DLLs memory area itself. Only address of DLL or address of function define in DLL will be appended in the executable.

When we have to call the function defined in the DLL, then we have to use the functions(APIs) of windows, LoadLibrary() and GetProcAddress().

LoadLibrary is to load the library into memory manually and GetProcAddress() is to get the address of the function defined in DLL. We have to use the function pointer to assign the address of DLL function.

Ex:
void (*FunctionPtr)(int,int, int);
hDll = LoadLibrary("OurDllFile.dll");
if(hDll)
{
FunctionPtr = GetProcAddress(hDll, "MyFunctionName");
}

Then u can call the function MyFunctionName() which is defined in OurdllFile.dll, using FunctionPtr.

As i have told in my first post about SingleByte(ASCII) or MultByte (Widecharacter), both types o f GetProcAddress() and LoadLibrary() is available.

Note: But, for both types, second parameter to GetProcAddress should be in SingleByte type.

Another thing is, if u include MyDllFile.lib file in the project work space, then functions of DLL will be automatically called and its addresses will be checked while compiling itself. No need to use LoadLibrary() and GetProcAddress(). Directly, we can call the functions.


Shared Objects in Linux Environement:

In the same way, we can use the Shared Objects in Linux with little change. First i will tell u how to create Shared objects and then i will share about its usage.

Creation

gcc -fPIC -c *.c
gcc -shared -o libMyShareObject.so *.o

Here, first line is to create object files of source (.c) files and second line is to create shared object of the name MySharedObject. I am mentioning here all source files and objects files present in the current directory using wild characters. But u can specifically mention the name of source files and object files separated by a space character.

Here, option 'fPIC' is mandatory which tells compiler to create position independent object file which is required for shared objects and 'shared' option is required for shared objects.

Note: Every shared object must start with 'lib' and followed name will be user defined.

Accessing the sared objects:

To use the shared ibjects, like DLLs in Windows, we use dlopen() and dlsym() APIs of Linux operating system. dlopen() is like Loadlibrary() and dlsym() is like GetProcAddress(). But, to use dlopen() and dlsym() APIs in our application, we have to link 'dl' library as follows.

gcc -ldl OurSource.c

See here, '-l' is replaced in the place of 'lib'(meaning is 'Link'). Actually its name will be libdl.so. In the same way we can use any shared objects and staic libraries in Linux.

Example usage:

hDll = dlopen("libMySharedObject.so")
if(hDll)
{
FunctionPtr = dlsym("MyFunctionName", RTLD_LAZY);
if(FunctionPtr)
{
FunctionPtr(); //calling the function
}
}

Like, how we include .lib file in project work space in windows, here if we compile the code by linking the shared object, then we need not to call the dlopen() and dlsym() APIs.

I will tell u in my next post about the creation of static libraries.
Please send a mail about ur doubts, sugeestions and my mistakes in my articles to pramoda.ma@gmail.com
Wish u gud luck...

Thursday, October 1, 2009

Sending SIGNALS from Shell Script to our Application: Linux Platform

Signals:

I knew that signals are like software interrupts in Linux. Earlier, I never used signals. When, my first code of device detection was inconsistent, our lead has given shell script idea and one of my friends has given signals idea.

Within next 4 days, everything was ready...!


When can we signals in our application?

If we have to do something when something happen, then we can use signals instead of constant polling using threads or processes. In our case, we were polling for device insertion detection using pthreads in Linux. Hence we shifted to use shell script independent of our application and we made shell script to send a signal to our application when device insertion is detected.

Among number of signals, two user signals are there in Linux which can be used in our application. Those are signal number 10 and 12 (SIGUSR1 and SIGUSR2).

I have used SIGUSR1 in our application.


How can we use signals in our Application?

We use ‘kill’ utility of Linux/Unix to send signals to application.

Consider the following script for example:

while [ 1 ]
do
if [ -b /dev/sdb1 ]
then
kill -10 {PID of OurApplication}
fi
done

When a valid block device is found in /dev/ directory as sdb1, then this will send a signal to our application. We have to give PID of our application to kill command.


How to get the PID of our application at run time?

When shell script implementation was over, it was working fine and robustly as a stand alone application. But when we thought to send a signal when device insertion is detected, I came to know that KILL requires PID of our application. Our next question was how to get the PID of our application at run time. Idea was combination of PS and GREP command utility.

pid = (`ps | grep OurApplication`)
kill -10 $pid

Here, OurApplication is the name of our application (say myPlayer). Variable pid will get the ProcessID of our application and use the same for sending signal.


At the END:

while [ 1 ]
do
If [ -b /dev/sdb1 ]
then
pid = (`ps | grep myPlayer`)
kill -10 $pid
fi
done

This work made to me to know about Signals and its deployment in our applications. I was happy when it was completed.

Write to me at pramoda.ma@gmail.com for ur all concerns.

Wednesday, September 30, 2009

fopen() usage using fgets() buffer: One of my bugs fixing

This article is related to one of my bug fixes. When we moved from WinCE to freescales Embedded Linux, our goal was to port the same application of WinCE to Linux. Hence we started to implement linux version of WinCE OS dependent code. Device detection is one of those implementations.

One day, when working on implementation of Device Detection code in C, we wanted to read the temp file which is the output of find command. When i read the first path from the file using fgets() function and used the same buffer in fopen(), opening a file has failed...!

system("find /home/raghu > temp");
fp = fopen("temp","r");

fgets(buffer_path, 500, fp);
fgets(buffer_path, 500, fp);//this is to avoid reading of first line in temp file which is the name of the directory itself

fp2 = fopen(buffer_path, "r");

Here, fp2 was NULL. I was shocked..! path of the file present in the buffer_path is valid, but fopen was failing..! I thought how it is possible? Then I tried,

fp2 = fopen("/home/raghu/temp","r");

Then, fopen was successful...! Then, have printed buffer_path character by character using one for loop. It was printing 'next line character' (going to next line) at the end when printed using '%d'. I have made it as '%x'. Then it has printed 'a' at the end BEFORE NULL CHARACTER. Then I tested by adding a SPACE character the end of path like,

fp2 = fopen("/home/Raghu/temp ", "r");

Then fopen has failed. I confirmed that fopen will fail if any extra character is present at the end. Then I made it like,

buffer_path[strlen(buffer_path)-1]='\0';

Then it worked fine.

In windows operating system also behavior is same as in Linux. I have tested. I had a doubt regarding this in Windows. But same behavior.

When i have done this, i got more confidence in my coding skill. From that day itself, i have involved in porting the application into linux. Hence i have understood more implementations of my colleagues on linux.

Even though coding language is same, every new implementation will give us more confidence and more happyness. Thats why i have started this blog also....

Feel free to write to me regarding ur doubts and suggestions. pramoda.ma@gmail.com

I wish u best of luck...

Sunday, September 27, 2009

Small C Program for USB device insertion detection in Linux Environment

As i have told u before in previous posts, at the first time i have written a small C program for device detection using mount  API of linux.

I am giving here that. Please look once.

void main()
{

  Char Buffer[256];
  FILE *fp1;
  system ("ls /dev/sd* > NodeList");
  fp1 = fopen (NodeList, "r");
  if(fp1 == NULL)
{
  printf("IN CM FIle Open Fail\n");
  }
pthread_create(&threadID , NULL, (void*)detect, NULL);
}

 
void detect(void)
{
  int i;
  FILE *fp;
  char Node[256];
  while (1)
  {

  fp = fopen(NodeList, “r”);
  if(!fp)
{
  Printf(“File open unsuccessful\n”);
  continue;
  }

  while(!feof(fP))  
  {
  fgets(Node, BYTES_TO_READ,pp_fd);
  i = mount(Node,"/mnt/DEVICE","vfat",0,0);
  if(i == 0 )
  {
  printf("Mounted %s\n”, DeviceNode);
  }  
fgets(Node, 256, fp);
  }
  fclose (fp);
  system ("ls /dev/sd* > NodeList");
Continue;
  }

}

Mount API of Linux returns zero when mounting is successful. Hence i am checking here the return value of mount API.

It was working fine when it was not integrated with our other modules. But when we integrated, this was not working sometimes. I dont know why it was inconsistent in our project. Hence i have implemented my other idea using shell scripting and signals. I have posted the same in previous posts. 

But it could give problem at sometimes when some hard disk or more devices are connected to the system. Also, in some embedded linux, USB device detection itself will take more time. For example, our current linux Freescale linux is taking near by 8 secaonds to create a node in /dev/ directory.  Hence our application (my shell script) also will take more time. 

If anybody finds a different and easy ways for device detection, please fell free to write to me at pramoda.ma@gmail.com.

Wish u best of luck...

Sunday, September 20, 2009

Autolaunching our Application in Embedded Linux

After all our developments, to make ready our hard ware to show our shoftware, our Application should start as soon as the system is ON.

We have used Qt 4.3 for developing HMI(GUI) application.

What I wanted to do was, our USB device detection shell script detect.sh and our GUI application 'Myplayer' both should launch when the system is switched ON. Hence i have written my own shell script at the end of init script in /etc/rc.d/rc.local file.

I have restarted the system and i was waiting for our application come up. But system is restarted but application hasn't come!

I have seen the currently running proccess using 'ps' command. My shell script was running, but after insertion of USB device, no statements were printing! i thought something is going wrong. I was trying more times.

After some time, just i have executes 'ls /mnt/Device'. This was the mounting point after USB insertion. All files were displayed!!!! I have shocked. Then i came to know, 'echo' will not print any statements because before 'console' application is started, shell script has started and hence any outputs will not come to console. I was heppy at that time.

Now i have started to think about the launching of HMI application. Actually to run our application, some paths has to be exported. I was doing this by exceuting a shell script. But those were not exported in console! Exporting of those paths were not affecting the console. Then i came to know that their scope is within the script only. Then i have written an extra statement at the end in shell script /opt/Myplayer where our application was in /opt/ directory.
I was successful.l.l.l.l.l....!!!!!!

Say example, OurStartupScript.sh would be,

export1
export2
export3
.
./opt/Myplayer

Our init script would be,

if [ -f /opt/Myplayer ]
then
sh /root/OurStrtupScript.sh &

if [ -f /root/detect.sh ]
then
sh /root/detect.sh &
fi
fi

Previously it was like,

if [ -f /opt/exportEcript.sh ]
then
/opt/exportScript.sh
/opt/Myplayer

if [ -f /root/detect.sh ]
then
sh /root/detect.sh &
fi
fi

After all, our application was starting after 1 min 40 seconds after rebooting/powering the system. Detection was robust. I was feeling happy....!!!

In my next posts, i will be sharing about the creation of shared objects in Linux and one small C program(but inconsistent) to detect the inserted device.

If u get any idea or doubt or solution or suggestion, please mail to pramoda.ma@gmail.com

Good luck.....

Tuesday, September 8, 2009

Shell Script for Embedded Linux

Following Shell script is for embedded linux if there is no nodes starting with 'sd' in /dev/ directory. In other words, if there is no HDD or other devices mounted on /dev/ directory as /dev/sda1, /dev/sda2 etc, the following script can be used.

If already some nodes are present in /dev/ directory starting with 'sd' like sda1, sda2 etc, previous script (for Desktop linux) )can be used.

while [ 1 ]
do
set ls /dev/sd[a-z][1-9]
if [ -b $1 ]
then
d=$#
else
d=0
fi
while [ 1 ]
do
set /dev/sd[a-z][1-9]
for p in "$@"
do
if [ -b "$p" ]
then
d=`expr "$d" + 1`
echo "$d"
fi
done
if [ "$d" -gt "$#" ]
then
echo Yes..Now Detected.."${@}"
mount=1
break
else
echo not yet
sleep 1
fi
done
sleep 1
echo "It has come $#"
j=0
for p in "$@"
do
arr[$j]=$p
j=`expr $j + 1`
done
echo j="$j"
echo This is the node "${arr[$#-1]}"
mount -t vfat ${arr[$#-1]} /mnt/DEVICE
ls /mnt/DEVICE
node="${arr[$#-1]}"
echo Final node is "$node"
#------------------------------------------#
d1=$j
echo j="$j" "$node"
i=0
while [ 1 ]
do
if [ -b "$node" ]
then
echo "still existing"
else
echo "Disconnected"
umount /mnt/DEVICE/
mount=0
fi
sleep 1
if [ "$mount" -eq 0 ]
then
break
else
continue
fi
done
done

Fine. I think these scripts can be optimized by the shell script experts. I have done this after long time of my Shell script usage. I have used shell script 3 years back in my academic. But because of this shell script, i was able to refresh most of the syntaxes/concepts of shell script. Thats what i needed.

I was very much happy when i completed this.

If anybody done optimization, please mail me the script to pramoda.ma@gmail.com

Saturday, September 5, 2009

Shell Script for USB Device Insertion/Removal Detection : Embedded Linux and Desktop Linux

Recently i have succeeded to write a shell script to detect the USB device insertion as well as removal in Desktop Linux and as well as fressscale's Embedded Linux.

First i have done for Embedded Linux in very simple way. But i was not sure about its working on all Linux distributions. Bcoz in some Linux, there could be HDD devices as /dev/sda1, /dev/sda2 and so on. Hence i have decided to make it work in Desktop linux and after, definitely that will work on all embedded linux also.

But my expectation was wrong. What i have executed on desktop Linux which didnt work on Embedded Linux on target. I didnt think about that's reason. Anyway after i have modified the same script to make work on Embedded linux.

Lets share tha same.

Script for Desktop Linux:

while [ 1 ]
do
set /dev/sd[a-z][1-9]
d=$#
while [ 1 ]
do
set /dev/sd[a-z][1-9]
if [ $# -gt "$d" ]
then
break
fi
echo not yet "$d"
sleep 1
done
echo "It has come $#"
j=0
for p in "$@"
do
arr[$j]=$p
j=`expr $j+1`
done
echo This is the node "${arr[$#-1]}"
mount -t vfat ${arr[$#-1]} /mnt/DEVICE
ls /mnt/DEVICE
#------------------------------------------#
d1=$#
while [ 1 ]
do
set /dev/sd[a-z][1-9]
if [ $# -lt "$d1" ]
then
break
fi
echo "Still connected"
sleep 1
done
echo "Disconnected now"
umount /mnt/DEVICE
done
done

But. this script should be running in background. Will generate the signal when device is detected or new node has come under /dev/ directory.

For which process signal has to be sent, that's PID is the input for 'kill' command. Process's PID i am getting here using 'grep'. Process name is the input for grep and 'ps' has to executed before 'grep' to get PID of the process.

When device is detected, i am mounting the same to a specific path, here is /mnt/DEVICE. In my proogram, i will read the contents of the device from the same path.

Actually, we were using thread (pthread_create) and 'mount' system call to detect the device insertion/removal. That program also i will give in y next post which could help or could give more idea to others.

Friday, August 14, 2009

Actual Program of Recursive File Reading for Windows CE

In my previous posts, i have tried to explain about Recursive File reading in Windows operating systems. But some chages are required to run the program in Windows CE. The program as follows:

void Function()
{
WIN32_FIND_DATA FileData;
HANDLE hSearch;
static RetValue=1;
unsigned char DirPath[300];
unsigned char DirPath_Temp[300];
unsigned int Count=0;
unsigned int Temp=0,Temp_2=0;
unsigned char Temp1[300];
unsigned char *Paths[300];
unsigned int Completed=0;

lstrcpy(DirPath,L"\\windows\\*.*");

Completed = 0;
hSearch = FindFirstFile(DirPath, &FileData);

while(1)
{
if(FileData.dwFileAttributes == 16 && RetValue != 0)
{
RetValue=1;
printf("directory is %S\n", FileData.cFileName);
Paths[Count] = (char*)malloc(300);
if(!Paths[Count])
{
printf("Malloc failed\n");
return -1;
}
Temp = lstrlen(DirPath);
Temp = Temp*2;
if(DirPath[Temp-2] == '*')
{
Temp = Temp - 6;
}
Temp_2 = 0;
while(Temp)
{
Temp1[Temp_2] = DirPath[Temp_2];
Temp_2++;
Temp--;
}
Temp1[Temp_2]='\0';
Temp1[Temp_2+1]='\0';
lstrcat(Temp1,FileData.cFileName);
lstrcat(Temp1,"\\");
lstrcpy(Paths[Count], Temp1);
Count++;
}
else if(FileData.dwFileAttributes == 32 && RetValue != 0)
{
RetValue=1;
Temp = lstrlen(DirPath);
Temp = Temp*2;
if(DirPath[Temp-2] == '*')
{
Temp = Temp - 6;
}
Temp_2 = 0;
while(Temp)
{
Temp1[Temp_2] = DirPath[Temp_2];
Temp_2++;
Temp--;
}
Temp1[Temp_2]='\0';
Temp1[Temp_2+1]='\0';
lstrcat(Temp1,FileData.cFileName);
printf("File read is %S\n",Temp1);
}
if(!FindNextFile(hSearch, &FileData))
{
if(GetLastError() == ERROR_NO_MORE_FILES)
{
if(Completed == Count)
{
printf("Exiting....\n");
break;
}
lstrcpy(DirPath, Paths[Completed]);
lstrcat(DirPath,"*\0.\0*\0\0\0");
Completed++;
hSearch = FindFirstFile(DirPath, &FileData);
if(!hSearch)
RetValue =0;
continue;
}
else
{
printf("Could not find next file.\n");
break;
}
}
}
FindClose(hSearch);
}

In Win32, in every directories, two hidden files will be there ('.' and '. .'). Hence two FindNextFile statements are removed here.

Thursday, August 13, 2009

How To Create DLL Files in Windows CE or Win32?

When we were trying to develop a pltform and hardware indpendent Media player for In-Vehicle Infotainment systems, our goal was to make every layer Independent!

Normally for every application in embedded domain, we classiy our work as 3 layers. (OSI layers will come after)
1. Application layer
2. OS and Device Driver layer
3. BSP and Hardware layer

Our work belongs to pure application layer where we are using Operating System services to implement our application. Further, our work will be classified as 3 layers.
1. Human Machine Interface (HMI or GUI)
2. Connectivity and Multimedia (CAM)
3. OS layer

We are not concentrating much on hardware and hence Hardware layer is excluded here.

As a first step, we have decided to separate HMI and CAM. To achieve this, creation of DLL file for the CAM layer was necessary.

With the help of some documents and googling, i was succeeded in creation of DLL in VC++ IDE as a static library. In case of static, we will include ".lib" file in the project settings(dependencies). Then the compiler automatically takes the respective DLL from the standard paths.

But it was not useful for us. Then we came to know about '.def' files (definition file). Definition file Contains Function names which are to be exported to outside of the module.

Finally we have achieved in Visual Studio 2005 IDE.

Steps to be followed:

1. Create a DLL project
2. Write your implementations without main function.
3. Add a new source file of type '.def'. It will be there is IDE.
3. Add function names which have to be accessed from other modules

The '.def' file will be like

LIBRARY "CAM_DLL_FOR_CE"
EXPORTS
FunctionName1
FunctionName2

If you build the project, you will be getting dll file in Debug/Release directory of ur workspace.

Note:
If you didnt add the '.def' file, you will not able to import the functions of DLL files.

We can discuss how to access the DLL files and its functions, in my next post.

Thursday, July 23, 2009

Recursive File Reading in Windows

In Linux command prompt or text mode, we use 'ls -r' for listing files recursively. In th same way, in windows command prompt i think we use 'dir /s' which will list the files present in the given folder and subfolders.

But our question was how to write our own function to read all files present in the folder and subfolder? Because,i think there is no spcific API in windows to print all files present in a folder recursively.

My colleague was written a small program to print files in a directolry using FindFirstFile and FindNextFile APIs of Windows. But that was not printing files in sudirectories .

Hence i thought to achieve our Recursive file searching using the same APIs. Then using file attributes of windows we have done our program. File attribute will be 16 for directories and 32 will be other than directories.

Following Program will print all the files present in the directory, recursively.

void Function()
{
WIN32_FIND_DATA FileData;
HANDLE hSearch;
static RetValue=1;
unsigned char DirPath[300];
unsigned char DirPath_Temp[300];
unsigned int Count=0;
unsigned int Temp=0,Temp_2=0;
unsigned char Temp1[300];
unsigned char *Paths[300];
unsigned int Completed=0;

lstrcpy(DirPath,L"C:\\songs\\*.*");
Completed = 0;
hSearch = FindFirstFile(DirPath, &FileData);
FindNextFileW(hSearch,&FileData);
FindNextFileW(hSearch,&FileData);

while(1)
{
if(FileData.dwFileAttributes == 16 && RetValue != 0)
{
RetValue=1;
printf("directory is %S\n", FileData.cFileName);
Paths[Count] = (char*)malloc(300);
if(!Paths[Count])
{
printf("Malloc failed\n");
return -1;
}
Temp = lstrlen(DirPath);
Temp = Temp*2;
if(DirPath[Temp-2] == '*')
{
Temp = Temp - 6;
}
Temp_2 = 0;
while(Temp)
{
Temp1[Temp_2] = DirPath[Temp_2];
Temp_2++;
Temp--;
}
Temp1[Temp_2]='\0';
Temp1[Temp_2+1]='\0';
lstrcat(Temp1,FileData.cFileName);
lstrcat(Temp1,"\\");
lstrcpy(Paths[Count], Temp1);
Count++;
}
else if(FileData.dwFileAttributes == 32 && RetValue != 0)
{
RetValue=1;
Temp = lstrlen(DirPath);
Temp = Temp*2;
if(DirPath[Temp-2] == '*')
{
Temp = Temp - 6;
}
Temp_2 = 0;
while(Temp)
{
Temp1[Temp_2] = DirPath[Temp_2];
Temp_2++;
Temp--;
}
Temp1[Temp_2]='\0';
Temp1[Temp_2+1]='\0';
lstrcat(Temp1,FileData.cFileName);
printf("File read is %S\n",Temp1);
}
if(!FindNextFile(hSearch, &FileData))
{
if(GetLastError() == ERROR_NO_MORE_FILES)
{
if(Completed == Count)
{
printf("Exiting....\n");
break;
}
lstrcpy(DirPath, Paths[Completed]);
lstrcat(DirPath,"*\0.\0*\0\0\0");
Completed++;
hSearch = FindFirstFile(DirPath, &FileData);
FindNextFileW(hSearch, &FileData);
RetValue = FindNextFileW(hSearch, &FileData);
continue;
}
else
{
printf("Could not find next file.\n");
break;
}
}
}
FindClose(hSearch);
}

Here you can come to know about the single byte and mutli byte(wide) character APIs of windows. By default, windows will take Wide character APIs. It means if u wirte FindFirstFile, it is defined as FindFirstFileW. Here 'W' means wide wide character API.

Also, many of APIs are also available in ASCII ie., Single byte character API. But u have to write explicitly like FindFirstFileA. Here 'A' means ascii or single byte charcter API. Not all APIs are available in ASCII form(single byte).

When we started to implement our own program, we thought that it will take more than a week time. But we have done it within few working hours. This iplementation was given us a great confidence. Because we have started our project without knowing anything about WinCE OS also without any training. Our trainer was/is GOOGLE and MSDN!

Actually, our goal was to achieve this in WinCE 6.0. But Win32 and WinCE are having almost same API set(libraries), we first done this in WinXp and ported the same to WinCE.

Some changes are required in this program to run in WinCE.
1. Remove two FindNextFile statements after FindFirstFile statment
2. Change the path. In WinCE paths will be like /windows/*.*. There is no C, D like drives.

For your reference i will give u this program for WinCE in my next blog. And also i will be explaining this program in my next blog.

Saturday, July 18, 2009

Single Byte Characters and Multi Byte Characters

When we were trying to implement Recursive File reading program in Windows, we were not knowing the concept of Multibyte characters or Wide character. With the help of google search, we were putting 'L' infront of strings. Like
char *ptr= L"Pramod";

We didnt see what the 'L' will do, at the first time. win32 API were executing in downloaded codes. But when we started to do our own implementations, we were using ANSI APIs also in our code. All ANSI C APis were failing!

We have printed the string which is attached with 'L', using for loop. NULL was printing alternatively!

Then we came to know the job of 'L' and TEXT("pramod"); These will put the NULL between alternative characters in the string and make it 'Multibyte characters'.

If i do like, char *ptr="Pramod", in memory it will be 'p0r0a0m0o0d0a00'. Zero will be the alternative character.

Most of ANSI C APIs requires single byte characters. Hence we have written 2 functions for converting Multibyte to Single byte and, Singlebyte to Multibyte.

int ConvertToSingleBytes(char *destpath, char *path)
{
int k,temp1,i;
k=0;
temp1 = lstrlen(path);
i=0;
while(temp1)
{
destpath[i] = path[k];
i++;
k+=2;
temp1--;
}
destpath[i] = '\0';
return 1;
}

Function for Converting SingleByte to MultiByte

int ConvertBackToWide(char*temp_path, char *path)
{
int i, j, h;
h = strlen(path);
i=0; j=0;
while(i < h)
{
temp_path[j]=path[i];
temp_path[j+1] = '\0';
i++; j+=2;
}
temp_path[j] = '\0';
temp_path[j+1] = '\0';
return 0;
}

Also, MultiByte character are called as Wide Characters. And, some ANSI C APIs also has come under wide characters.