0% found this document useful (0 votes)
8 views

Practical of Windows File

The document outlines experiments in programming in a Windows environment, including printing the current directory, file listing and directory traversal, and file processing with error handling. It provides code examples for each experiment.

Uploaded by

Vlog Tech
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
8 views

Practical of Windows File

The document outlines experiments in programming in a Windows environment, including printing the current directory, file listing and directory traversal, and file processing with error handling. It provides code examples for each experiment.

Uploaded by

Vlog Tech
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 72

PRACTICAL FILE

OF

Programming in Windows
Environment
(Paper code: OSD-330P)

Submitted to: Submitted by:


Mr. Neeraj Singh Arindam Nandy
Assistant Professor Roll no:10015603121
IT Department Section : T7

Roll no:10015603121
INDEX

S.no Name of the Experiment Date Sign


1 Printing the Current Directory

2 File Listing and Directory Traversal

3 File Processing with Error and Exception


Recovery

4 Sorting a File with Memory Mapping

5 Create an Index File

6 Create a DLL with Explicit linking

7 Parallel Searching using multiple


processes

8 Multithreaded Pattern Searching

9 Write a socket based client

10 Socket-Based Server with In-Process


Servers

11 Write code for A Service Wrapper using


existing services

Roll no:10015603121
EXPERIMENT 1
Aim:Printing the Current Directory

Theory:Printing the directory in Windows serves purposes like quick


reference, documentation, debugging, scripting, and workflow
management. It provides visibility and context, aiding tasks and
workflows.

Code:

#ifdef _WIN32

#include <direct.h>

#define GetCurrentDir _getcwd

#else

#include <unistd.h>

#define GetCurrentDir getcwd

#endif

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

