// Программа из конспекта "Системное программное обеспечение" // Именованные каналы в Windows // стр. ?? // Приложение SERVER_MS (системная служба) // Демонстрация использования почтовых ящиков // для передачи данных между процессами и службами #include #include #include #include // for SetSecurityInfo extern int addLogMessage(const char* text); int ServiceStart(); void ServiceStop(); // Идентификаторы почтовых ящиков (туда и обратно) HANDLE hMailslot1, hMailslot2; // Имена создаваемых почтовых ящиков // Имя серверного канала Mailslot LPSTR lpszReadMailslotName = "\\\\.\\mailslot\\$Channel1$"; // Имя клиентского канала Mailslot LPSTR lpszWriteMailslotName = "\\\\*\\mailslot\\$Channel2$"; int Server() { // Код возврата из функций BOOL fReturnCode; // Размер сообщения в байтах DWORD cbMessages; // Количество сообщений в канале Mailslot DWORD cbMsgNumber; // Буфер для передачи данных через канал char szBuf[512]; // Количество байт данных, принятых через канал DWORD cbRead; // Количество байт данных, переданных через канал DWORD cbWritten; DWORD total = 0; // буфер для сообщения об ошибке, результата char message[80] = { 0 }; // Дескриптор файла FILE *hdl; sprintf(message,"Mailslot server demo\n"); addLogMessage(message); // Ожидаем соединения со стороны клиента // Цикл получения команд через канал while (1) { sprintf(message, "Waiting for connect...\n"); //addLogMessage(message); // Определяем состояние канала Mailslot fReturnCode = GetMailslotInfo(hMailslot1, NULL, &cbMessages,&cbMsgNumber, NULL); if (!fReturnCode) { sprintf(message, "GetMailslotInfo: Error %ld\n", GetLastError()); addLogMessage(message); //break; continue; } // Если в канале есть Mailslot сообщения, // читаем первое из них и выводим на экран if (cbMsgNumber != 0) { if (ReadFile(hMailslot1, szBuf, 512, &cbRead, NULL)) { // Выводим принятую строку на консоль sprintf(message,"Received: <%s>\n", szBuf); addLogMessage(message); // Если пришла команда "exit", завершаем работу приложения if (!strcmp(szBuf, "exit")) { sprintf(message, "Client exited!\n"); addLogMessage(message); //break; continue; // Иначе считаем что принято имя файла } else { // Открываем канал с процессом MSLOTCLIENT hMailslot2 = CreateFile(lpszWriteMailslotName, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); // Если возникла ошибка, выводим ее код и завершаем работу приложения if (hMailslot2 == INVALID_HANDLE_VALUE) { sprintf(message, "CreateFile for send: Error %ld\n",GetLastError()); addLogMessage(message); //CloseHandle(hMailslot2); //return 0; //break; CloseHandle(hMailslot2); continue; } if (hdl = fopen(szBuf, "rt")){ // цикл чтения до конца файла while (!feof(hdl)) { // чтение одного символа из файла if ((char)fgetc(hdl) == 0x20) total++; } // сообщение в консоль ошибок sprintf(message, "(Server): file:%s, spaces = %d\n", szBuf, total); addLogMessage(message);; // сообщение в канал sprintf(message, "%d", total); WriteFile(hMailslot2, message, strlen(message) + 1, &cbWritten, NULL); sprintf(message,"Bytes sent %d\n", cbWritten); addLogMessage(message); // закрытие файла fclose(hdl); } else { // сообщение в канал sprintf(message, "(Server)Can't open %s!", szBuf); addLogMessage(message);; WriteFile(hMailslot2, message, strlen(message) + 1, &cbWritten, NULL); sprintf(message,"Bytes sent %d\n", cbWritten); addLogMessage(message); } } } else { sprintf(message, "ReadFile: Error %ld\n",GetLastError()); addLogMessage(message); //break; continue; } } // Выполняем задержку на 500 миллисекунд Sleep(500); //конец цикла while } //CloseHandle(hMailslot2); return 0; } int ServiceStart() { char message[80] = { 0 }; DWORD res; // Создаем канал Mailslot, имеющий имя lpszReadMailslotName hMailslot1 = CreateMailslot( lpszReadMailslotName, 0, MAILSLOT_WAIT_FOREVER, NULL); // Если возникла ошибка, выводим ее код и зваершаем работу приложения if (hMailslot1 == INVALID_HANDLE_VALUE) { sprintf(message, "CreateMailslot: Error %ld\n", GetLastError()); addLogMessage(message); return -1; } // Выводим сообщение о создании канала SetSecurityInfo(hMailslot1, SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, NULL, NULL); sprintf(message, "Mailslot created\n"); addLogMessage(message); return 0; } void ServiceStop() { CloseHandle(hMailslot1); addLogMessage("Mailslot closed!"); }