Windows NT Systems Programming: Spring 1999

[ Home | Syllabus | Course Notes | Assignments | Search]


File I/O & Version 0


Handles and Objects

Object is owned by the Operating System

Handle is a "pointer" to the object

Kernel Objects:

Some are sharable , some are private.

Objects in green will be covered in this course (and possibly some of the others).


FILE APIs

Why Use Direct File API( vs C++ libraries)?

 


Creating/Opening Files

HANDLE CreateFile( // See p. 24

LPCTSTR name, // file name
DWORD accessMode, // Read/Write or both
DWORD shareMode, // none/read/write
LPSECURITY_ATTRIBUTES security, // child inheritable
DWORD create, // CREATE_NEW, CREATE_ALWAYS,OPEN_EXISTING, //OPEN_ALWAYS,TRUNCATE_EXISTING
DWORD attributes, // normal,readonly,hidden,system,archive,temporary
//writeThrough,noBuffers,randomAccess,sequential
HANDLE templateFile) // for inherited attributes

For now ignore shareMode, security, attributes, and templateFile


Basic Data Types

 

Typedef

Description

WINAPI Use in place of FAR PASCAL in API declarations. If you are writing a DLL with exported API entry points, you can use this for your own APIs.
CALLBACK Use in place of FAR PASCAL in application callback routines such as window procedures and dialog procedures.

ReadFile

BOOL ReadFile(

HANDLE file, // handle of file to read
LPVOID buffer, // address of buffer that receives data
DWORD requestedBytes, // number of bytes to read
LPDWORD actualBytes, // address of number of bytes read
LPOVERLAPPED overlapped ) // address of structure for data


WriteFile

Same as ReadFile except second parameter is LPCVOID

(Long Pointer to a Constant unspecified type)


CloseHandle

BOOL CloseHandle(

HANDLE object) // works for lots of kernel objects

Returns "false" on failure, see

DWORD GetLastError(VOID)

for details


Message System - Version 0

(click here to get source file)

//***********************************************
// Simple Message Filer (Version0)
// This is as C-like as I want to get 
// Main purpose of this program is to introduce the semester's
// teaching project and to show some simple windowsNT file manipulation
//		FILE IO:
// terminal input and output uses c++'s cin and cout operators
// However for file I/O we use win32 file routines
// even though c++ or c's file I/O may be more preferable because of
// its portability. We are here to learn windowsNT not c++
//		USER INTERFACE: 
//  . . . .

//	Messages are arbitrarily numbered from 1 to the last message
//	Messages consist of a topic( up to 50 characters) and text (up to 300)
//	Editing of existing messages is not supported in this version.
//		DATA STRUCTURE: 
//	Messages are stored in a fixed length array - one message per array location
//  with a fixed space for the topic and text
//	AUTHOR: chris wild
//	DATE: July 27. 1997
//*************************************************

#include <iostream.h>
#include <windows.h>	// for file types 

const int  SIZE_TOPIC = 50; // maximum size for topic field
const int SIZE_TEXT = 300; // maximum size for message text field
const int MAX_NUM_MSG = 10;	// maximum number of messages
// status flags for messages
const int DELETED = 0;	// denotes a deleted messages
const int EMPTY = 1;	// message slot is empty
const int MSG_OK = 2;	// messages is OK

const int NO_SLOT_FOUND = -1;

struct message {
	char topic[SIZE_TOPIC+1];
	char text[SIZE_TEXT+1];
};

struct messages {
	message msg;
	int status; /// of this messages (used to find empty slots and mark deleted Messages)
} msgList[MAX_NUM_MSG]; 

//************** prototypes of functions
void listMessages();
void addMessage();
void deleteMessage(int msgNum);
void showMessage(int msgNum);
void inputMessages(const  char* filename);
void outputMessages(const char* filename);

void main()
{
// . . .
}
		

//*****************************************************************************
// Worker Functions:
//*****************************************************************************
// . . .

//********
// inputMessages: inputs messages from file
void inputMessages( const char* fileName) 
{
	HANDLE messageFile;	// handle for message file 
	DWORD nBytes; 
	int i;
	
	for(i = 0; i < MAX_NUM_MSG; i++) {
		msgList[i].status = EMPTY;	// mark slot empty
	}	
	messageFile  = CreateFile(fileName,	// LPCTSTR -- pointer to character string 
		GENERIC_READ ,	// DWORD -- accessMODE (constant defined in windows.h) 
		0,	// DWORD -- share mode (we want exclusive access)
		0,	// LPSECURITY_ATTRIBUTES -- what can be inherited
		OPEN_EXISTING ,	// DWORD create -- file must already exist
		0,	// DWORD -- attributes
		0);	// HANDLE -- templatefile
	if(messageFile == INVALID_HANDLE_VALUE) { 
		cerr << "Error: " << GetLastError()  <<
			" when opening file: " << fileName << endl;
		ExitProcess(1); 
	}	
	for(i = 0; i < MAX_NUM_MSG; i++) {
		if(!  ReadFile(messageFile,	// HANDLE to open file
			msgList[i].msg.topic,	// pointer to input buffer
			SIZE_TOPIC+1,			// size of input buffer
			&nBytes ,				// bytes actually read
			0))						// overlapped structure (asynchronous I/O)
			break;
		if(nBytes == 0) break;		// End of File 
		if(!ReadFile(messageFile,msgList[i].msg.text,SIZE_TEXT+1,&nBytes,0))
			break;
		if(nBytes == 0) break; // Should NEVER happen!
		msgList[i].status = MSG_OK;
	}
	CloseHandle(messageFile); 
}

//********
// outputMessages: writes messages to file
void outputMessages(const char* fileName)
{
	HANDLE messageFile;	// handle for message file
	DWORD nBytes;

	messageFile = CreateFile(fileName,GENERIC_WRITE,0,0,CREATE_ALWAYS,0,0);
	if(messageFile == INVALID_HANDLE_VALUE) {
		cerr << "Error: " << GetLastError() <<
			" when creating file: " << fileName << endl;
		ExitProcess(1);
	}
	for(int i = 0; i < MAX_NUM_MSG; i++) {
		if(msgList[i].status != MSG_OK)
			continue;
		if(!WriteFile(messageFile,msgList[i].msg.topic,SIZE_TOPIC+1,&nBytes,0)) 
			break;
		if(nBytes == 0) break; // something went wrong - should handle error
		if(!WriteFile(messageFile,msgList[i].msg.text,SIZE_TEXT+1,&nBytes,0))
			break;
		if(nBytes == 0) break; // something went wrong - should handle error
	}
	CloseHandle(messageFile);
}

Notes on Program

Temporary Files


Random Access

DWORD SetFilePointer( // Page 52 - allows 64 bit file addresses (ackwardly)

HANDLE hFile, // handle of file
LONG lDistanceToMove, // number of bytes to move file pointer
PLONG lpDistanceToMoveHigh, // address of high-order word of distance to move
DWORD dwMoveMethod // how to move
// FILE_BEGIN, FILE_CURRENT, FILE_END
);


HomeWork: Assignment 1


Copyright chris wild 1999.
For problems or questions regarding this web contact [Dr. Wild].
Last updated: January 13, 1999.