Roll no:10015603121
char* get_current_dir() {

char buff[FILENAME_MAX];

GetCurrentDir(buff, FILENAME_MAX);

char* current_working_dir = _strdup(buff);

return current_working_dir;

int main() {

char* cwd = get_current_dir();

printf("%s\n", cwd);

free(cwd);

return 0;

Output:

Roll no:10015603121
EXPERIMENT 2
Aim:File Listing and Directory Traversal

Theory:File listing and directory traversal are crucial tasks in Windows


system programming. They allow users and applications to access
information about files and directories, including attributes like names,
sizes, and modification times. These operations enable file
management tasks such as copying, moving, and deleting files, as well
as batch processing and search operations. Additionally, they facilitate
monitoring file system changes and analyzing file system structures,
making them essential for both system administrators and application
developers.

Code:
#include <windows.h>

#include <stdio.h>

#include <tchar.h>

#define FILENAME_PATH 256

DWORD FileType(LPWIN32_FIND_DATA pData) {

if (pData->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {

return FILE_ATTRIBUTE_DIRECTORY;

} else {

Roll no:10015603121
return FILE_ATTRIBUTE_NORMAL;

void ProcessFile(LPWIN32_FIND_DATA pData, LPCTSTR


path,LPCTSTR DirPath) {

if (FileType(pData) == FILE_ATTRIBUTE_DIRECTORY) {

printf("%s\\%s\n",DirPath,pData->cFileName);

} else {

printf("File: %s\n", pData->cFileName);

void TraverseDirectory(LPCTSTR path) {

WIN32_FIND_DATA findData;

HANDLE hFind = INVALID_HANDLE_VALUE;

TCHAR searchPath[MAX_PATH];

LPCTSTR Dirpath=path;

_tcscpy(searchPath, path);

Roll no:10015603121
_tcscat(searchPath, _T("\\*"));

hFind = FindFirstFile(searchPath, &findData);

if (hFind == INVALID_HANDLE_VALUE) {

printf("Error opening directory: %s\n", path);

return;

do {

if (_tcscmp(findData.cFileName, _T(".")) != 0 &&


_tcscmp(findData.cFileName, _T("..")) != 0) {

ProcessFile(&findData, path,Dirpath);

if (FileType(&findData) == FILE_ATTRIBUTE_DIRECTORY) {

TCHAR subDirPath[MAX_PATH];

_tcscpy(subDirPath, path);

_tcscat(subDirPath, _T("\\"));

_tcscat(subDirPath, findData.cFileName);

TraverseDirectory(subDirPath);

Roll no:10015603121
}

} while (FindNextFile(hFind, &findData) != 0);

FindClose(hFind);

int main(int argc, char *argv[]) {

char str[FILENAME_MAX];

printf("Enter the Directory: ");

fgets(str, FILENAME_MAX, stdin);

str[strcspn(str, "\n")] = '\0';

LPCTSTR directoryPath = _T(str);

TraverseDirectory(directoryPath);

return 0;

Roll no:10015603121
Output:

Roll no:10015603121
EXPERIMENT 3
Aim:File Processing with Error and Exception Recovery

Theory:In Windows system programming, adept error and exception


handling in file processing are paramount. Utilize GetLastError() and
FormatMessage() for error management, adapting responses to severity.
Employ structured exception handling (__try, __except) for comprehensive error
handling. Leverage Transactional NTFS (TxF) for atomic file operations,
rolling back transactions upon errors. Ensure robust error handling during
backup and restore processes using Windows APIs. Implement
asynchronous file I/O cautiously to avert data loss.

Code:

#include <WinSock2.h>

#include <windows.h>

#include <tchar.h>

#include <stdio.h>

#include <stdlib.h>

#include <ctype.h>

#define MAX_FILENAME_LEN 250

Roll no:10015603121
#if defined(UTILITY_4_0_EXPORTS)

#define LIBSPEC __declspec (dllexport)

#elif defined(__cplusplus)

#define LIBSPEC extern "C" __declspec (dllimport)

#else

#define LIBSPEC __declspec (dllimport)

#endif

LIBSPEC VOID ReportError(LPCTSTR, DWORD, BOOL);

LIBSPEC VOID ReportException(LPCTSTR, DWORD);

LIBSPEC BOOL WindowsVersionOK(DWORD, DWORD);

int _tmain(int argc, LPTSTR argv[])

HANDLE hIn = INVALID_HANDLE_VALUE, hOut = INVALID_HANDLE_VALUE;

DWORD nXfer, iFile, j;

TCHAR outFileName[256] = _T(""), * pBuffer = NULL;

OVERLAPPED ov = { 0, 0, 0, 0, NULL };

LARGE_INTEGER fSize;

Roll no:10015603121
if (!WindowsVersionOK(3, 1))

ReportError(_T("This program requires Windows NT 3.1 or greater to


support LockFileEx"),

1, FALSE);

if (argc <= 1)

ReportError(_T("Usage: Win3 files"), 1, FALSE);

for (iFile = 1; iFile < (unsigned int)argc; iFile++) __try {

if (_tcslen(argv[iFile]) > 250)

ReportException(_T("The file name is too long."), 1);

swprintf_s(outFileName, _T("UC_%s"), argv[iFile]);

__try {

hIn = CreateFile(argv[iFile], GENERIC_READ,

0, NULL, OPEN_EXISTING, 0, NULL);

if (hIn == INVALID_HANDLE_VALUE) ReportException(argv[iFile],


1);

if (!GetFileSizeEx(hIn, &fSize) || fSize.HighPart > 0)

ReportException(_T("This file is too large for this program."),


1);

Roll no:10015603121
hOut = CreateFile(outFileName, GENERIC_READ |
GENERIC_WRITE,

0, NULL, CREATE_NEW, 0, NULL);

if (hOut == INVALID_HANDLE_VALUE)
ReportException(outFileName, 1);;

TCHAR* pBuffer = (TCHAR*)malloc(fSize.LowPart);

if (pBuffer == NULL) ReportException(_T("Memory allocation


error"), 1);;

if (!ReadFile(hIn, pBuffer, fSize.LowPart, &nXfer, NULL) || (nXfer !=


fSize.LowPart))

ReportException(_T("ReadFile error"), 1);

for (j = 0; j < fSize.LowPart; j++)

if (isalpha(pBuffer[j])) pBuffer[j] = toupper(pBuffer[j]);

if (!WriteFile(hOut, pBuffer, fSize.LowPart, &nXfer, NULL) || (nXfer


!= fSize.LowPart))

ReportException(_T("WriteFile error"), 1);

__finally {

Roll no:10015603121
if (pBuffer != NULL) free(pBuffer); pBuffer = NULL;

if (hIn != INVALID_HANDLE_VALUE) {

CloseHandle(hIn);

hIn = INVALID_HANDLE_VALUE;

if (hOut != INVALID_HANDLE_VALUE) {

CloseHandle(hOut);

hOut = INVALID_HANDLE_VALUE;

wcscpy_s(outFileName, _T(""));

__except (EXCEPTION_EXECUTE_HANDLER) {

_tprintf(_T("Error occured processing file %s\n"), argv[iFile]);

DeleteFile(outFileName);

_tprintf(_T("All files converted, except as noted above\n"));

return 0;

Roll no:10015603121
Output:

Roll no:10015603121
EXPERIMENT 4
Aim:Sorting a File with Memory Mapping

Theory:In Windows system programming, adept error and exception


handling in file processing are paramount. Utilize GetLastError() and
FormatMessage() for error management, adapting responses to severity.
Employ structured exception handling (__try, __except) for comprehensive error
handling. Leverage Transactional NTFS (TxF) for atomic file operations,
rolling back transactions upon errors. Ensure robust error handling during
backup and restore processes using Windows APIs. Implement
asynchronous file I/O cautiously to avert data loss.

Code:

#include <iostream>

#include <fstream>

#include <vector>

#include <algorithm>

#include <Windows.h>

using namespace std;

const string FILENAME = "data.txt";

Roll no:10015603121
bool compare(int a, int b) {

return a < b;

int main() {

HANDLE hFile = CreateFileA(FILENAME.c_str(), GENERIC_READ | GENERIC_WRITE,


0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

if (hFile == INVALID_HANDLE_VALUE) {

cerr << "Error opening file.\n";

return 1;

DWORD fileSize = GetFileSize(hFile, NULL);

if (fileSize == INVALID_FILE_SIZE) {

cerr << "Error getting file size.\n";

CloseHandle(hFile);

return 1;

Roll no:10015603121
HANDLE hMapping = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, 0,
NULL);

if (hMapping == NULL) {

cerr << "Error creating file mapping.\n";

CloseHandle(hFile);

return 1;

LPVOID lpData = MapViewOfFile(hMapping, FILE_MAP_READ | FILE_MAP_WRITE,


0, 0, 0);

if (lpData == NULL) {

cerr << "Error mapping file into memory.\n";

CloseHandle(hMapping);

CloseHandle(hFile);

return 1;

int* data = static_cast<int*>(lpData);

int numElements = fileSize / sizeof(int);

sort(data, data + numElements, compare);

Roll no:10015603121
UnmapViewOfFile(lpData);

CloseHandle(hMapping);

CloseHandle(hFile);

cout << "File sorted successfully.\n";

return 0;

Output:

Roll no:10015603121
EXPERIMENT 5
Aim:Create an Index File

Theory:In Windows system programming, indexing files serves to enhance


efficiency and performance by organizing metadata about file contents. This
facilitates quicker data retrieval, especially in large files, by avoiding the need
to scan entire files. Indexing optimizes file access patterns, supports
complex queries, and aids in effective file management, making it a valuable
technique for improving file-related operations in various applications.

Code:

#include <Windows.h>

#include <iostream>

#include <vector>

#include <string>

#include <algorithm>

using namespace std;

vector<string> GetFileNames(const string& directory) {

vector<string> filenames;

string searchPath = directory + "\\*.*";

Roll no:10015603121
WIN32_FIND_DATA findData;

HANDLE hFind = FindFirstFile(searchPath.c_str(), &findData);

if (hFind != INVALID_HANDLE_VALUE) {

do {

if (!(findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {

filenames.push_back(findData.cFileName);

} while (FindNextFile(hFind, &findData) != 0);

FindClose(hFind);

sort(filenames.begin(), filenames.end());

return filenames;

int main() {

string directory = "C:\\Users\\HP\\Desktop\\New Files\\New Files\\OS";

vector<string> filenames = GetFileNames(directory);

vector<HANDLE> fileMappings;

Roll no:10015603121
vector<LPVOID> mappedFilePointers;

for (const auto& filename : filenames) {

string filePath = directory + "\\" + filename;

HANDLE hFile = CreateFile(filePath.c_str(), GENERIC_READ, FILE_SHARE_READ,


NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

if (hFile != INVALID_HANDLE_VALUE) {

HANDLE hMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0,


NULL);

if (hMapping != NULL) {

LPVOID pData = MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0);

if (pData != NULL) {

fileMappings.push_back(hMapping);

mappedFilePointers.push_back(pData);

else {

CloseHandle(hMapping);

else {

CloseHandle(hFile);

Roll no:10015603121
}

if (!fileMappings.empty() && fileMappings.size() == mappedFilePointers.size()) {

cout << "Memory-mapped file index:\n";

for (size_t i = 0; i < filenames.size(); ++i) {

cout << "Filename: " << filenames[i] << ", Memory-mapped pointer: " <<
mappedFilePointers[i] << endl;

else {

cout << "Error: Failed to map files to memory.\n";

for (size_t i = 0; i < fileMappings.size(); ++i) {

UnmapViewOfFile(mappedFilePointers[i]);

CloseHandle(fileMappings[i]);

return 0;

Roll no:10015603121
}

Output:

Roll no:10015603121
EXPERIMENT 6
Aim:Create a DLL with Explicit linking

Theory:In Windows system programming, indexing files serves to enhance


efficiency and performance by organizing metadata about file contents. This
facilitates quicker data retrieval, especially in large files, by avoiding the need
to scan entire files. Indexing optimizes file access patterns, supports
complex queries, and aids in effective file management, making it a valuable
technique for improving file-related operations in various applications.

Code:

MyMath.cpp = MyMath.dll Declaration

#include <windows.h>

#ifdef __cplusplus

extern "C" {

#endif

__declspec (dllexport) int __cdecl Addition(int x, int y)

int z;

z = x + y;

Roll no:10015603121
return z;

__declspec (dllexport) int __cdecl Subrtaction(int x, int y)

int z;

z = x - y;

return z;

__declspec (dllexport) int __cdecl Multiplication(int x, int y)

int z;

z = x * y;

return z;

__declspec (dllexport) int __cdecl Division(int x, int y)

int z;

z = x / y;

return z;

Roll no:10015603121
#ifdef __cplusplus

#endif

MyMathProgram.cpp

#include <Windows.h>

#include <stdio.h>

typedef int(__cdecl* FunAdd)(int a, int b);

typedef int(__cdecl* FunSub)(int a, int b);

typedef int(__cdecl* FunMul)(int a, int b);

typedef int(__cdecl* FunDiv)(int a, int b);

int main()

HMODULE hModule;

hModule =
LoadLibrary(TEXT("C:\\Users\\HP\\source\\repos\\MyMath\\x64\\Debug\\MyMath
.dll"));

if (hModule == NULL)

Roll no:10015603121
{

printf("Failed to Load the DLL File: %lu\n", GetLastError());

return 1;

printf("Dll File Loaded Successfully\n");

FunSub MulFunc = (FunSub)GetProcAddress(hModule, "Multiplication");

FunSub DivFunc = (FunSub)GetProcAddress(hModule, "Division");

FunSub AddFunc = (FunSub)GetProcAddress(hModule, "Addition");

FunSub SubFunc = (FunSub)GetProcAddress(hModule, "Subtraction");

if (NULL == MulFunc)

printf("Function Address is not valid, error no: %lu\n", GetLastError());

return 1;

printf("Function Address is Valid\n");

printf("Multiplication = %d\n", MulFunc(50, 10));

printf("Division = %d\n", DivFunc(50, 10));

printf("Addition = %d\n", AddFunc(50, 10));

printf("Subtraction = %d\n", SubFunc(50, 10));

Roll no:10015603121
FreeLibrary(hModule);

return 0;

Output:

Roll no:10015603121
EXPERIMENT 7
Aim:Parallel Searching using multiple processes

Theory:Pattern searching, akin to Unix's grep command, is indispensable in


Windows system programming for tasks like text processing, log analysis,
and data extraction. It enables efficient sifting through large text volumes,
aiding in error identification, anomaly detection, and specific event tracing in
system logs. Moreover, it facilitates data extraction from structured
documents, content filtering, and advanced pattern matching using regular
expressions. Integrating pattern searching capabilities into Windows
programming enriches functionality and productivity, making it invaluable for
various tasks requiring text analysis and manipulation.

Code:

#include <Windows.h>

#include <stdio.h>

#include <tchar.h>

#if defined(UTILITY_4_0_EXPORTS)

#define LIBSPEC __declspec (dllexport)

#elif defined(__cplusplus)

#define LIBSPEC extern "C" __declspec (dllimport)

#else

Roll no:10015603121
#define LIBSPEC __declspec (dllimport)

#endif

LIBSPEC VOID ReportError(LPCTSTR, DWORD, BOOL);

int _tmain(int argc, LPTSTR argv[]) {

HANDLE hTempFile;

SECURITY_ATTRIBUTES stdOutSA = { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE };

TCHAR commandLine[MAX_PATH + 100];

STARTUPINFO startUpSearch, startUp;

PROCESS_INFORMATION processInfo;

DWORD exitCode, dwCreationFlags = 0;

int iProc;

HANDLE* hProc;

typedef struct { TCHAR tempFile[MAX_PATH]; } PROCFILE;

PROCFILE* procFile;

#ifdef UNICODE

dwCreationFlags = CREATE_UNICODE_ENVIRONMENT;

#endif

if (argc < 3)

ReportError(_T("Usage: grepMP pattern files."), 1, FALSE);

Roll no:10015603121
GetStartupInfo(&startUpSearch);

GetStartupInfo(&startUp);

procFile = (PROCFILE*)malloc((argc - 2) * sizeof(PROCFILE));

hProc = (HANDLE*)malloc((argc - 2) * sizeof(HANDLE));

for (iProc = 0; iProc < argc - 2; iProc++) {

swprintf_s(commandLine, _T("grep \"%s\" \"%s\""), argv[1], argv[iProc + 2]);

if (GetTempFileName(_T("."), _T("gtm"), 0, procFile[iProc].tempFile) == 0)

ReportError(_T("Temp file failure."), 2, TRUE);

hTempFile = CreateFile(procFile[iProc].tempFile, GENERIC_WRITE,


FILE_SHARE_READ | FILE_SHARE_WRITE, &stdOutSA, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL, NULL);

if (hTempFile == INVALID_HANDLE_VALUE)

ReportError(_T("Failure opening temp file."), 3, TRUE);

Roll no:10015603121
startUpSearch.dwFlags = STARTF_USESTDHANDLES;

startUpSearch.hStdOutput = hTempFile;

startUpSearch.hStdError = hTempFile;

startUpSearch.hStdInput = GetStdHandle(STD_INPUT_HANDLE);

if (!CreateProcess(NULL, commandLine, NULL, NULL, TRUE, dwCreationFlags,


NULL, NULL, &startUpSearch, &processInfo))

ReportError(_T("ProcCreate failed."), 4, TRUE);

CloseHandle(hTempFile);

CloseHandle(processInfo.hThread);

hProc[iProc] = processInfo.hProcess;

for (iProc = 0; iProc < argc - 2; iProc += MAXIMUM_WAIT_OBJECTS)

WaitForMultipleObjects(min(MAXIMUM_WAIT_OBJECTS, argc - 2 - iProc),


&hProc[iProc], TRUE, INFINITE);

for (iProc = 0; iProc < argc - 2; iProc++) {

Roll no:10015603121
if (GetExitCodeProcess(hProc[iProc], &exitCode) && exitCode == 0) {

if (argc > 3) _tprintf(_T("%s:\n"), argv[iProc + 2]);

swprintf_s(commandLine, _T("cat \"%s\""), procFile[iProc].tempFile);

if (!CreateProcess(NULL, commandLine, NULL, NULL, TRUE, dwCreationFlags,


NULL, NULL, &startUp, &processInfo))

ReportError(_T("Failure executing cat."), 0, TRUE);

else {

WaitForSingleObject(processInfo.hProcess, INFINITE);

CloseHandle(processInfo.hProcess);

CloseHandle(processInfo.hThread);

CloseHandle(hProc[iProc]);

if (!DeleteFile(procFile[iProc].tempFile))

ReportError(_T("Cannot delete temp file."), 6, TRUE);

free(procFile);

free(hProc);

return 0;

Roll no:10015603121
}

Output:

Roll no:10015603121
EXPERIMENT 8
Aim:Multithreaded Pattern Searching

Theory:Multithreaded search patterns in Windows system programming


boost performance by utilizing multiple CPU cores concurrently. They
enhance resource utilization, ensuring optimal system performance.
Scalability is improved as workloads can be distributed across threads
efficiently. Multithreading prevents long-running search operations from
blocking the main thread, enhancing application responsiveness.
Asynchronous search operations are enabled, allowing other tasks to
proceed while awaiting search results. Overall, multithreaded search patterns
optimize performance, scalability, and responsiveness in Windows
applications.

Code:

#include <stdio.h>

#include <windows.h>

#include <process.h>

#include <tchar.h>

#define MAX_COMMAND_LINE 1024

#define EOS _T('\0')

Roll no:10015603121
#define ASTRSK 1

#define QM 2

#define BEGCLASS 3

#define ENDCLASS 4

#define ANCHOR 5

typedef struct {

int argc;

TCHAR targv[4][MAX_COMMAND_LINE];

} GREP_THREAD_ARG;

typedef GREP_THREAD_ARG* PGR_ARGS;

static BOOL ignoreCase = FALSE;

static void prepSearchString(TCHAR* p, TCHAR* buf);

static BOOL patternMatch(TCHAR* pattern, TCHAR* string);

unsigned int __stdcall ThGrep(void* pArgs);

TCHAR commandLine[MAX_COMMAND_LINE]; // Declare commandLine variable

BOOL ok;

Roll no:10015603121
int _tmain(int argc, LPTSTR argv[]) {

PGR_ARGS gArg;

HANDLE* tHandle;

DWORD threadIndex, exitCode;

int iThrd, threadCount;

STARTUPINFO startUp;

PROCESS_INFORMATION processInfo;

GetStartupInfo(&startUp);

if (argc < 3) {

_tprintf(_T("No file names.\n"));

return 1;

tHandle = (HANDLE*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (argc -


2) * sizeof(HANDLE));

gArg = (PGR_ARGS)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (argc - 2)


* sizeof(GREP_THREAD_ARG));

Roll no:10015603121
for (iThrd = 0; iThrd < argc - 2; iThrd++) {

_tcscpy_s(gArg[iThrd].targv[1], MAX_COMMAND_LINE, argv[1]);

_tcscpy_s(gArg[iThrd].targv[2], MAX_COMMAND_LINE, argv[iThrd + 2]);

GetTempFileName(_T("."), _T("Gre"), 0, gArg[iThrd].targv[3]);

gArg[iThrd].argc = 4;

tHandle[iThrd] = (HANDLE)_beginthreadex(NULL, 0, ThGrep,


(void*)&gArg[iThrd], 0, NULL);

if (tHandle[iThrd] == 0) _tprintf(_T("ThreadCreate failed.\n"));

threadCount = argc - 2;

while (threadCount > 0) {

threadIndex = WaitForMultipleObjects(threadCount, tHandle, FALSE, INFINITE);

iThrd = (int)threadIndex - (int)WAIT_OBJECT_0;

if (iThrd < 0 || iThrd >= threadCount) _tprintf(_T("Thread wait error.\n"));

GetExitCodeThread(tHandle[iThrd], &exitCode);

CloseHandle(tHandle[iThrd]);

if (exitCode == 0) {

Roll no:10015603121
if (argc > 3) {

_tprintf(_T("%s\n"), gArg[iThrd].targv[2]);

fflush(stdout);

_stprintf_s(commandLine, MAX_COMMAND_LINE, _T("cat \"%s\""),


gArg[iThrd].targv[3]);

ok = CreateProcess(NULL, commandLine, NULL, NULL, TRUE, 0, NULL, NULL,


&startUp, &processInfo);

if (!ok) _tprintf(_T("Failure executing cat.\n"));

WaitForSingleObject(processInfo.hProcess, INFINITE);

CloseHandle(processInfo.hProcess);

CloseHandle(processInfo.hThread);

if (!DeleteFile(gArg[iThrd].targv[3])) _tprintf(_T("Cannot delete temp file.\n"));

tHandle[iThrd] = tHandle[threadCount - 1];

_tcscpy_s(gArg[iThrd].targv[3], MAX_COMMAND_LINE, gArg[threadCount -


1].targv[3]);

Roll no:10015603121
_tcscpy_s(gArg[iThrd].targv[2], MAX_COMMAND_LINE, gArg[threadCount -
1].targv[2]);

threadCount--;

HeapFree(GetProcessHeap(), 0, tHandle);

HeapFree(GetProcessHeap(), 0, gArg);

return 0;

unsigned int __stdcall ThGrep(void* pArgs) {

PGR_ARGS pArguments = (PGR_ARGS)pArgs;

TCHAR pattern[256];

TCHAR string[2048];

int i, patternSeen = FALSE, showName = FALSE, argc, result = 1;

FILE* fp, * fpout;

// Declare ok variable

argc = pArguments->argc;

if (_wfopen_s(&fpout, pArguments->targv[argc - 1], _T("wb")) != 0) {

Roll no:10015603121
printf("Failure to open output file.\n");

return 1;

for (i = 1; i < argc - 1; ++i) {

if (pArguments->targv[i][0] == _T('-')) {

switch (pArguments->targv[i][1]) {

case _T('y'):

ignoreCase = TRUE;

break;

else {

if (!patternSeen++)

prepSearchString(pArguments->targv[i], pattern);

else if (_wfopen_s(&fp, pArguments->targv[i], _T("rb")) == 0) {

if (!showName && i < argc - 2) ++showName;

while (_fgetts(string, sizeof(string), fp) != NULL && !feof(fp)) {

if (ignoreCase) _tcslwr_s(string);

if (patternMatch(pattern, string)) {

Roll no:10015603121
result = 0;

if (showName) {

fputws(pArguments->targv[i], fpout);

fputws(string, fpout);

else

fputws(string, fpout);

fclose(fp);

fclose(fpout);

return result;

static FILE* openFile(TCHAR* file, TCHAR* mode) {

Roll no:10015603121
FILE* fp = NULL;

if (_wfopen_s(&fp, file, mode) != 0) _tperror(file);

return fp;

static void prepSearchString(TCHAR* p, TCHAR* buf) {

register int c;

register int i = 0;

if (*p == _T('^')) {

buf[i++] = ANCHOR;

++p;

for (;;) {

switch (c = *p++) {

case EOS: goto Exit;

case _T('*'): if (i >= 0 && buf[i - 1] != ASTRSK) c = ASTRSK; break;

case _T('?'): c = QM; break;

case _T('['): c = BEGCLASS; break;

Roll no:10015603121
case _T(']'): c = ENDCLASS; break;

case _T('\\'):

switch (c = *p++) {

case EOS: goto Exit;

case _T('a'): c = _T('\a'); break;

case _T('b'): c = _T('\b'); break;

case _T('f'): c = _T('\f'); break;

case _T('t'): c = _T('\t'); break;

case _T('v'): c = _T('\v'); break;

case _T('\\'): c = _T('\\'); break;

break;

buf[i++] = (ignoreCase ? tolower(c) : c);

Exit:

buf[i] = EOS;

Roll no:10015603121
static BOOL patternMatch(TCHAR* pattern, TCHAR* string) {

register TCHAR pc, sc;

TCHAR* pat;

BOOL anchored;

if (anchored = (*pattern == ANCHOR)) ++pattern;

Top:

pat = pattern;

Again:

pc = *pat;

sc = *string;

if (sc == _T('\n') || sc == EOS) {

if (pc == EOS) goto Success;

else if (pc == ASTRSK) {

++pat;

goto Again;

Roll no:10015603121
}

else return (FALSE);

else {

if (pc == sc || pc == QM) {

++pat;

++string;

goto Again;

else if (pc == EOS) goto Success;

else if (pc == ASTRSK) {

if (patternMatch(pat + 1, string)) goto Success;

else {

++string;

goto Again;

else if (pc == BEGCLASS) {

BOOL clmatch = FALSE;

while (*++pat != ENDCLASS) {

Roll no:10015603121
if (!clmatch && *pat == sc) clmatch = TRUE;

if (clmatch) {

++pat;

++string;

goto Again;

if (anchored) return (FALSE);

++string;

goto Top;

Success:

return (TRUE);

Roll no:10015603121
Output:

Roll no:10015603121
EXPERIMENT 9
Aim:Write a socket based client

Theory:Socket-based clients are essential in Windows system programming


for several reasons: They enable communication between client and server
applications over networks. By utilizing sockets, clients can connect to
remote servers, exchange data, and perform various network-related tasks.
Socket-based clients facilitate the implementation of distributed systems,
enabling applications to interact across different machines seamlessly. They
support various protocols such as TCP/IP or UDP, making them versatile for
different communication needs. Socket programming in Windows allows for
the development of robust and scalable networked applications. Overall,
socket-based clients are fundamental for building networked applications in
Windows environments, offering flexibility, reliability, and interoperability.

Code:

#pragma comment(lib, "ws2_32.lib")

#include <winsock2.h>

#include <stdio.h>

#include <tchar.h>

#include <Windows.h>

#include <ws2tcpip.h>

Roll no:10015603121
#define MAX_RQRS_LEN 0x1000

#define SERVER_PORT 50000

typedef struct {

LONG32 rqLen;

BYTE record[MAX_RQRS_LEN];

} REQUEST;

typedef struct {

LONG32 rsLen;

BYTE record[MAX_RQRS_LEN];

} RESPONSE;

SOCKET clientSock;

struct sockaddr_in clientSAddr;

BOOL quit = FALSE;

BOOL SendRequestMessage(REQUEST*, SOCKET);

BOOL ReceiveResponseMessage(RESPONSE*, SOCKET);

Roll no:10015603121
int main(int argc, char* argv[]) {

WSADATA WSStartData;

REQUEST request;

RESPONSE response;

WSAStartup(MAKEWORD(2, 0), &WSStartData);

clientSock = socket(AF_INET, SOCK_STREAM, 0);

if (clientSock == INVALID_SOCKET) {

printf("Failed to create socket\n");

WSACleanup();

return 1;

memset(&clientSAddr, 0, sizeof(clientSAddr));

clientSAddr.sin_family = AF_INET;

clientSAddr.sin_port = htons(SERVER_PORT);

if (argc >= 2) {

inet_pton(AF_INET, argv[1], &clientSAddr.sin_addr);

Roll no:10015603121
}

else {

inet_pton(AF_INET, "127.0.0.1", &clientSAddr.sin_addr);

if (connect(clientSock, (struct sockaddr*)&clientSAddr, sizeof(clientSAddr)) ==


SOCKET_ERROR) {

printf("Failed to connect to server\n");

closesocket(clientSock);

WSACleanup();

return 1;

while (!quit) {

printf("Enter Command: ");

fgets(request.record, MAX_RQRS_LEN - 1, stdin);

request.record[strlen(request.record) - 1] = '\0';

if (strcmp(request.record, "$Quit") == 0) {

quit = TRUE;

Roll no:10015603121
continue;

if (!SendRequestMessage(&request, clientSock)) {

printf("Failed to send request\n");

break;

if (!quit && !ReceiveResponseMessage(&response, clientSock)) {

printf("Failed to receive response\n");

break;

shutdown(clientSock, SD_BOTH);

closesocket(clientSock);

WSACleanup();

printf("\n****Leaving client\n");

return 0;

Roll no:10015603121
BOOL SendRequestMessage(REQUEST* pRequest, SOCKET sd) {

int result = send(sd, (char*)pRequest, sizeof(REQUEST), 0);

return result != SOCKET_ERROR;

BOOL ReceiveResponseMessage(RESPONSE* pResponse, SOCKET sd) {

int result = recv(sd, (char*)pResponse, sizeof(RESPONSE), 0);

return result != SOCKET_ERROR;

Output:

Roll no:10015603121
EXPERIMENT 10
Aim:Socket-Based Server with In-Process Servers

Theory:Socket-based servers are integral for in-process servers in Windows


system programming because they enable inter-process communication
within the same machine. Using sockets, servers can listen for incoming
connections and handle client requests efficiently. They facilitate the
development of scalable and modular systems by allowing multiple client
connections concurrently. Socket-based servers support various
communication protocols like TCP/IP or UDP, ensuring flexibility and
interoperability. In-process servers benefit from the lightweight and efficient
nature of socket communication, enhancing overall system performance.
Socket-based servers are essential for building robust and responsive
in-process server applications in Windows environments.

Code:

#pragma comment(lib, "ws2_32.lib")

#include <winsock2.h>

#include <stdio.h>

#include <tchar.h>

#include <Windows.h>

#include <ws2tcpip.h>

Roll no:10015603121
struct sockaddr_in srvSAddr;

WSADATA WSStartData;

#define MAX_CLIENTS 10

#define SERVER_PORT 50000

#define MAX_RQRS_LEN 0x1000

typedef struct {

SOCKET sock;

BOOL threadActive;

} THREAD_INFO;

typedef struct {

LONG32 rqLen;

BYTE record[MAX_RQRS_LEN];

} REQUEST;

typedef struct {

LONG32 rsLen;

BYTE record[MAX_RQRS_LEN];

} RESPONSE;

Roll no:10015603121
SOCKET clientSock;

struct sockaddr_in clientSAddr;

BOOL quit = FALSE;

static BOOL ReceiveRequestMessage(REQUEST* pRequest, SOCKET sd);

static BOOL SendResponseMessage(RESPONSE* pResponse, SOCKET sd);

static DWORD WINAPI ServerThread(LPVOID lpParam);

int main() {

DWORD tStatus;

SOCKET SrvSock = INVALID_SOCKET;

THREAD_INFO threads[MAX_CLIENTS];

if (WSAStartup(MAKEWORD(2, 0), &WSStartData) != 0) {

printf("WSAStartup failed\n");

return 1;

SrvSock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

if (SrvSock == INVALID_SOCKET) {

printf("Failed to create server socket\n");

Roll no:10015603121
WSACleanup();

return 1;

srvSAddr.sin_family = AF_INET;

srvSAddr.sin_addr.s_addr = htonl(INADDR_ANY);

srvSAddr.sin_port = htons(SERVER_PORT);

if (bind(SrvSock, (struct sockaddr*)&srvSAddr, sizeof(srvSAddr)) ==


SOCKET_ERROR) {

printf("Bind failed\n");

closesocket(SrvSock);

WSACleanup();

return 1;

if (listen(SrvSock, SOMAXCONN) == SOCKET_ERROR) {

printf("Listen failed\n");

closesocket(SrvSock);

WSACleanup();

return 1;

Roll no:10015603121
for (int i = 0; i < MAX_CLIENTS; ++i) {

threads[i].sock = INVALID_SOCKET;

threads[i].threadActive = FALSE;

while (1) {

int freeThread = -1;

for (int i = 0; i < MAX_CLIENTS; ++i) {

if (!threads[i].threadActive) {

freeThread = i;

break;

if (freeThread != -1) {

threads[freeThread].sock = accept(SrvSock, NULL, NULL);

if (threads[freeThread].sock == INVALID_SOCKET) {

printf("Accept failed\n");

continue;

Roll no:10015603121
threads[freeThread].threadActive = TRUE;

DWORD dwThreadId;

HANDLE hThread = CreateThread(NULL, 0, ServerThread,


&threads[freeThread], 0, &dwThreadId);

if (hThread == NULL) {

printf("Failed to create server thread\n");

closesocket(threads[freeThread].sock);

threads[freeThread].sock = INVALID_SOCKET;

threads[freeThread].threadActive = FALSE;

else {

CloseHandle(hThread);

else {

printf("Too many clients\n");

Sleep(1000);

Roll no:10015603121
closesocket(SrvSock);

WSACleanup();

return 0;

static DWORD WINAPI ServerThread(LPVOID lpParam) {

THREAD_INFO* pInfo = (THREAD_INFO*)lpParam;

SOCKET clientSock = pInfo->sock;

REQUEST request;

RESPONSE response;

while (1) {

if (!ReceiveRequestMessage(&request, clientSock)) {

printf("Failed to receive request\n");

break;

if (strcmp(request.record, "$Quit") == 0) {

break;

Roll no:10015603121
if (!SendResponseMessage(&response, clientSock)) {

printf("Failed to send response\n");

break;

closesocket(clientSock);

pInfo->threadActive = FALSE;

return 0;

static BOOL ReceiveRequestMessage(REQUEST* pRequest, SOCKET sd) {

int result = recv(sd, (char*)pRequest, sizeof(REQUEST), 0);

return result != SOCKET_ERROR;

static BOOL SendResponseMessage(RESPONSE* pResponse, SOCKET sd) {

int result = send(sd, (char*)pResponse, sizeof(RESPONSE), 0);

return result != SOCKET_ERROR;

Roll no:10015603121
Output:

Roll no:10015603121
EXPERIMENT 11
Aim:Write code for A Service Wrapper using existing services

Theory:Windows services, integral to Windows System Programming, are


background processes that run independently of user sessions. They offer
various functionalities, including server processes, device drivers, and
system utilities. Managed through the Service Control Manager, they can
start automatically at system boot or be triggered by specific events.
Services adhere to a defined interface, implementing functions like service
initialization, control handling, and status reporting. They provide essential
system functionalities, such as networking, security, and system
maintenance, contributing to the stability and functionality of the Windows
operating system. Understanding their lifecycle, communication protocols,
and security implications is crucial for effective Windows System
Programming.

Code:

#include <windows.h>

#include <stdio.h>

#include <tchar.h>

#include <time.h>

#define UPDATE_TIME 1000

Roll no:10015603121
BOOL shutDown = FALSE, pauseFlag = FALSE;

SERVICE_STATUS hServStatus;

SERVICE_STATUS_HANDLE hSStat;

TCHAR serviceName[] = _T("SimpleService");

TCHAR logFileName[] = _T(".\\LogFiles\\SimpleServiceLog.txt");

BOOL consoleApp = FALSE, isService;

VOID WINAPI ServiceMain(DWORD argc, LPTSTR argv[]);

VOID WINAPI ServerCtrlHandler(DWORD);

VOID UpdateStatus(DWORD, DWORD);

VOID LogEvent(LPCTSTR, WORD);

int main(int argc, char* argv[]) {

// Initialize log file

FILE* logFp = _tfopen(logFileName, _T("a+"));

if (logFp != NULL) LogEvent(_T("Initialized Logging"), EVENTLOG_SUCCESS);

// Initialize service

SERVICE_TABLE_ENTRY DispatchTable[] = {

Roll no:10015603121
{ serviceName, ServiceMain },

{ NULL, NULL }

};

StartServiceCtrlDispatcher(DispatchTable);

return 0;

VOID WINAPI ServiceMain(DWORD argc, LPTSTR argv[]) {

// Set up service status

hSStat = RegisterServiceCtrlHandler(serviceName, ServerCtrlHandler);

if (hSStat == 0) return;

hServStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;

hServStatus.dwCurrentState = SERVICE_START_PENDING;

hServStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP |
SERVICE_ACCEPT_SHUTDOWN | SERVICE_ACCEPT_PAUSE_CONTINUE;

hServStatus.dwWin32ExitCode = NO_ERROR;

hServStatus.dwServiceSpecificExitCode = 0;

hServStatus.dwCheckPoint = 0;

Roll no:10015603121
hServStatus.dwWaitHint = 2 * UPDATE_TIME;

SetServiceStatus(hSStat, &hServStatus);

// Perform service-specific tasks

UpdateStatus(SERVICE_RUNNING, -1);

while (!shutDown) {

Sleep(UPDATE_TIME);

UpdateStatus(-1, -1);

UpdateStatus(SERVICE_STOPPED, 0);

VOID WINAPI ServerCtrlHandler(DWORD dwControl) {

switch (dwControl) {

case SERVICE_CONTROL_SHUTDOWN:

case SERVICE_CONTROL_STOP:

shutDown = TRUE;

UpdateStatus(SERVICE_STOP_PENDING, -1);

break;

Roll no:10015603121
case SERVICE_CONTROL_PAUSE:

pauseFlag = TRUE;

// Handle pause functionality

break;

case SERVICE_CONTROL_CONTINUE:

pauseFlag = FALSE;

// Handle continue functionality

break;

case SERVICE_CONTROL_INTERROGATE:

// Respond to interrogation

break;

default:

// Handle user-defined control codes

break;

UpdateStatus(-1, -1);

VOID UpdateStatus(DWORD NewStatus, DWORD Check) {

if (Check < 0) hServStatus.dwCheckPoint++;

Roll no:10015603121
else hServStatus.dwCheckPoint = Check;

if (NewStatus >= 0) hServStatus.dwCurrentState = NewStatus;

if (isService) SetServiceStatus(hSStat, &hServStatus);

VOID LogEvent(LPCTSTR UserMessage, WORD type) {

TCHAR cTimeString[30];

time_t currentTime = time(NULL);

_tcsncpy_s(cTimeString, _countof(cTimeString), _tctime(&currentTime),


_TRUNCATE);

cTimeString[_tcslen(cTimeString) - 2] = _T('\0');

FILE* logFp = _tfopen(logFileName, _T("a+"));

if (logFp != NULL) {

_ftprintf(logFp, _T("%s. "), cTimeString);

if (type == EVENTLOG_SUCCESS || type == EVENTLOG_INFORMATION_TYPE)

_ftprintf(logFp, _T("%s"), _T("Information. "));

else if (type == EVENTLOG_ERROR_TYPE)

_ftprintf(logFp, _T("%s"), _T("Error. "));

Roll no:10015603121
else if (type == EVENTLOG_WARNING_TYPE)

_ftprintf(logFp, _T("%s"), _T("Warning. "));

else

_ftprintf(logFp, _T("%s"), _T("Unknown. "));

_ftprintf(logFp, _T("%s\n"), UserMessage);

fflush(logFp);

fclose(logFp);

Output:

Roll no:10015603121
Roll no:10015603121

You might also like