Sunday, November 6, 2011

The ReadSector( ) Function of Interaction With Hardware in C programming

With the preliminaries over let us now concentrate on the real stuff in this program, i.e. the ReadSector( ) function. This function begins by making a call to the CreateFile( ) API function as shown below:

h = CreateFile ( src, GENERIC_READ,
FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0 ) ;

The CreateFile( ) API function is very versatile. Anytime we are to communicate with a device we have to firstly call this API function. The CreateFile( ) function opens the specified device as a file. Windows treats all devices just like files on disk. Reading from this file means reading from the device.

The CreateFile( ) API function takes several parameters. The first parameter is the string specifying the device to be opened. The second parameter is a set of flags that are used to specify the desired access to the file (representing the device) about to be opened. By specifying the GENERIC_READ flag we have indicated that we just wish to read from the file (device). The third parameter specifies the sharing access for the file (device). Since floppy drive is a shared resource across all the running applications we have specified the FILE_SHARE_READ flag. In general while interacting with any hardware the sharing flag for the file (device) must always be set to this value since every piece of hardware is shared amongst all the running applications. The fourth parameter indicates security access for the file (device). Since we are not concerned with security here we have specified the value as 0. The fifth parameter specifies what action to take if  the file already exists. When using CreateFile( ) for device access we must always specify this parameter as OPEN_EXISTING. Since the floppy disk file was already opened by the OS a long time back during the booting. The remaining two parameters are not used when using CreateFile( ) API function for device access. Hence we have passed a 0 value for them. If the call to CreateFile( ) succeeds then we obtain a handle to the file (device).

The device file mechanism allows us to read from the file (device) by setting the file pointer using the SetFilePointer( ) API function and then reading the file using the ReadFile( ) API function. Since every sector is 512 bytes long, to read from the nth sector we need to set the file pointer to the 512 * n bytes from the start of the file. The first parameter to SetFilePointer( ) is the handle of the device file that we obtained by calling the CreateFile( ) function. The second parameter is the byte offset from where the reading is to begin. This second parameter is relative to the third parameter. We have specified the third parameter as FILE_BEGIN which means the byte offset is relative to the start of the file.

To actually read from the device file we have made a call to the ReadFile( ) API function. The ReadFile( ) function is very easy to use. The first parameter is the handle of the file (device), the second parameter is the address of a buffer where the read contents should be dumped. The third parameter is the count of bytes that have to be read. We have specified the value as 512 * num so as to read num sectors. The fourth parameter to ReadFile( ) is the address of an unsigned int variable which is set up with the count of bytes that the function was successfully able to read. Lastly, once our work with the device is over we should close the file (device) using the CloseHandle( ) API function.

Though ReadSector( ) doesn’t need it, there does exist a counterpart of the ReadFile( ) function. Its name is WriteFile( ). This API function can be used to write to the file (device). The parameters of WriteFile( ) are same as that of ReadFile( ). 

Note  that when WriteFile( ) is to be used we need to specify the GENERIC_WRITE flag in the call to CreateFile( ) API function. Given below is the code of WriteSector( ) function that works exactly opposite to the ReadSector( ) function.

void WriteSector ( char *src, int ss, int num, void* buff )
{
HANDLE h ;
unsigned int br ;
h = CreateFile ( src, GENERIC_WRITE,
FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0 ) ;
SetFilePointer ( h, ( ss * 512 ), NULL, FILE_BEGIN ) ;
WriteFile ( h, buff, 512 * num, &br, NULL ) )
CloseHandle ( h ) ;
}


No comments:

Post a Comment