bool ServiceBase::OnCommand(DWORD dwControl, DWORD dwEventType, void *lpEventData) { TRC(2, ServiceName << ": " << ServiceControlToString(dwControl)); switch (dwControl) { case SERVICE_CONTROL_STOP: Stop(); break; case SERVICE_CONTROL_SHUTDOWN: Status = SERVICE_STOP_PENDING; OnShutdown(); break; case SERVICE_CONTROL_PAUSE: Status = SERVICE_PAUSE_PENDING; OnPause(); break; case SERVICE_CONTROL_CONTINUE: Status = SERVICE_CONTINUE_PENDING; OnContinue(); break; case SERVICE_CONTROL_INTERROGATE: Status = m_status; break; case SERVICE_CONTROL_POWEREVENT: OnPowerEvent((PowerBroadcastStatus)dwEventType); break; case SERVICE_CONTROL_SESSIONCHANGE: { SessionChangeDescription scd = { (SessionChangeReason)dwEventType, (int)((WTSSESSION_NOTIFICATION*)lpEventData)->dwSessionId }; TRC(2, ReasonToString(scd.Reason)); OnSessionChange(scd); } break; case SERVICE_CONTROL_PARAMCHANGE: OnParamChange(); break; case SERVICE_CONTROL_TIMECHANGE: OnTimeChange(); break; case SERVICE_CONTROL_HARDWAREPROFILECHANGE: OnHardwareProfileChange(); break; default: if (dwControl >= 128 && dwControl <= 255) OnCustomCommand(dwControl); else return false; } return true; }
/*************************************************** OnConnect This member is called when a connection is made and accepted. Do all processing here, since the connection is automatically terminated when this function returns. Plus the thread that this function runs in is terminated as well. This function is the main engine that process all clients commands. PARAM NONE RETURN VOID ****************************************************/ void CUT_HTTPThread::OnConnect(){ char command[30]; int success = TRUE; // Clear the data variables m_szFileName[0] = 0; m_szBuf[0] = 0; m_szData[0] = 0; // Get the current tick count long tickCount = GetTickCount(); // Get the first line int len = ReceiveLine(m_szData, WSS_BUFFER_SIZE*2); // Break on error or disconnect if(len <= 0) return; // Remove the CRLF pair from the string CUT_StrMethods::RemoveCRLF(m_szData); // Parse the line if(CUT_StrMethods::ParseString(m_szData," ",0,command,30) != UTE_SUCCESS) { // Command not reconized Send("Command Not Reconized\r\n"); return; } // Get the command ID int commandID = GetCommandID(command); if(commandID == CUT_NA) { Send("Command Not Reconized\r\n"); return; } //********************************** // Check for GET //********************************** if(commandID == CUT_GET || commandID == CUT_HEAD ){ // Get the filename if(CUT_StrMethods::ParseString(m_szData," ?",1,m_szBuf, WSS_BUFFER_SIZE) != UTE_SUCCESS) { // Command not reconized Send("Command Not Reconized\r\n"); return; } // Get the absolute path if(MakePath(m_szFileName,m_szBuf) != UTE_SUCCESS) { Send("HTTP/1.0 404 Requested file not found\r\n"); return; } // Send a start notification if(OnNotify(CUT_START,commandID,m_szFileName,sizeof(m_szFileName),success) == FALSE) { // If FALSE is returned then do not continue ClearReceiveBuffer(); return; } // Open the file // v4.2 using CreateFileA here HANDLE hFile = CreateFileA(m_szFileName,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,0,NULL); if(hFile == INVALID_HANDLE_VALUE) { Send("HTTP/1.0 404 Requested file not found\r\n"); success = FALSE; } else { // Send the MIME header Send("HTTP/1.0 200 OK\r\n"); _snprintf(m_szBuf,sizeof(m_szBuf)-1,"Date:%s\r\n",GetGMTStamp()); Send(m_szBuf); Send("Server: The Ultimate Toolbox WWW Server\r\n"); Send("MIME-verion: 1.0\r\n"); _snprintf(m_szBuf,sizeof(m_szBuf)-1,"Content-type: %s\r\n",GetContentType(m_szFileName)); Send(m_szBuf); _snprintf(m_szBuf,sizeof(m_szBuf)-1,"Last-modified: %s\r\n",GetFileModifiedTime(hFile)); Send(m_szBuf); DWORD hiVal; long OrigFileSize = GetFileSize(hFile,&hiVal); _snprintf(m_szBuf,sizeof(m_szBuf)-1,"Content-length: %ld\r\n",OrigFileSize); Send(m_szBuf); Send("\r\n"); // Send the file only for a GET if(commandID == CUT_GET) { // Get the max send size to send at once len = GetMaxSend(); if(len > WSS_BUFFER_SIZE*2) len = WSS_BUFFER_SIZE*2; // Send the file DWORD readLen; int rt; long totalLen = 0; // v4.2 change - was while(1) - gave conditional expression is constant warning for (;;) { rt = ReadFile(hFile,m_szData,len,&readLen,NULL); if(rt == FALSE || readLen ==0) break; if(Send(m_szData,readLen) == SOCKET_ERROR) break; totalLen+= readLen; } if(totalLen != OrigFileSize) success = FALSE; } CloseHandle(hFile); ClearReceiveBuffer(); } // Send a finish notification OnNotify(CUT_FINISH,commandID,m_szFileName,sizeof(m_szFileName),success); } //********************************** // Check for POST //********************************** else if(commandID == CUT_POST) { while(IsDataWaiting()) { len = ReceiveLine(m_szData, WSS_BUFFER_SIZE*2); CUT_StrMethods::RemoveCRLF(m_szData); ((CUT_HTTPServer *)m_winsockclass_this)->OnStatus(m_szData); } } //********************************** // Check for PUT //********************************** else if(commandID == CUT_PUT){ Send("HTTP/1.0 501 Not Implemented\r\n\r\n"); Send("Server: The Ultimate Toolbox WWW Server\r\n"); Send("MIME-verion: 1.0\r\n"); return; } //********************************** // Check for PLACE //********************************** else if(commandID == CUT_PLACE) { Send("HTTP/1.0 501 Not Implemented\r\n\r\n"); return; } //********************************** // Check for DELETE //********************************** else if(commandID == CUT_DELETE) { // Get the filename if(CUT_StrMethods::ParseString(m_szData," ",1,m_szBuf, WSS_BUFFER_SIZE) != UTE_SUCCESS) { // Command not reconized Send("HTTP/1.0 400 Bad Request\r\n\r\n"); return; } // Get the absolute path if(MakePath(m_szFileName,m_szBuf) != UTE_SUCCESS) { Send("HTTP/1.0 404 Requested file not found\r\n\r\n"); return; } // Send a start notification if(OnNotify(CUT_START,commandID,m_szFileName,sizeof(m_szFileName),success) == FALSE) { // If FALSE is returned then do not continue Send("HTTP/1.0 405 Method Not Allowed\r\n"); Send("Content-Type: text/html\r\n\r\n"); Send("<html><body>DELETE Method Not Allowed</body></html>"); ClearReceiveBuffer(); return; } // Send the finish notify // v4.2 using DeleteFileA here if(DeleteFileA(m_szFileName) == FALSE) { Send("HTTP/1.0 500 Internal Server Error\r\n"); success = FALSE; return ; } // Send a start notification OnNotify(CUT_FINISH,commandID,m_szFileName,sizeof(m_szFileName),success); } //********************************** // Allow handling for custom commands //********************************** else { // Get the rest of the data after the command char* pData = strstr(m_szData, " "); if (pData) strncpy(m_szBuf, pData+1, sizeof(m_szBuf)); if(OnNotify(CUT_START,commandID,m_szBuf,sizeof(m_szBuf),success) == FALSE) { // If FALSE is returned then do not continue ClearReceiveBuffer(); return; } OnCustomCommand(commandID,m_szBuf,WSS_BUFFER_SIZE); // Send a finish notification OnNotify(CUT_FINISH,commandID,m_szBuf,sizeof(m_szBuf),success); //Returns so the default OnSendStatus() implementation is not called. // If needed OnStatus() can be called in the OnNotify(CUT_FINISH)! return; } // Send a status line to the server history window OnSendStatus(commandID,m_szFileName,success,tickCount); }