// Primer laboratornoi raboti ¹ 2 - klient-servernoe konsolnoe prilozenie Windows #include <windows.h> #include <conio.h> #include <iostream> #define PAGE_SIZE 10 // ispolzuetsia pri vivode #define ADD_USER '1' #define EDIT_USER '2' #define DELETE_USER '3' #define CHANGE_PWD '4' #define VIEW_USERS '5' #define ADD_RATING '6' #define PURGE '7' #define FINISH '8' #define BUFSIZE 4096 // pipe buffer size using namespace std; struct User { int exist; // 0 - if deleted, 1 - otherwise char login[11]; char passwd[21]; int rating; User(){ exist=0; login[0]=0; passwd[0]=0; rating=0; } }; void print_menu(void); void Add_User(); void Print_Users(); void Edit_User(); void Find_User(User*); void Delete_User(); void Change_Pwd(); void Add_Rating(); void Purge(); void createServer(); void openPipe(); void initStrings(); void myExit(); wchar_t *pipename, *servername, *comandline; PROCESS_INFORMATION pi; HANDLE hPipe=NULL; int main(int argc, TCHAR* argv[], TCHAR* envp[]) { int i='1', retCode; DWORD bytesWritten; pipename= L"\\\\.\\pipe\\oslab3"; servername=L"lab3_server.exe"; // Create the pipe openPipe(); // Create the server createServer(); // Wait until server connects to pipe printf("Wait server ..."); retCode=ConnectNamedPipe(hPipe,NULL); if(!retCode && GetLastError()!=ERROR_PIPE_CONNECTED){ CloseHandle(hPipe); printf("Server connection waiting failed"); exit(0); } printf(" OK\n"); // Main cycle while(i!='8'){ print_menu(); // Output menu fflush(stdin); // Clear standard input stream i=getc(stdin); // read the character from standard input // Set command code to the server retCode=WriteFile(hPipe,(void*)&i,sizeof(int),&bytesWritten,NULL); if(!retCode || bytesWritten!=sizeof(int)){ printf("Can't write command"); myExit(); } switch(i){ case ADD_USER:Add_User();break; case VIEW_USERS:Print_Users();break; case EDIT_USER:Edit_User();break; case DELETE_USER:Delete_User();break; case CHANGE_PWD:Change_Pwd();break; case ADD_RATING:Add_Rating();break; case PURGE:break; case FINISH:FlushFileBuffers(hPipe);DisconnectNamedPipe(hPipe);CloseHandle(hPipe);break; default:break; } } return 0; } void createServer(){ STARTUPINFO si; ZeroMemory(&si,sizeof(si)); si.cb=sizeof(si); // Set window properties //si.dwXSize = 100; //si.dwYSize = 50; // Start the child process. DWORD retCode=CreateProcess(TEXT("lab3_server.exe"),TEXT("lab3_server.exe"),NULL,NULL,FALSE,0,NULL,NULL,&si,&pi); DWORD err = GetLastError(); if(!retCode){ printf("CreateProcess failed"); // Disconnect server from pipe DisconnectNamedPipe(hPipe); // Close pipe CloseHandle(hPipe); exit(0); } } void openPipe(){ // Create pipe hPipe = CreateNamedPipe(pipename,PIPE_ACCESS_DUPLEX,PIPE_TYPE_MESSAGE|PIPE_READMODE_MESSAGE|PIPE_WAIT,PIPE_UNLIMITED_INSTANCES,BUFSIZE,BUFSIZE,NMPWAIT_USE_DEFAULT_WAIT,NULL); if (hPipe == INVALID_HANDLE_VALUE){// If pipe can't be created printf("CreatePipe failed"); exit(0); } } void myExit(){ if(hPipe){ int code=8;//stop server // send to server stop signal WriteFile(hPipe,(void*)&code,sizeof(int),NULL,NULL); // Wait until server read our message FlushFileBuffers(hPipe); // Disconnect server from pipe DisconnectNamedPipe(hPipe); // Close piep CloseHandle(hPipe); } exit(0); } void print_menu(void){ int i; for(i=0;i<3;i++) printf("\n"); printf("1 - Add User\n2 - Edit User\n3 - Delete User\n4 - Change Password\n5 - View Users\n6 - Add to User's Rating\n7 - Purge\n8 - Finish work\n"); } void Add_User(){ // Add user User tmpUser; int retCode; DWORD bytesWritten; tmpUser.exist=1; // The user is exists printf("Input login\n"); scanf("%s",tmpUser.login); // Input login printf("Input password\n"); scanf("%s",tmpUser.passwd); // Input password printf("Input user's initial rating\n"); scanf("%d",&tmpUser.rating); // Input rating // Send user structure ti the server retCode=WriteFile(hPipe,(void*)&tmpUser,sizeof(User),&bytesWritten,NULL); if(!retCode || bytesWritten!=sizeof(User)){ printf("Can't write new student to pipe"); myExit(); } } void Print_Users(){ // List all students int i, st=0, // number of students to print retCode; User tmpUser; DWORD bytesRead; // Read number of students retCode=ReadFile(hPipe,(void*)&st,sizeof(int),&bytesRead,NULL); if(!retCode || bytesRead!=sizeof(int)){ printf("Can't read number of strudents for output"); myExit(); } for(i=0;i<st;i++){ if(i>0 && i%PAGE_SIZE==0){ // Pause beetween pages printf("Press any key to continue\n"); fflush(stdin); getc(stdin); } retCode=ReadFile(hPipe,(void*)&tmpUser,sizeof(User),&bytesRead,NULL); if(!retCode || bytesRead!=sizeof(User)){ printf("Can't read strudent for output"); myExit(); } printf("User's number: %d\n",i); printf("Login: %s\n",tmpUser.login); printf("Password: %s\n",tmpUser.passwd); printf("Rating: %d\n\n",tmpUser.rating); } } void Edit_User(){ // Edit user data int retCode; DWORD bytesWritten; User tmpUser; printf("Search user for editing\n"); Find_User(&tmpUser); // Find user and get its information to tmpUser structure if(tmpUser.exist==-1) return; // If search fails, then exit // Print current information and input new information printf("Previous login: %s\n",tmpUser.login); // Output old login printf("Input new login\n"); scanf("%s",tmpUser.login); // Input new login printf("Previous password: %s\n",tmpUser.passwd); //same with password printf("Input new password\n"); scanf("%s",tmpUser.passwd); printf("Previous rating: %d\n",tmpUser.rating); // same with rating printf("Input user's new rating\n"); scanf("%d",&(tmpUser.rating)); tmpUser.exist=1; // Send new user data retCode=WriteFile(hPipe,(void*)&tmpUser,sizeof(User),&bytesWritten,NULL); if(!retCode || bytesWritten!=sizeof(User)){ printf("Can't write new student data"); myExit(); } } void Find_User(User *tmpUser){ // Function for student search // Funkcia otsilaet login na server i polushaet infu o naidennom studente // esli ot servea prishel kod neudachnogo poiska, to sprashivaetsia o novom poiske int i, retCode, fl1; // otvet polzolatelia na zapros o povtornom vvode DWORD bytesRead,bytesWritten; while(1) { printf("Please input login for the user\n"); fflush(stdin); tmpUser->exist=777; scanf("%s",tmpUser->login); // Input login for search // Send login to the server retCode=WriteFile(hPipe,(void*)tmpUser,sizeof(User),&bytesWritten,NULL); if(!retCode || bytesWritten!=sizeof(User)){ printf("Can't write login for search"); myExit(); } // Recieve answer from the server. If User.exist=-1, then ask new search retCode=ReadFile(hPipe,(void*)tmpUser,sizeof(User),&bytesRead,NULL); if(!retCode || bytesRead!=sizeof(User)){ printf("Can't read results of search"); myExit(); } if(tmpUser->exist!=-1){// search success read student info retCode=ReadFile(hPipe,(void*)tmpUser,sizeof(User),&bytesRead,NULL); if(!retCode || bytesRead!=sizeof(User)){ printf("Can't read results of search"); myExit(); } return; } // No results printf("Login incorrect. Do you want to try again (y/n)?\n"); fflush(stdin); fl1=getc(stdin); if((char)fl1=='n'){ // send code to finish search to the server tmpUser->exist=-1; retCode=WriteFile(hPipe,(void*)tmpUser,sizeof(User),&bytesWritten,NULL); if(!retCode || bytesWritten!=sizeof(User)){ printf("Can't write search decline"); myExit(); } return; } } return; } void Delete_User(){ // Delete user int retCode; User tmpUser; printf("Search user for deleting\n"); Find_User(&tmpUser); // Find user to delete if(tmpUser.exist==-1)// no user found return; if(tmpUser.exist==777) printf("Used was deleted successfully\n"); } void Change_Pwd(){ // Password changing int retCode; DWORD bytesWritten; User tmpUser; printf("Change password for which user?\n"); Find_User(&tmpUser); if(tmpUser.exist==-1) return; printf("Previous password: %s\n",tmpUser.passwd); printf("Input new password\n"); scanf("%s",tmpUser.passwd); tmpUser.exist=1; // Send new password to the server retCode=WriteFile(hPipe,(void*)&tmpUser,sizeof(User),&bytesWritten,NULL); if(!retCode || bytesWritten!=sizeof(User)){ printf("Can't write new password"); myExit(); } } void Add_Rating(){ // Add rating to user int retCode, diff; // Addition to the rating DWORD bytesWritten; User tmpUser; printf("Whose rating you want to change?\n"); Find_User(&tmpUser); if(tmpUser.exist==-1) return; printf("Current rating: %d\n",tmpUser.rating); printf("Enter the difference between old and new rating\n"); scanf("%d",&diff); tmpUser.rating=diff; // Send rating difference to the server retCode=WriteFile(hPipe,(void*)&tmpUser,sizeof(User),&bytesWritten,NULL); if(!retCode || bytesWritten!=sizeof(User)){ printf("Can't write rating difference"); myExit(); } }