|< C Run-Time 1 | Main | C Run-Time 3 >| Site Index | Download |
MODULE A1
IMPLEMENTATION SPECIFIC
MICROSOFT C Run-Time 2
|
|
My Training Period: hours
Note: More program examples, compiled using Visual C++ .Net (Visual studio .Net 2003). It is low-level programming and the .Net used is Unmanaged (/clr is not set: Project menu → your_project_name Properties… sub menu → Configuration Properties folder → General subfolder → Used Managed Extension setting set to No). All programs are in debug mode, run on Windows 2000 and Xp Pro.
Abilities
▪ Able to recognize the standard and implementation specific C. ▪ Able to grasp the fundamental of the Windows file system, file and directory. ▪ Able to find and collect the needed information in order to use functions to accomplish your tasks. ▪ Able to understand and use functions that available in the libraries in your own programs.
- In this Module you will be introduced to the absolute implementation specific of the C/C++, the Microsoft C/C++. However it is still non-GUI type of programs :o). - This brings you to the specific use of the compilers that compile the Windows applications and the programs developed are specific to be run on the Windows platform although in the discussion and program examples of this Module and later on, the standard and non standard (Microsoft extension) libraries will be used together. - Make sure you have already fluent in functions because we will learn how to use them. Remember all the thing about a function such as parameters, return values etc. The final purpose of this Module and that follows actually to show you how to find and collect all the required information from tons of the documentations to suit your needs in developing programs. - Keep in mind that, normally, in libraries we have the following things which defined in and accessed through the header files:
▪ Macro definitions. ▪ Function prototypes. ▪ Structure definitions (struct). ▪ Enumeration definitions (enum). ▪ Data type definitions. ▪ The typedef usage.
- For the data type and structure definitions, you will find that use of struct, typedef and enum is normal here and also for Win32 programming (will be discussed in another Module). - To better understand you must be fluent on those things. If you encounter any problem, you might have to go back to basic :o) by referring to Tutorial #1 tenouk.com. - Other pre requirement topics include array and pointer.
System Calls
- The following functions are Windows 98/Me and Windows NT/2000/XP operating-system calls. |
System Call Functions
|
Function |
Use |
|
_findclose() |
Release resources from previous find operations. |
|
_findfirst(), _findfirst64(), _findfirsti64(), _wfindfirst(), _wfindfirst64(), _wfindfirsti64() |
Find file with specified attributes. |
|
_findnext(), _findnext64(), _findnexti64(), _wfindnext(), _wfindnext64(), _wfindnexti64() |
Find next file with specified attributes. |
|
Table 9: System call functions |
|
- For example, the _findfirst() function provides information about the first instance of a filename that matches the file specified in the filespec argument.
- Any wildcard combination supported by the host operating system such as the *, can be used in filespec. File information is returned in a _finddata_t (or _finddata64_t) structure, defined in io.h.
- The _finddata_t structure used in these functions includes the following elements:
|
Element/field |
Description |
|
unsigned attrib |
File attribute. |
|
time_t time_create |
Time of file creation (–1L for FAT file systems). |
|
time_t time_access |
Time of last file access (–1L for FAT file systems). |
|
time_t time_write |
Time of last write to file. |
|
_fsize_t size |
Length of file in bytes. |
|
char name[_MAX_FNAME] |
Null-terminated name of matched file/directory, without the path. _MAX_FNAME is defined in stdlib.h as 256 bytes. |
|
Table 10: _finddata_t structure information |
|
- The time_create and time_access fields are always –1L for file systems that do not support the creation and last access times of a file, such as the FAT system.
- You cannot specify target attributes (such as _A_RDONLY) by which to limit the find operation. This attribute is returned in the attrib field of the _finddata_t structure and can have the following values (defined in io.h).
|
attrib |
Description |
|
_A_ARCH |
Archive. Set whenever the file is changed, and cleared by the BACKUP command. Value: 0x20. |
|
_A_HIDDEN |
Hidden file. Not normally seen with the DIR command, unless the /AH option is used. Returns information about normal files as well as files with this attribute. Value: 0x02. |
|
_A_NORMAL |
Normal. File can be read or written to without restriction. Value: 0x00. |
|
_A_RDONLY |
Read-only. File cannot be opened for writing, and a file with the same name cannot be created. Value: 0x01. |
|
_A_SUBDIR |
Subdirectory. Value: 0x10. |
|
_A_SYSTEM |
System file. Not normally seen with the DIR command, unless the /A or /A:S option is used. Value: 0x04. |
|
Table 11: attrib return value |
|
- _findnext() finds the next name, if any, that matches the filespec argument specified in a prior call to _findfirst(). The fileinfo argument should point to a structure initialized by a previous call to _findfirst().
- If a match is found, the fileinfo structure contents are altered as described above. _findclose() closes the specified search handle and releases all associated resources for both _findfirst() and _findnext(). The handle returned by either _findfirst() or _findnext() must first be passed to _findclose(), before modification operations, such as deleting, can be performed on the directories that form the paths passed to them.
- The _find() functions allow nested calls. For example, if the file found by a call to _findfirst() or _findnext() is a subdirectory, a new search can be initiated with another call to _findfirst() or _findnext().
- _wfindfirst() and _wfindnext() are wide-character versions of _findfirst() and _findnext().
- The structure argument of the wide-character versions has the _wfinddata_t data type, which is defined in io.h and in wcahr.h. The fields of this data type are the same as those of the _finddata_t data type, except that in _wfinddata_t the name field is of type wchar_t rather than type char.
- Otherwise _wfindfirst() and _wfindnext() behave identically to _findfirst() and _findnext(). _findfirsti64(), _findnexti64(), _wfindfirsti64(), and _wfindnexti64() functions also behave identically except they use and return 64-bit file lengths.
- The following is an example of the needed information in order to use the _findclose() function.
|
Information |
Description |
|
The function |
_findclose(). |
|
The use |
Closes the specified search handle and releases associated resources. |
|
The prototype |
int _findclose(intptr_t handle); |
|
Example |
struct _finddata_t c_file; long hFile; hFile = _findfirst("*.*", &c_file); _findclose(hFile); |
|
The parameters |
handle - Search handle returned by a previous call to _findfirst(). |
|
The return value |
If successful, _findclose() returns 0. Otherwise, it returns –1 and sets errno to ENOENT, indicating that no more matching files could be found. |
|
The header file |
<io.h>. |
|
Table 12: _findclose()function information |
|
- The following Table lists the needed information in order to use the _findfirst() family functions.
|
Information |
Description |
|
The function |
_findfirst(), _findfirst64(), _findfirsti64(), _wfindfirst(), _wfindfirst64(), _wfindfirsti64(). |
|
The use |
Provide information about the first instance of a filename that matches the file specified in the filespec argument. |
|
The prototype |
intptr_t _findfirst(
const char *filespec,
struct _finddata_t *fileinfo);
intptr_t _findfirst64( const char *filespec, struct __finddata64_t *fileinfo);
intptr_t _findfirsti64( const char *filespec, struct _finddatai64_t *fileinfo);
intptr_t _wfindfirst( const wchar_t *filespec, struct _wfinddata_t *fileinfo);
intptr_t _wfindfirst64( const wchar_t *filespec, struct __wfinddata64_t *fileinfo);
intptr_t _wfindfirsti64( const wchar_t *filespec, struct _wfinddatai64_t *fileinfo); |
|
Example |
struct _finddata_t c_file; long hFile;
hFile = _findfirst("*.*", &c_file); |
|
The parameters |
filespec - Target file specification (may include wildcards). fileinfo - File information buffer. |
|
The return value |
If successful, _findfirst() returns a unique search handle identifying the file or group of files matching the filespec specification, which can be used in a subsequent call to _findnext() or to _findclose(). Otherwise, _findfirst() will return –1 and set errno to one of the following values: ENOENT - File specification that could not be matched. EINVAL - Invalid filename specification. |
|
The header file |
<io.h> or <wchar.h> for _wfindfirst(), _wfindfirst64(), _wfindfirsti64(). |
|
Table 13: _findfirst() family function information |
|
- _findfirst64(), which uses the __finddata64_t() structure, and _wfindfirst64(), which use the __wfinddata64_t structure, allows file-creation dates to be expressed up through 23:59:59, December 31, 3000, UTC.
- Whereas the other functions only represent dates through 19:14:07 January 18, 2038, UTC. Midnight, January 1, 1970, is the lower bound of the date range for all these functions.
- You must call _findclose() after you are finished using either the _findfirst() or _findnext() function. This will free up resources used by these functions in your application.
- The following Table lists the needed information in order to use the _findnext() family functions.
|
Information |
Description |
|
The function |
_findnext(), _findnext64(), _findnexti64(), _wfindnext(), _wfindnext64(), _wfindnexti64(). |
|
The use |
Find the next name, if any, that matches the filespec argument in a previous call to _findfirst(), and then alter the fileinfo structure contents accordingly. |
|
The prototype |
int _findnext(
intptr_t handle, struct _finddata_t *fileinfo); int _findnext64( intptr_t handle, struct __finddata64_t *fileinfo); int _findnexti64( intptr_t handle, struct _finddatai64_t *fileinfo);
int _wfindnext(
intptr_t handle,
struct _wfinddata_t *fileinfo);
int _wfindnext64(
intptr_t handle,
struct __wfinddata64_t *fileinfo
);
int _wfindnexti64(
intptr_t handle,
struct _wfinddatai64_t *fileinfo); |
|
Example |
struct _finddata_t c_file; long hFile; _findnext(hFile, &c_file); |
|
The parameters |
handle - Search handle returned by a previous call to _findfirst(). fileinfo - File information buffer. |
|
The return value |
If successful, return 0. Otherwise, return –1 and sets errno to ENOENT, indicating that no more matching files could be found. |
|
The header file |
<io.h> or <wchar.h> for _wfindnext(), _wfindnext64(), _wfindnexti64(). |
|
Table 14: _findnext() family function information |
|
- _findnext64(), which uses the __finddata64_t structure, and _wfindnext64(), which use the __wfinddata64_t structure, allow file-creation dates to be expressed up through 23:59:59, December 31, 3000, UTC.
- Whereas the other functions only represent dates through 19:14:07 January 18, 2038, UTC. Midnight, January 1, 1970, is the lower bound of the date range for all these functions.
- The following is a program example that uses some of the functions.
/*The use of the 32-bit _find functions to print a list
of all files (and their attributes) in the current directory.*/
#include <stdio.h>
#include <io.h>
#include <time.h>
#include <direct.h>
#include <conio.h>
#include <ctype.h>
int main()
{
char path[50] = "C:\\WINNT\\System32\\config";
struct _finddata_t c_file;
long hFile;
printf("Change to %s\n", path);
if(_chdir(path))
printf("Unable to locate the directory: %s\n", path);
else
/* Find first in the current directory */
hFile = _findfirst("*.*", &c_file);
/* List the files... */
printf("Listing of files in the directory %s\n\n", path);
printf("\nRDO HID SYS ARC FILE DATE %25c SIZE\n", ' ');
printf("--- --- --- --- ---- ---- %25c ----\n", ' ');
printf((c_file.attrib & _A_RDONLY) ? " Y " : " N ");
printf((c_file.attrib & _A_SYSTEM) ? " Y " : " N ");
printf((c_file.attrib & _A_HIDDEN) ? " Y " : " N ");
printf((c_file.attrib & _A_ARCH) ? " Y " : " N ");
printf(" %-12s %.24s %9ld\n", c_file.name, ctime(&(c_file.time_write)), c_file.size);
/*Find the rest of the files*/
while(_findnext(hFile, &c_file) == 0)
{
printf((c_file.attrib & _A_RDONLY) ? " Y " : " N ");
printf((c_file.attrib & _A_SYSTEM) ? " Y " : " N ");
printf((c_file.attrib & _A_HIDDEN) ? " Y " : " N ");
printf((c_file.attrib & _A_ARCH) ? " Y " : " N ");
printf(" %-12s %.24s %9ld\n", c_file.name, ctime(&(c_file.time_write)), c_file.size);
}
_findclose(hFile);
return 0;
}
The output:
Change to C:\WINNT\System32\config
Listing of files in the directory C:\WINNT\System32\config
RDO HID SYS ARC FILE DATE SIZE
--- --- --- --- ---- ---- ----
N N N Y . Sat Jun 05 14:23:34 2004 0
N N N Y .. Sat Jun 05 14:23:34 2004 0
N N N Y AppEvent.Evt Thu May 12 01:18:44 2005 65536
N N N Y default Tue May 17 20:07:50 2005 147456
N N Y Y default.LOG Tue May 17 20:07:50 2005 1024
N N N Y default.sav Sat Jun 05 07:06:31 2004 81920
N N N Y netlogon.ftl Wed Jun 16 02:08:51 2004 112
N N N Y SAM Tue May 17 20:08:13 2005 32768
N N Y Y SAM.LOG Tue May 17 20:08:13 2005 1024
N N N Y SecEvent.Evt Sat Jun 05 14:26:09 2004 65536
N N N Y SECURITY Tue May 17 20:17:21 2005 49152
N N Y Y SECURITY.LOG Tue May 17 20:17:21 2005 1024
N N N Y software Tue May 17 20:42:37 2005 26300416
N N Y Y software.LOG Tue May 17 20:42:37 2005 1024
N N N Y software.sav Sat Jun 05 07:06:31 2004 540672
N N N Y SysEvent.Evt Tue May 17 01:27:36 2005 524288
N N N Y system Tue May 17 20:08:52 2005 3072000
N N N Y SYSTEM.ALT Tue May 17 20:08:53 2005 3076096
N N Y Y system.LOG Sat Jun 05 07:06:31 2004 1024
N N N Y system.sav Sat Jun 05 07:06:31 2004 372736
N N Y Y TempKey.LOG Sat Jun 05 07:06:28 2004 0
N N N Y userdiff Sat Jun 05 07:06:31 2004 139264
N N Y Y userdiff.LOG Sat Jun 05 07:06:31 2004 1024
Press any key to continue
- The functions in this category used to create, delete, and manipulate files and to set and check file-access permissions.
- The C run-time libraries have a 512 limit for the number of files that can be open at any one time.
- Attempting to open more than the maximum number of file handles or file streams causes program failure. But you can use _setmaxstdio() function to change this number.
File-Handling Functions (Files)
- The following functions operate on files designated by a file handle. Handle will be explained in C & Win32 programming.
|
Function |
Use |
|
_chsize() |
Change the file size. |
|
_filelength() |
Get file length. |
|
_fstat(), _fstat64(), _fstati64() |
Get file-status information on handle. |
|
_isatty() |
Check for character device. |
|
_locking() |
Lock areas of file. |
|
_setmode() |
Set file-translation mode. |
|
Table 15: File handling functions for files |
|
- The following Table is an example of the needed information in order to use the _chsize() function.
|
Information |
Description |
|
The function |
_chsize(). |
|
The use |
Changes the file size. |
|
The prototype |
int _chsize(int handle, long size); |
|
Example |
int fhdl; _chsize(fhdl, 123456); |
|
The parameters |
handle - Handle referring to open file. size - New length of file in bytes. |
|
The return value |
_chsize() returns the value 0 if the file size is successfully changed. A return value of –1 indicates an error: errno is set to EACCES if the specified file is locked against access, to EBADF if the specified file is read-only or the handle is invalid, or to ENOSPC if no space is left on the device. |
|
The header file |
<io.h> |
|
Table 16: _chsize() function information |
|
#include <io.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
int main()
{
int fhdl, result;
char fname[20] = "C:\\data.txt";
/*Open a file*/
if((fhdl = _open(fname, _O_RDWR | _O_CREAT, _S_IREAD | _S_IWRITE)) != -1)
{
printf("%s file length before running _chsize(): %ld\n", fname, _filelength(fhdl));
/*Change the file size*/
printf("Executing _chsize(fhdl, 123456)...\n");
if((result = _chsize(fhdl, 123456)) == 0)
printf("%s file size successfully changed!\n", fname);
else
printf("Problem in changing the %s size\n", fname);
/*New size*/
printf("%s file length after changing the size: %ld\n", fname, _filelength(fhdl));
/*close the file handle*/
_close(fhdl);
}
return 0;
}
The output:
C:\data.txt file length before running _chsize(): 0
Executing _chsize(fhdl, 123456)...
C:\data.txt file size successfully changed!
C:\data.txt file length after changing the size: 123456
Press any key to continue
File-Handling Functions (Path or Filename)
- The following Table is a list of functions that operate on files specified by a path or filename.
|
Function |
Use |
|
_access(), _waccess() |
Check file-permission setting. |
|
_chmod(), _wchmod() |
Change file-permission setting. |
|
_fullpath(), _wfullpath() |
Expand a relative path to its absolute path name. |
|
_get_osfhandle() |
Return operating-system file handle associated with existing stream FILE pointer. |
|
_makepath(), _wmakepath() |
Merge path components into single, full path. |
|
_mktemp(), _wmktemp() |
Create unique filename. |
|
_open_osfhandle() |
Associate C run-time file handle with existing operating-system file handle. |
|
remove(), _wremove() |
Delete file. |
|
rename(), _wrename() |
Rename file. |
|
_splitpath(), _wsplitpath() |
Parse path into components. |
|
_stat(), _stat64(), _stati64(), _wstat(), _wstat64(), _wstati64() |
Get file-status information on named file. |
|
_umask() |
Set default permission mask for new files created by program. |
|
_unlink(), _wunlink() |
Delete file. |
|
Table 17: File handling functions for path and filename |
|
- The following Table is an example of the needed information for _chmod() function.
|
Information |
Description |
|
The function |
_chmod(). |
|
The use |
Change the file-permission settings. |
|
The prototype |
int _chmod(const char *filename, int pmode); |
|
Example |
_chmod("test.txt", _S_IREAD); |
|
The parameters |
filename - Name of existing file. pmode - Permission setting for file. |
|
The return value |
These functions return 0 if the permission setting is successfully changed. A return value of –1 indicates that the specified file could not be found, in which case errno is set to ENOENT. |
|
The header file |
<io.h> |
|
Table 18: _chmod() function information |
|
- The following Table lists the needed information for _fullpath(), _wfullpath() functions.
|
Information |
Description |
|
The function |
_fullpath(), _wfullpath(). |
|
The use |
Create an absolute or full path name for the specified relative path name. |
|
The prototype |
char *_fullpath(char *absPath, const char *relPath, size_t maxLength);
/*For wide character*/ wchar_t *_wfullpath(wchar_t *absPath, const wchar_t *relPath, size_t maxLength); |
|
Example |
char full[_MAX_PATH]; char relPath[20] = "test.txt"; _fullpath(full, relPath, _MAX_PATH); |
|
The parameters |
absPath Pointer to a buffer containing the absolute or full path name.
relPath Relative path name.
maxLength Maximum length of the absolute path name buffer (absPath). This length is in bytes for _fullpath() but in wide characters (wchar_t) for _wfullpath(). |
|
The return value |
Each of these functions returns a pointer to a buffer containing the absolute path name (absPath). If there is an error (for example, if the value passed in relPath includes a drive letter that is not valid or cannot be found, or if the length of the created absolute path name (absPath) is greater than maxLength) the function returns NULL. |