{*******************************************************} { } { RdpSecuServer } { } { Copyright (C) 2022 kku } { } {*******************************************************} unit RSecuServer; interface uses Tocsg.ServerBase, System.SysUtils, System.Classes, Winapi.Messages, Winapi.Windows, Tocsg.Packet, Tocsg.StoredPacket, System.SyncObjs, System.Generics.Collections, Winapi.Winsock2; const WM_CRMSERVER_NOTIFICATION = WM_USER + 4938; NOTI_RCV_TEST = 0; NOTI_SERVER_ON = 1; NOTI_SERVER_OFF = 2; NOTI_CLIENT_CONN = 3; NOTI_CLIENT_DISCONN = 4; NOTI_REFRESH_LIST = 5; type TTgClientCtx = class(TTgClientCtxBase) private sEmpNo_, sRdpRqIp_: String; bRdpOn_: Boolean; public Constructor Create(aServer: TTgServerBase; aSocket: TSocket); property EmpNo: String read sEmpNo_; property RdpOn: Boolean read bRdpOn_; end; TStdPktList = class(TList) protected procedure Notify(const Item: TTgStoredPacket; Action: TCollectionNotification); override; end; TRSecuServer = class(TTgServerBase) private CSStored_: TCriticalSection; wStdPktCnt_, wStdPktPos_: WORD; StdPktList_: TStdPktList; ThdProcStdPkd_: TObject; // ¼­¹ö »óž˸² ¸Þ½ÃÁö Àü¼Û ÇÚµé 22_0411 08:57:10 kku hRcvHwnd_: THandle; DcRdpOnCtx_: TDictionary; protected procedure SetActive(bVal: Boolean); override; function CreateClientContext(aSocket: TSocket): TTgClientCtxBase; override; procedure ClientConnectedEvent(aClientCtx: TTgClientCtxBase); override; procedure ClientDisconnectedEvent(aClientCtx: TTgClientCtxBase); override; procedure ProcessClientConnection(aCtx: TTgClientCtxBase); override; procedure ProcessRcvPacket(aCtx: TTgClientCtxBase; aRcv: IRcvPacket); override; // procedure ProcessFileQueuePacket(ClientCtx: TTgClientCtxBase; // RcvPacket: IRcvPacket); overload; override; // procedure ProcessFileQueuePacket(ClientContext: TSunkClientContext; pRcvBuf: Pointer; nRcvLen: Integer); overload; override; public Constructor Create(hRcvHwnd: HWND; nPort: Integer); Destructor Destroy; override; procedure SafeFreeUseSaveStored(const sPath: String); end; var gServer: TRSecuServer = nil; implementation uses Tocsg.Exception, ThdProcStoredPacket, Tocsg.PacketDefine, GlobalSocketDefine, Tocsg.Safe, superobject; { TTgClientCtx } Constructor TTgClientCtx.Create(aServer: TTgServerBase; aSocket: TSocket); begin Inherited Create(aServer, aSocket); sEmpNo_ := ''; sRdpRqIp_ := ''; bRdpOn_ := false; end; { TStdPktList } procedure TStdPktList.Notify(const Item: TTgStoredPacket; Action: TCollectionNotification); begin if Action = cnRemoved then Item.Free; end; { TRSecuServer } Constructor TRSecuServer.Create(hRcvHwnd: HWND; nPort: Integer); begin Inherited Create(nPort); ASSERT(gServer = nil); gServer := Self; hRcvHwnd_ := hRcvHwnd; ThdProcStdPkd_ := nil; CSStored_ := TCriticalSection.Create; DcRdpOnCtx_ := TDictionary.Create; wStdPktCnt_ := 0; wStdPktPos_ := 0; StdPktList_ := TStdPktList.Create; end; Destructor TRSecuServer.Destroy; begin gServer := nil; Inherited; if ThdProcStdPkd_ <> nil then FreeAndNil(ThdProcStdPkd_); FreeAndNil(CSStored_); FreeAndNil(DcRdpOnCtx_); FreeAndNil(StdPktList_); end; procedure TRSecuServer.SetActive(bVal: Boolean); var i: Integer; StdPkt: TTgStoredPacket; begin if bActive_ = bVal then exit; if bVal then begin // todo : °¢Á¾ °æ·Î ¼³Á¤ if ThdProcStdPkd_ <> nil then FreeAndNil(ThdProcStdPkd_); wStdPktPos_ := 0; wStdPktCnt_ := 0; // gCfg.PktDiv if wStdPktCnt_ > 0 then begin if wStdPktCnt_ > 20 then wStdPktCnt_ := 20; for i := 0 to wStdPktCnt_ - 1 do begin StdPkt := TTgStoredPacket.Create(Format('c:\test\Pkt%.2d\stdpkt', [i + 1])); StdPkt.SegSize := MAX_DATA_SIZE; // gCfg.StdPktSegSize StdPktList_.Add(StdPkt); end; end else begin StdPkt := TTgStoredPacket.Create('c:\test_stdPkt'); StdPkt.SegSize := MAX_DATA_SIZE; // gCfg.StdPktSegSize StdPktList_.Add(StdPkt); // ThdProcStdPkd_ := TThdProcStoredPacketFile.Create('', '', 500); end; end else begin end; Inherited; // after process .. 14_0121 17:56:36 sunk if bActive_ then begin if hRcvHwnd_ <> 0 then SendMessage(hRcvHwnd_, WM_CRMSERVER_NOTIFICATION, NOTI_SERVER_ON, 0); end else begin // todo : ÃʱâÈ­ ó¸® if hRcvHwnd_ <> 0 then SendMessage(hRcvHwnd_, WM_CRMSERVER_NOTIFICATION, NOTI_SERVER_OFF, 0); DcRdpOnCtx_.Clear; if ThdProcStdPkd_ <> nil then begin TThdProcStoredPacketFile(ThdProcStdPkd_).StopThread; Sleep(500); FreeAndNil(ThdProcStdPkd_); end; StdPktList_.Clear; end; end; function TRSecuServer.CreateClientContext(aSocket: TSocket): TTgClientCtxBase; begin Result := TTgClientCtx.Create(Self, aSocket); end; procedure TRSecuServer.ClientConnectedEvent(aClientCtx: TTgClientCtxBase); var ClientCtx: TTgClientCtx; begin // if aClientCtx is TTgClientCtx then // begin // ClientCtx := TTgClientCtx(aClientCtx); // if ClientCtx.ClientInfo.ClientType <> CLIENT_TYPE_MANAGER then // begin // // end; // end; Inherited; end; procedure TRSecuServer.ClientDisconnectedEvent(aClientCtx: TTgClientCtxBase); var enum: TClientEnumerator; Ctx, CtxEnt: TTgClientCtx; Send: ISendPacket; begin Ctx := TTgClientCtx(aClientCtx); Guard(enum, GetClientEnumerator); while enum.MoveNext do begin CtxEnt := TTgClientCtx(enum.Current); if CtxEnt.sRdpRqIp_ = Ctx.ClientInfo_.sIpAddr then begin CtxEnt.SendPacket(TTgPacket.Create(RS_REQ_RDP_CLOSE)); end; end; if hRcvHwnd_ <> 0 then SendMessage(hRcvHwnd_, WM_CRMSERVER_NOTIFICATION, NOTI_CLIENT_DISCONN, NativeUInt(aClientCtx)); Inherited; end; procedure TRSecuServer.SafeFreeUseSaveStored(const sPath: String); begin CSStored_.Acquire; try if (wStdPktCnt_ = 0) and (StdPktList_.Count = 1) then StdPktList_[0].SafeFreeSaveStored(sPath, TASK_LOAD); finally CSStored_.Release; end; end; procedure TRSecuServer.ProcessClientConnection(aCtx: TTgClientCtxBase); begin end; procedure TRSecuServer.ProcessRcvPacket(aCtx: TTgClientCtxBase; aRcv: IRcvPacket); var Ctx: TTgClientCtx; procedure process_TOC_TEST; begin if hRcvHwnd_ <> 0 then begin TTgPacket(aRcv).Socket := aCtx; SendMessage(hRcvHwnd_, WM_CRMSERVER_NOTIFICATION, NOTI_RCV_TEST, NativeInt(aRcv)); end; end; procedure process_RC_RSECU_INFO; begin Ctx.sEmpNo_ := aRcv.S['EmpNo']; if hRcvHwnd_ <> 0 then SendMessage(hRcvHwnd_, WM_CRMSERVER_NOTIFICATION, NOTI_CLIENT_CONN, NativeUInt(Ctx)); end; procedure process_RS_REQ_RDP_DESTLIST; var enum: TClientEnumerator; Send: ISendPacket; O, OA: ISuperObject; sEmpNo: String; CtxEnt: TTgClientCtx; begin sEmpNo := aRcv.S['EmpNo']; Send := TTgPacket.Create(aRcv); OA := TSuperObject.Create(stArray); Guard(enum, GetClientEnumerator); while enum.MoveNext do begin CtxEnt := TTgClientCtx(enum.Current); if CtxEnt = Ctx then continue; if not CtxEnt.bRdpOn_ and (CompareText(CtxEnt.sEmpNo_, sEmpNo) = 0) then begin O := SO; O.S['IP'] := CtxEnt.ClientInfo_.sIpAddr; O.S['EmpNo'] := sEmpNo; O.S['Account'] := CtxEnt.ClientInfo_.sAccount; O.S['ComName'] := CtxEnt.ClientInfo_.sComName; OA.AsArray.Add(O); end; end; Send.O['List'] := OA; Ctx.SendPacket(Send); end; procedure process_RS_REQ_RDP_CONNECT; var enum: TClientEnumerator; Send: ISendPacket; sIp: String; CtxEnt: TTgClientCtx; begin sIp := aRcv.S['IP']; Guard(enum, GetClientEnumerator); while enum.MoveNext do begin CtxEnt := TTgClientCtx(enum.Current); if CtxEnt.ClientInfo_.sIpAddr = sIp then begin if CtxEnt.bRdpOn_ then begin Send := TTgPacket.Create(aRcv); Send.Result := 1; Send.ResultMsg := 'ÀÌ¹Ì ´ë±âÁßÀÎ ¿¬°áÀÌ ÀÖ½À´Ï´Ù.'; Ctx.SendPacket(Send); end else begin Send := TTgPacket.Create(RS_REQ_RDP_OPEN); Send.Handle := aRcv.Handle; Send.WndMessage := aRcv.WndMessage; Send.S['RqIP'] := Ctx.ClientInfo_.sIpAddr; Send.S['ComName'] := Ctx.ClientInfo_.sComName; Send.S['Account'] := Ctx.ClientInfo_.sAccount; CtxEnt.SendPacket(Send); end; exit; end; end; end; procedure process_RS_REQ_RDP_OPEN; var sRqIp: String; enum: TClientEnumerator; CtxEnt: TTgClientCtx; Send: ISendPacket; begin Send := TTgPacket.Create(RS_REQ_RDP_CONNECT); Send.Handle := aRcv.Handle; Send.WndMessage := aRcv.WndMessage; Send.I['Port'] := aRcv.I['Port']; Send.Result := aRcv.Result; Send.ResultMsg := aRcv.ResultMsg; sRqIp := aRcv.S['RqIP']; Guard(enum, GetClientEnumerator); while enum.MoveNext do begin CtxEnt := TTgClientCtx(enum.Current); if CtxEnt.ClientInfo_.sIpAddr = sRqIp then begin if aRcv.Result = 0 then begin Ctx.sRdpRqIp_ := sRqIp; Ctx.bRdpOn_ := true; Send.Toss := NativeUInt(Ctx); if hRcvHwnd_ <> 0 then SendMessage(hRcvHwnd_, WM_CRMSERVER_NOTIFICATION, NOTI_REFRESH_LIST, 0); end; CtxEnt.SendPacket(Send); exit; end; end; end; procedure process_RS_REQ_RDP_CLOSE; begin Ctx.sRdpRqIp_ := ''; Ctx.bRdpOn_ := false; if hRcvHwnd_ <> 0 then SendMessage(hRcvHwnd_, WM_CRMSERVER_NOTIFICATION, NOTI_REFRESH_LIST, 0); end; var dwCmd: DWORD; begin dwCmd := 0; if not IsValidClient(aCtx) then exit; Ctx := TTgClientCtx(aCtx); try dwCmd := aRcv.Command; case dwCmd of TOC_TEST : process_TOC_TEST; RC_RSECU_INFO : process_RC_RSECU_INFO; RS_REQ_RDP_DESTLIST : process_RS_REQ_RDP_DESTLIST; RS_REQ_RDP_CONNECT : process_RS_REQ_RDP_CONNECT; RS_REQ_RDP_OPEN : process_RS_REQ_RDP_OPEN; RS_REQ_RDP_CLOSE : process_RS_REQ_RDP_CLOSE; else Inherited; end; except on E: Exception do ETgException.TraceException(Self, E, 'Fail .. ProcessRcvPacket(), Cmd=%d', [dwCmd]); end; end; end.