int NetworkServer::proc(ProcJob *job){ job->serv = this; job->result = PROC_OK; job->stime = millitime(); const Protoc *req = job->req; do{ Command *cmd = proc_map.get_proc(req->head.method); if(!cmd){ log_warn("[%s] invalid method [ method: %s ].", job->link->get_basic_string(), req->head.method); job->link->response.head.status = 1; //method does not exist break; } if(job->link->request.head.magic_num != magic_num){ log_warn("[%s] invalid magic num [ magic_num: %u, config: %u ].", job->link->get_basic_string(), req->head.magic_num, magic_num); job->link->response.head.status = 2; //invalid magic num break; } if(job->link->request.head.bodylen > MAX_PACKAGE_SIZE){ log_warn("[%s] request body too big [ body len: %u, max: %u ].", job->link->get_basic_string(), job->link->request.head.bodylen, MAX_PACKAGE_SIZE); job->link->response.head.status = 3; //invalid magic num break; } job->cmd = cmd; if(cmd->flags & Command::FLAG_THREAD){ if(cmd->flags & Command::FLAG_WRITE){ log_frame("[%s] command with write property, push it to backend thread [ logid: %llu, method: %s ]", job->link->get_basic_string(), job->link->response.head.logid, job->link->response.head.method); if(-1 == writer->push(job)){ log_warn("[%s] push job into writer queue failed.", job->link->get_basic_string()); job->link->response.head.status = 5; //other system error } }else{ log_frame("[%s] command with read property, push it to backend thread [ logid: %llu, method: %s ]", job->link->get_basic_string(), job->link->response.head.logid, job->link->response.head.method); if(-1 == reader->push(job)){ log_warn("[%s] push job into reader queue failed.", job->link->get_basic_string()); job->link->response.head.status = 5; //other system error } } return PROC_THREAD; } log_frame("[%s] command will be processed in main thread [ logid: %llu, method: %s ]", job->link->get_basic_string(), job->link->response.head.logid, job->link->response.head.method); proc_t p = cmd->proc; job->time_wait = 1000 * (millitime() - job->stime); job->result = (*p)(this, job->link, *req, &job->link->response); job->time_proc = 1000 * (millitime() - job->stime) - job->time_wait; }while(0); return job->result; }
int NetworkServer::proc_result(ProcJob *job, ready_list_t *ready_list){ Link *link = job->link; int result = job->result; log_debug("[%s] process finished, wait time:%.3f,proc time:%.3f, method: %s, status: %u", job->link->get_basic_string(), job->time_wait, job->time_proc, job->req->head.method, job->link->response.head.status); if(job->cmd){ job->cmd->calls += 1; job->cmd->time_wait += job->time_wait; job->cmd->time_proc += job->time_proc; } SAFE_DELETE(job); int len = 0; if(result == PROC_ERROR){ log_info("[%s] fd: %d, proc error, maybe network is unavailable, delete link", link->get_basic_string(), link->fd()); goto proc_err; } //try to write for one time //if there is no writing buffer, 0 will be returned len = link->write(); if(len < 0){ log_warn("[%s] fd: %d, write: %d, delete link", link->get_basic_string(), link->fd(), len); goto proc_err; } if(link->response.head.bodylen + sizeof(head_t) > link->writed){ //need more writing operation fdes->set(link->fd(), FDEVENT_OUT, 1, link); }else{ if(!long_connect || 0 != link->response.head.status){ //TODO: for short connection link_count--; fdes->del(link->fd()); log_frame("[%s] short connection, close [ fd: %d ]", link->get_basic_string(), link->fd()); SAFE_DELETE(link); }else{ //TODO: long connection£¬ continue to read data link->readed = link->writed = 0; link->request.reset(); link->response.reset(); link->reset_basic_string(); fdes->set(link->fd(), FDEVENT_IN, 1, link); log_frame("[%s] long connection, try to receive request next time [ fd: %d ]", link->get_basic_string(), link->fd()); } } return PROC_OK; proc_err: this->link_count --; fdes->del(link->fd()); SAFE_DELETE(link); return PROC_ERROR; }
int NetworkServer::proc_client_event(const Fdevent *fde, ready_list_t *ready_list){ Link *link = (Link *)fde->data.ptr; if(fde->events & FDEVENT_ERR){ ready_list->push_back(link); log_warn("fd: %d, wait error, delete link", link->fd()); link->mark_error(); return 0; } if(fde->events & FDEVENT_IN){ ready_list->push_back(link); if(link->error()){ return 0; } int len = link->read(); if(len <= 0){ if(link->readed < sizeof(head_t) || link->request.head.bodylen < MAX_PACKAGE_SIZE){ log_frame("fd: %d, read: %d, delete link [ readed: %d, head_size: %d, bodylen: %u, max: %d ]", link->fd(), len, link->readed, sizeof(head_t), link->request.head.bodylen, MAX_PACKAGE_SIZE); link->mark_error(); } return 0; } } if(fde->events & FDEVENT_OUT){ if(link->error()){ return 0; } int len = link->write(); if(len < 0){ log_warn("[%s] fd: %d, write: %d, delete link", link->get_basic_string(), link->fd(), len); link->mark_error(); return 0; } if(link->response.head.bodylen + sizeof(head_t) <= link->writed){ log_frame("[%s] fd: %d, write: %d, finish writing", link->get_basic_string()); fdes->clr(link->fd(), FDEVENT_OUT); } if(!long_connect || 0 != link->response.head.status){ link_count--; fdes->del(link->fd()); log_frame("[%s] short connection, close [ fd: %d ]", link->get_basic_string(), link->fd()); SAFE_DELETE(link); }else{ link->readed = link->writed = 0; link->request.reset(); link->response.reset(); link->reset_basic_string(); fdes->set(link->fd(), FDEVENT_IN, 1, link); log_frame("[%s] long connection, try to receive request next time [ fd: %d ]", link->get_basic_string(), link->fd()); } } return 0; }
HRESULT WINAPI my_CreateDXGIFactory1( REFIID riid, void **ppFactory ) { log_frame( "dxgi", u::info ) << u::endh; HRESULT result = (*stub_CreateDXGIFactory1)(riid, ppFactory); frame << log_ret(result); return result; }
BOOL WINAPI my_UpdateLayeredWindow( HWND hwnd, HDC hdcDst, POINT *pptDst, SIZE *psize, HDC hdcSrc, POINT *pptSrc, COLORREF crKey, BLENDFUNCTION *pblend, DWORD dwFlags ) { log_frame( "gdi", u::info ) << log_var(hwnd) << u::endh; BOOL result = (*stub_UpdateLayeredWindow)( hwnd, hdcDst, pptDst, psize, hdcSrc, pptSrc, crKey, pblend, dwFlags ); frame << log_ret(result); return result; }
HRESULT STDMETHODCALLTYPE my_CreateSwapChain( IDXGIFactory* This, IUnknown* ifDevice, DXGI_SWAP_CHAIN_DESC* pdesc, IDXGISwapChain** ppSwapChain ) { log_frame( "dxgi", u::info ) << log_var(ifDevice) << log_var(pdesc->OutputWindow) << log_var(pdesc->BufferCount) << log_var(pdesc->BufferDesc.Width) << log_var(pdesc->BufferDesc.Height) << u::endh; HRESULT result = (*stub_CreateSwapChain)( This, ifDevice, pdesc, ppSwapChain ); frame << log_ret(result); return result; }
int WINAPI my_ReleaseDC( HWND hwnd, HDC hdc ) { log_frame( "user", u::info ) << log_var(hwnd) << log_var(hdc) << u::endh; int result = (*stub_ReleaseDC)( hwnd, hdc ); frame << log_ret(result); return result; }
int WINAPI my_BitBlt( HDC hdc, int x, int y, int cx, int cy, HDC hdcSrc, int x1, int y1, DWORD rop ) { log_frame( "gdi", u::info ) << log_var(hdc) << log_var(x) << log_var(y) << log_var(cx) << log_var(cy) << log_var(rop) << u::endh; BOOL result = (*stub_BitBlt)( hdc, x, y, cx, cy, hdcSrc, x1, y1, rop ); frame << log_ret(result); return result; }
HRESULT STDMETHODCALLTYPE my_CreateSwapChainForHwnd( IDXGIFactory2* This, IUnknown* pDevice, HWND hWnd, const DXGI_SWAP_CHAIN_DESC1* pDesc, const DXGI_SWAP_CHAIN_FULLSCREEN_DESC* pFullscreenDesc, IDXGIOutput* pRestrictToOutput, IDXGISwapChain1** ppSwapChain ) { log_frame( "dxgi", u::info ) << log_var(pDevice) << log_var(hWnd) << log_var(pDesc->Width) << log_var(pDesc->Height) << log_var(pDesc->BufferCount) << u::endh; HRESULT result = (*stub_CreateSwapChainForHwnd)( This, pDevice, hWnd, pDesc, pFullscreenDesc, pRestrictToOutput, ppSwapChain ); frame << log_var(*ppSwapChain) << log_ret(result); return result; }
HDC WINAPI my_GetDC( HWND hwnd ) { log_frame( "user", u::info ) << log_var(hwnd) << u::endh; HDC hdc = (*stub_GetDC)( hwnd ); frame << log_ret(hdc); return hdc; }
void STDMETHODCALLTYPE my_DrawGlyphRun( ID2D1RenderTarget* This, D2D1_POINT_2F baselineOrigin, const DWRITE_GLYPH_RUN* glyphRun, ID2D1Brush *foregroundBrush, DWRITE_MEASURING_MODE measuringMode ) { log_frame( "d2d1", u::info ) << log_var(This) << log_var(baselineOrigin.x) << log_var(baselineOrigin.y) << log_var(glyphRun->glyphCount) << u::endh; g_currentRtWithGlyph = This; (*stub_DrawGlyphRun)( This, baselineOrigin, glyphRun, foregroundBrush, measuringMode ); return; }
HRESULT STDMETHODCALLTYPE my_CreateBitmapFromWicBitmap( ID2D1RenderTarget* This, IWICBitmapSource* wicBitmapSource, const D2D1_BITMAP_PROPERTIES* bitmapProperties, ID2D1Bitmap** bitmap ) { log_frame( "d2d1", u::info ) << log_var(This) << log_var(wicBitmapSource); double dpix, dpiy; UINT width, height; wicBitmapSource->GetResolution( &dpix, &dpiy ); wicBitmapSource->GetSize( &width, &height ); frame << log_var(dpix) << log_var(dpiy) << log_var(width) << log_var(height) << u::endh; HRESULT result = (*stub_CreateBitmapFromWicBitmap)( This, wicBitmapSource, bitmapProperties, bitmap ); frame << log_var(*bitmap) << log_ret(result); return result; }
HRESULT STDMETHODCALLTYPE my_Present( IDXGISwapChain* This, UINT SyncInterval, UINT Flags ) { log_frame( "dxgi", u::info ) << log_var(This) << u::endh; HRESULT hr; DXGI_SWAP_CHAIN_DESC desc; hr = This->GetDesc( &desc ); frame << log_var(desc.BufferDesc.Width) << log_var(desc.BufferDesc.Height) << log_var(desc.OutputWindow); CComPtr<IDXGIDevice> dxgiDevice; hr = This->GetDevice( __uuidof(IDXGIDevice), (void**)&dxgiDevice ); frame << log_var(dxgiDevice); HRESULT result = stub_Present(This, SyncInterval, Flags ); frame << log_ret(result); return result; }
HRESULT STDMETHODCALLTYPE my_CreateWicBitmapRenderTarget( ID2D1Factory* This, IWICBitmap* target, const D2D1_RENDER_TARGET_PROPERTIES *renderTargetProperties, ID2D1RenderTarget** renderTarget ) { log_frame( "d2d1", u::info ) << log_var(This) << log_var(target) << u::endh; // Some data about the bitmap UINT width, height; double dpix, dpiy; target->GetSize( &width, &height ); target->GetResolution( &dpix, &dpiy ); frame << log_var(width) << log_var(height); frame << log_var(dpix) << log_var(dpiy); HRESULT result = (*stub_CreateWicBitmapRenderTarget)( This, target, renderTargetProperties, renderTarget ); frame << log_var(*renderTarget) << log_ret(result); return result; }
LRESULT WINAPI my_DispatchMessage( const MSG *pmsg ) { log_frame( "user", u::info ) << log_var(pmsg->hwnd) << log_var_f(pmsg->message, "%x") << u::endh; LRESULT result = (*stub_DispatchMessage)(pmsg); if( pmsg->message == 0x401 ) { CPlug* pplug = CPlug::inst(); if( pplug ) { CSubclsWnd* pwnd = pplug->getSubclsWnd(); if( pwnd ) { //CPlug::inst()->getSubclsWnd()->highlight(); } } } frame << log_ret(result); return result; }
HRESULT STDMETHODCALLTYPE my_Present1( IDXGISwapChain1* This, UINT SyncInterval, UINT PresentFlags, const DXGI_PRESENT_PARAMETERS *pPresentParameters ) { log_frame( "dxgi", u::info ) << log_var(This) << u::endh; HRESULT hr; DXGI_SWAP_CHAIN_DESC1 desc; hr = This->GetDesc1( &desc ); frame << log_var(desc.Width) << log_var(desc.Height); HWND hwnd; hr = This->GetHwnd( &hwnd ); frame << log_var(hwnd); CComPtr<IDXGIDevice> dxgiDevice; hr = This->GetDevice( __uuidof(IDXGIDevice), (void**)&dxgiDevice ); frame << log_var(dxgiDevice); HRESULT result = (*stub_Present1)(This, SyncInterval, PresentFlags, pPresentParameters ); frame << log_ret(result); return result; }
void STDMETHODCALLTYPE my_DrawBitmap( ID2D1RenderTarget* This, ID2D1Bitmap* bitmap, const D2D1_RECT_F* destRc, FLOAT opacity, D2D1_BITMAP_INTERPOLATION_MODE interpolationMode, const D2D1_RECT_F* srcRc ) { log_frame( "d2d1", u::info ) << log_var(This) << log_var(bitmap) << log_var(opacity); D2D1_SIZE_F bitmapSize = bitmap->GetSize( ); frame << log_var(bitmapSize.width) << log_var(bitmapSize.height); if( destRc ) { frame << log_var(destRc->left) << log_var(destRc->top) << log_var(destRc->right) << log_var(destRc->bottom); } if( srcRc ) { frame << log_var(srcRc->left) << log_var(srcRc->top) << log_var(srcRc->right) << log_var(srcRc->bottom); } frame << u::endh; (*stub_DrawBitmap)(This, bitmap, destRc, opacity, interpolationMode, srcRc ); return; }
/********************************************************************************************************************** CProcessBase::Flush_System_Messages -- Manager and log messages get sent separately from other messages. This function must be the last function called in this thread's execution context/tbb-execute. The instant a reschedule message is pushed to the manager, this thread may end up getting reexecuted which would cause data corruption if the current execution is still ongoing. **********************************************************************************************************************/ void CProcessBase::Flush_System_Messages( void ) { bool is_shutting_down = Is_Shutting_Down(); // Flush logging messages if possible if ( LoggingMailbox.get() != nullptr && LogFrame.get() != nullptr ) { shared_ptr< CProcessMessageFrame > log_frame( LogFrame ); LogFrame.reset(); LoggingMailbox->Add_Frame( log_frame ); } // Clear log interface if necessary if ( is_shutting_down ) { LoggingMailbox.reset(); } // Flush manager messages if possible if ( ManagerMailbox.get() != nullptr && ManagerFrame.get() != nullptr ) { shared_ptr< CProcessMessageFrame > manager_frame( ManagerFrame ); ManagerFrame.reset(); ManagerMailbox->Add_Frame( manager_frame ); } // Clear manager interface if necessary if ( is_shutting_down ) { // logically safe to do even after we've pushed messages // A thread should not be rescheduled if it's in the shut down stage, and even it did // get rescheduled, the subsequent execution of the thread does nothing and does not access // the manager interface ManagerMailbox.reset(); } }
static void log_sysinfo(void) { struct rx_meas_stat *meas = &ms->meas; struct gsm48_sysinfo *s = &sysinfo; int8_t rxlev; char ta_str[32] = ""; if (log_si.ta != 0xff) sprintf(ta_str, " TA=%d", log_si.ta); LOGP(DSUM, LOGL_INFO, "Cell: ARFCN=%d MCC=%s MNC=%s (%s, %s)%s\n", arfcn, gsm_print_mcc(s->mcc), gsm_print_mnc(s->mnc), gsm_get_mcc(s->mcc), gsm_get_mnc(s->mcc, s->mnc), ta_str); LOGFILE("[sysinfo]\n"); LOGFILE("arfcn %d\n", s->arfcn); log_time(); log_gps(); LOGFILE("bsic %d,%d\n", s->bsic >> 3, s->bsic & 7); rxlev = meas->rxlev / meas->frames - 110; LOGFILE("rxlev %d\n", rxlev); if (s->si1) log_frame("si1", s->si1_msg); if (s->si2) log_frame("si2", s->si2_msg); if (s->si2bis) log_frame("si2bis", s->si2b_msg); if (s->si2ter) log_frame("si2ter", s->si2t_msg); if (s->si3) log_frame("si3", s->si3_msg); if (s->si4) log_frame("si4", s->si4_msg); if (log_si.ta != 0xff) LOGFILE("ta %d\n", log_si.ta); LOGFILE("\n"); LOGFLUSH(); }
void STDMETHODCALLTYPE my_BeginDraw( ID2D1RenderTarget* This ) { log_frame( "d2d1", u::info ) << log_var(This) << u::endh; (*stub_BeginDraw)( This ); return; }
void NetworkServer::serve(){ { auto_mask mask(3, SIGPIPE, SIGINT, SIGTERM, SIGQUIT); writer = new (std::nothrow)ProcWorkerPool("writer"); ASSERT_SYS(NULL != writer, "try to new ProcWorkerPool failed, no memory"); writer->start(num_writers); reader = new (std::nothrow)ProcWorkerPool("reader"); ASSERT_SYS(NULL != reader, "try to new ProcWorkerPool failed, no memory"); reader->start(num_readers); } ready_list_t ready_list; ready_list_t ready_list_2; ready_list_t::iterator it; const Fdevents::events_t *events; fdes->set(serv_link->fd(), FDEVENT_IN, 0, serv_link); fdes->set(this->reader->fd(), FDEVENT_IN, 0, this->reader); fdes->set(this->writer->fd(), FDEVENT_IN, 0, this->writer); uint32_t last_ticks = g_ticks; while(!quit){ if((uint32_t)(g_ticks - last_ticks) >= STATUS_REPORT_TICKS){ last_ticks = g_ticks; log_info("server is running, links: %d", this->link_count); } ready_list.swap(ready_list_2); ready_list_2.clear(); if(!ready_list.empty()){ events = fdes->wait(0); }else{ events = fdes->wait(50); } if(events == NULL){ log_fatal("events.wait error: %s", strerror(errno)); break; } for(int i=0; i<(int)events->size(); i++){ const Fdevent *fde = events->at(i); if(fde->data.ptr == serv_link){ Link *link = accept_link(); if(link){ this->link_count ++; log_debug("new link from %s:%d, fd: %d, links count: %d", link->remote_ip, link->remote_port, link->fd(), this->link_count); fdes->set(link->fd(), FDEVENT_IN, 1, link); } }else if(fde->data.ptr == this->reader || fde->data.ptr == this->writer){ ProcWorkerPool *worker = (ProcWorkerPool *)fde->data.ptr; ProcJob *job = NULL; if(worker->pop(&job) == 0){ log_fatal("reading result from workers error!"); exit(0); } if(proc_result(job, &ready_list) == PROC_ERROR){ // } }else{ proc_client_event(fde, &ready_list); } } for(it = ready_list.begin(); it != ready_list.end(); it ++){ Link *link = *it; if(link->error()){ this->link_count --; fdes->del(link->fd()); SAFE_DELETE(link); continue; } if(link->readed >= sizeof(head_t) && 0x00 == link->get_basic_string()[0]){ if(0 == link->request.head.logid){ link->request.head.logid = pow(2, 64) * (rand() / (RAND_MAX + 1.0)); } link->add_basic_info("client_ip", link->remote_ip); link->add_basic_info("client_port", link->remote_port); link->add_basic_info("logid", link->request.head.logid); link->add_basic_info("method", link->request.head.method); link->add_basic_info("magic_num", link->request.head.magic_num); } if(link->readed >= sizeof(head_t) && link->request.head.bodylen > MAX_PACKAGE_SIZE){ log_frame("[ %s ]fd: %d, body len is too big, give up reading[ body len: %u, max: %u ].", link->get_basic_string(), link->request.head.bodylen, MAX_PACKAGE_SIZE); fdes->del(link->fd()); }else if(link->readed < sizeof(head_t) || link->request.head.bodylen + sizeof(head_t) > link->readed){ //head has not been read over or body has not been read over, continue to read log_frame("[ %s ]fd: %d, readed: %d, bodylen: %u, continue to read", (link->readed >= sizeof(head_t) ? link->get_basic_string() : ""), link->fd(), link->readed, link->request.head.bodylen); fdes->set(link->fd(), FDEVENT_IN, 1, link); continue; }else{ log_frame("[ %s ]fd: %d, readed: %d, bodylen: %u, read data finished", link->get_basic_string(), link->fd(), link->readed, link->request.head.bodylen); fdes->del(link->fd()); } link->active_time = millitime(); //prepare response head first link->response.head = link->request.head; snprintf(link->response.head.provider, sizeof(link->response.head.provider), "%s", provider); link->response.head.bodylen = 0; ProcJob *job = new (std::nothrow)ProcJob(); ASSERT_SYS(NULL != job, "try to new ProcJob failed, no memory"); job->link = link; job->req = &link->request; int result = this->proc(job); if(result == PROC_THREAD){ fdes->del(link->fd()); continue; } if(result == PROC_BACKEND){ job->req = &link->request; this->link_count --; continue; } if(proc_result(job, &ready_list_2) == PROC_ERROR){ // } } // end foreach ready link } }
HRESULT STDMETHODCALLTYPE my_EndDraw( ID2D1RenderTarget* This, D2D1_TAG *tag1, D2D1_TAG *tag2 ) { HRESULT hr; log_frame( "d2d1", u::info ) << log_var(This) << u::endh; if( g_currentRtWithGlyph == This ) { CComPtr<ID2D1SolidColorBrush> ifBrushBlack; CComPtr<ID2D1SolidColorBrush> ifBrushRed; CComPtr<ID2D1SolidColorBrush> ifBrushGreen; CComPtr<ID2D1SolidColorBrush> ifBrushBlue; CComPtr<ID2D1SolidColorBrush> ifBrushOrange; hr = This->CreateSolidColorBrush( D2D1::ColorF( D2D1::ColorF::Black ), &ifBrushBlack ); hr = This->CreateSolidColorBrush( D2D1::ColorF( D2D1::ColorF::Red ), &ifBrushRed ); hr = This->CreateSolidColorBrush( D2D1::ColorF( D2D1::ColorF::Green ), &ifBrushGreen ); hr = This->CreateSolidColorBrush( D2D1::ColorF( D2D1::ColorF::Blue ), &ifBrushBlue ); hr = This->CreateSolidColorBrush( D2D1::ColorF( D2D1::ColorF::OrangeRed, 0.5f ), &ifBrushOrange ); D2D1_RECT_F rect; rect.left = 0; rect.top = 0; rect.right = 1024; rect.bottom = 2014; //This->PushAxisAlignedClip( &rect, D2D1_ANTIALIAS_MODE_PER_PRIMITIVE ); //This->DrawLine( D2D1::Point2F(0.0f, 0.0f), D2D1::Point2F(480.0f, 480.0f), ifBrush ); if( CPlug::inst()->IsDoingGrid() ) { for( int i=0; i<20; ++i ) { for( int j=0; j<20; ++j ) { float cy = i * 50.0f; float cx = j * 50.0f; ID2D1SolidColorBrush* ifBrush = ( i<10 && j < 10 ) ? ifBrushBlack : ( i<10 ) ? ifBrushRed : ( j<10 ) ? ifBrushGreen : ifBrushBlue; This->DrawLine( D2D1::Point2F( cx - 5.0f, cy - 5.0f ), D2D1::Point2F( cx + 5.0f, cy + 5.0f ), ifBrush ); This->DrawLine( D2D1::Point2F( cx + 5.0f, cy - 5.0f ), D2D1::Point2F( cx - 5.0f, cy + 5.0f ), ifBrush ); } } //This->PopAxisAlignedClip(); } if( CPlug::inst()->IsDoingRosebud() ) { CPlug* pplug = CPlug::inst(); if( pplug ) { int num; int i; num = pplug->numRosebuds( ); for( i = 0; i < num; ++i ) { int ileft, itop, iright, ibottom; bool f = pplug->enumRosebud( i, &ileft, &itop, &iright, &ibottom ); if( f ) { float left = (float)ileft; float top = (float)itop; float right = (float)iright; float bottom = (float)ibottom; //This->DrawLine( D2D1::Point2F( left, top ), D2D1::Point2F( right, top ), ifBrushBlack ); //This->DrawLine( D2D1::Point2F( right, top ), D2D1::Point2F( right, bottom ), ifBrushBlack ); //This->DrawLine( D2D1::Point2F( right, bottom ), D2D1::Point2F( left, bottom ), ifBrushBlack ); //This->DrawLine( D2D1::Point2F( left, bottom ), D2D1::Point2F( left, top ), ifBrushBlack ); D2D1_RECT_F rc = D2D1::RectF( left, top, right, bottom ); This->FillRectangle( &rc, ifBrushOrange ); } } } } g_currentRtWithGlyph = NULL; } HRESULT result = stub_EndDraw(This, tag1, tag2 ); frame << log_ret(result); return result; }