Здравствуйте, собственно в теме указано с чем нужна помощь. Мне нужно рисовать на поверхности DD7 приложения. DirectDrawCreateEx перехвачена, теперь я хочу создать свой интерфейс, поддерживающий IDirectDraw7 Код (Text): #undef INTERFACE #define INTERFACE myIDirectDraw7 DECLARE_INTERFACE_(INTERFACE, IDirectDraw7) { BEGIN_INTERFACE STDMETHOD(CreateSurface)(THIS_ LPDDSURFACEDESC2, LPDIRECTDRAWSURFACE7 FAR *, IUnknown FAR *) PURE; STDMETHOD(GetDisplayMode)( THIS_ LPDDSURFACEDESC2) PURE; STDMETHOD(RestoreDisplayMode)(THIS) PURE; STDMETHOD(SetCooperativeLevel)(THIS_ HWND, DWORD) PURE; STDMETHOD(SetDisplayMode)(THIS_ DWORD, DWORD,DWORD, DWORD, DWORD) PURE; END_INTERFACE }; Переопределить там нужные для перехвата методы, создать класс, поддерживающий новый интерфейс и подсовывать всю эту кухню в DirectDrawCreateEx в параметре lplpDD, но что то подсказывает что я брешу) Какие будут комментарии, ссылки, идеи, готовые куски кода. Заранее спасибо!
Ну и оадно, диалог не удался, устроим монолог. Может кому решение и понадобится) Код (Text): HRESULT WINAPI MyDirectDrawCreateEx(GUID *lpGuid,LPVOID *lplpDD,const IID &iid,IUnknown *pUnkOuter) { #define CREATE_SURFACE_OFFSET 24 HRESULT ret= NULL; DWORD* ppvtbl= NULL; DWORD* pvtbl= NULL; DWORD flOldProtect= NULL; DWORD flNewProtect= NULL; DWORD flDontCare= NULL; DWORD* pCreateSurface= NULL; MEMORY_BASIC_INFORMATION mbi; OutputDebugString("!!in MyDirectDrawCreateEx"); ret=pDirectDrawCreateEx(lpGuid,lplpDD,iid,pUnkOuter); ppvtbl = (DWORD*)*lplpDD; pvtbl = (DWORD*) *ppvtbl; VirtualQuery( (void*)pvtbl, &mbi, sizeof(mbi) ); flNewProtect = mbi.Protect; flNewProtect &= ~(PAGE_READONLY | PAGE_EXECUTE_READ | PAGE_EXECUTE); flNewProtect |= (PAGE_READWRITE); if ( !VirtualProtect( (void*)pvtbl, sizeof(PVOID)*31, flNewProtect, &flOldProtect) ) { OutputDebugString("cant unprotect memory. return false"); return false; } //Hook Vtbl pCreateSurface = MakePtr(DWORD*,pvtbl,CREATE_SURFACE_OFFSET); pIDirectDraw7_CreateSurface=(HRESULT (__stdcall PASCAL *) (LPVOID lplpDD,LPDDSURFACEDESC2, LPDIRECTDRAWSURFACE7 FAR *, IUnknown FAR *))*pCreateSurface; *pCreateSurface=(DWORD) MyIDirectDraw7_CreateSurface; VirtualProtect((void*)pvtbl, sizeof(PVOID), flOldProtect, &flDontCare); return ret; }
Код (Text): HRESULT __stdcall PASCAL MyIDirectDraw7_CreateSurface(LPVOID lplpDD,LPDDSURFACEDESC2 lpDDSurfdesc2, LPDIRECTDRAWSURFACE7 FAR *lpDDSurf7, IUnknown FAR * pUnk) { HRESULT ret=NULL; ret=pIDirectDraw7_CreateSurface(lplpDD,lpDDSurfdesc2,lpDDSurf7,pUnk); OutputDebugString("In lpDD->CreateSurface"); return ret; }
Здравствуйте. Не могли бы вы рассказать какая практическая польза от этого алгоритма, что дает это решение?
tex32 Здравствуйте, чую сарказм, но все же это дает возможность вывода поверх приложений использующих директдро7 и ниже, а по аналогии и D3D.
А зачем такие хитрые манипуляции с указателем таблицы виртеальных функций, ради экономии на подсчёте ссылок? По моему проще определить класс реализующий IDirectDraw7 и возвращать указатель на его экземпляр в MyDirectDrawCreateEx
punxer интересуюсь для общего развития, а не ради сарказма. То есть это даст возможность вывода изображений поверх обычного, или это позволяет модифицировать старое приложение под свои нужды путем подтасовок параметров и указателей? Какова скорость фпс в таком случае у приложения пропатченного таким образом и если можно приведите источник откуда черпаете информацию по данной теме. Еще один вопрос, а можно вашим методом перевести приложение из Д7 под Д9. Понимаю, звучит глупо, но все же, есть ли перспектива написать такую программу?
tex32 Выводить поверх приложения свои данные. Информацию черпаю из мозга и интернета.) Теоретически можно перевести. Но все теоретисчески, я пока прошол этап перехвата и получения указателя на первичную поверхность, вроде получаю задний буфер...но пока как то не пойму где и на какой поверхности свое рисовать. В перехваченном флипе думаю и рисовать нужно на заднем буфере, предварительно залочив его, а потом вызвать таки натуральный флип, может кто опытный подтянется подскажет??
J0E Я думал об этом, но потом пришол к выводу что лучше пропатчу что нужно мне и не буду городить огород, да и подсчет ссылок...
Код (Text): HRESULT __stdcall PASCAL MyIDirectDraw7_CreateSurface(LPVOID lplpDD,LPDDSURFACEDESC2 lpDDSurfdesc2, LPDIRECTDRAWSURFACE7 FAR *lpDDSurf7, IUnknown FAR * pUnk) { #define IDirectDrawSurface7_Flip_OFFSET 44 #define GetAttachedSurface_OFFSET 48 HRESULT ret= NULL; ret=pIDirectDraw7_CreateSurface(lplpDD,lpDDSurfdesc2,lpDDSurf7,pUnk); OutputDebugString("!!!In lpDD->CreateSurface"); if(lpDDSurfdesc2->ddsCaps.dwCaps & DDSCAPS_PRIMARYSURFACE) { //Hook flip and other OutputDebugString("!!!!!!Primary surface founded"); g_lpDDSurfPrimary=(LPDIRECTDRAWSURFACE7)*lpDDSurf7; Код (Text): HRESULT __stdcall PASCAL MyIDirectDrawSurface7_GetAttachedSurface(LPDIRECTDRAWSURFACE7 lplpThis, LPDDSCAPS2 lpCaps, LPDIRECTDRAWSURFACE7 FAR * lplpSurf) { HRESULT ret; OutputDebugString("!!!!!!Primary surface->GetAttachedSurface"); if (lpCaps->dwCaps & DDSCAPS_BACKBUFFER) { OutputDebugString("!!!!!!!!!!!Back Buffer Founded"); g_lpDDSurfBack=*lplpSurf; } ret=pIDirectDrawSurface7_GetAttachedSurface(lplpThis,lpCaps,lplpSurf); return ret; } Код (Text): HRESULT __stdcall PASCAL MyIDirectDrawSurface7_Flip(LPDIRECTDRAWSURFACE7 lplpThis,LPDIRECTDRAWSURFACE7* lplpSurf7,DWORD param) { LPDIRECTDRAWSURFACE7 lpDDs; HRESULT ret=NULL; DDSURFACEDESC2 SD; DDSCAPS2 caps; RECT rc; BYTE* ptr= NULL; OutputDebugString("!!!In lpDDPrimarySurf7->Flip"); caps.dwCaps=DDSCAPS_BACKBUFFER; pIDirectDrawSurface7_GetAttachedSurface(g_lpDDSurfPrimary,&caps,&lpDDs); if (lpDDs) { OutputDebugString("!!!In lpDDPrimarySurf7->Flip!!!BackBuffer obtained"); } ret=pIDirectDrawSurface7_Flip(lplpThis,lplpSurf7,param); return ret; } Так вот во флипе g_lpDDSurfBack=0 А pIDirectDrawSurface7_GetAttachedSurface(g_lpDDSurfPrimary,&caps,&lpDDs); отрабатывает ну что то совсем поздно. g_lpDDSurfPrimary находится нормально. Очень много флипов прорходит без успешного pIDirectDrawSurface7_GetAttachedSurface.
Код (Text): 00000081 12:53:27 [688] In MyCreateWindowExA 00000082 12:53:27 [688] !!in MyDirectDrawCreateEx 00000083 12:53:27 [688] !!CreateSurface hooked 00000084 12:53:27 [688] !!!In lpDD->CreateSurface 00000085 12:53:27 [688] !!!!!!Primary surface founded 00000086 12:53:27 [688] !!!!!!Primary surface->GetAttachedSurface 00000087 12:53:27 [688] !!!!!!!!!!!Back Buffer Founded 00000088 12:53:27 [688] !!!In lpDDPrimarySurf7->Flip 00000089 12:53:27 [688] !!!In lpDDPrimarySurf7->Flip 00000090 12:53:27 [688] !!!In lpDDPrimarySurf7->Flip 00000091 12:53:27 [688] !!!In lpDDPrimarySurf7->Flip 00000092 12:53:27 [688] !!!In lpDDPrimarySurf7->Flip 00000093 12:53:27 [688] !!!In lpDDPrimarySurf7->Flip 00000094 12:53:27 [688] !!!In lpDDPrimarySurf7->Flip 00000095 12:53:27 [688] !!!In lpDDPrimarySurf7->Flip 00000096 12:53:27 [688] !!!In lpDDPrimarySurf7->Flip 00000097 12:53:28 [688] !!!In lpDDPrimarySurf7->Flip 00000098 12:53:28 [688] !!!In lpDDPrimarySurf7->Flip 00000099 12:53:28 [688] !!!In lpDDPrimarySurf7->Flip 00000100 12:53:28 [688] !!!In lpDDPrimarySurf7->Flip 00000101 12:53:28 [688] !!!In lpDD->CreateSurface 00000102 12:53:28 [688] !!!In lpDD->CreateSurface 00000103 12:53:28 [688] !!!In lpDD->CreateSurface 00000104 12:53:28 [688] !!!In lpDD->CreateSurface 00000105 12:53:28 [688] !!!In lpDD->CreateSurface и в самом конце Код (Text): 00014742 12:54:52 [688] !!!In lpDDPrimarySurf7->Flip 00014743 12:54:52 [688] !!!In lpDDPrimarySurf7->Flip 00014744 12:54:52 [688] !!!In lpDDPrimarySurf7->Flip 00014745 12:54:52 [688] !!!In lpDDPrimarySurf7->Flip 00014746 12:54:52 [688] !!!In lpDDPrimarySurf7->Flip 00014747 12:54:52 [688] !!!In lpDDPrimarySurf7->Flip 00014748 12:54:52 [688] !!!In lpDDPrimarySurf7->Flip 00014749 12:54:52 [688] !!!In lpDDPrimarySurf7->Flip 00014750 12:54:52 [688] !!!In lpDDPrimarySurf7->Flip 00014751 12:54:52 [688] !!!In lpDDPrimarySurf7->Flip 00014752 12:54:52 [688] !!!In lpDDPrimarySurf7->Flip 00014753 12:54:52 [688] !!!In lpDDPrimarySurf7->Flip 00014754 12:54:52 [688] !!!In lpDDPrimarySurf7->Flip!!!BackBuffer obtained
punxer глянь программу DirectX Logger на http://blackninja2000.narod.ru Она тоже может хватать ddraw.dll и вести лог по Д7.
Код (Text): HRESULT __stdcall PASCAL MyIDirectDrawSurface7_GetAttachedSurface(LPDIRECTDRAWSURFACE7 lplpThis, LPDDSCAPS2 lpCaps, LPDIRECTDRAWSURFACE7 FAR * lplpSurf) { HRESULT ret; OutputDebugString("!!!!!!Primary surface->GetAttachedSurface"); if (lpCaps->dwCaps & DDSCAPS_BACKBUFFER) { OutputDebugString("!!!!!!!!!!!Back Buffer Founded"); g_lpDDSurfBack=*lplpSurf; } ret=pIDirectDrawSurface7_GetAttachedSurface(lplpThis,lpCaps,lplpSurf); return ret; } а вот правильный вариант)) Код (Text): HRESULT __stdcall PASCAL MyIDirectDrawSurface7_GetAttachedSurface(LPDIRECTDRAWSURFACE7 lplpThis, LPDDSCAPS2 lpCaps, LPDIRECTDRAWSURFACE7 FAR * lplpSurf) { HRESULT ret; OutputDebugString("!!!!!!Primary surface->GetAttachedSurface"); [b]ret=pIDirectDrawSurface7_GetAttachedSurface(lplpThis,lpCaps,lplpSurf);[/b] if (lpCaps->dwCaps & DDSCAPS_BACKBUFFER) { OutputDebugString("!!!!!!!!!!!Back Buffer Founded"); g_lpDDSurfBack=*lplpSurf; } return ret; }